Skip to content

Commit 040c1fe

Browse files
committed
patch 8.0.1279: initializing menus can be slow
Problem: Initializing menus can be slow, especially when there are many keymaps, color schemes, etc. Solution: Do the globbing for runtime files lazlily. (Ken Takata)
1 parent 8ac4415 commit 040c1fe

3 files changed

Lines changed: 107 additions & 61 deletions

File tree

runtime/doc/gui.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*gui.txt* For Vim version 8.0. Last change: 2017 Sep 23
1+
*gui.txt* For Vim version 8.0. Last change: 2017 Nov 09
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -499,6 +499,17 @@ in the menu (which can take a bit of time to load). If you want to have all
499499
filetypes already present at startup, add: >
500500
:let do_syntax_sel_menu = 1
501501
502+
The following menuitems show all available color schemes, keymaps and compiler
503+
settings:
504+
Edit > Color Scheme ~
505+
Edit > Keymap ~
506+
Tools > Set Compiler ~
507+
However, they can also take a bit of time to load, because they search all
508+
related files from the directories in 'runtimepath'. Therefore they are
509+
loaded lazily (by the |CursorHold| event), or you can also load them manually.
510+
If you want to have all these items already present at startup, add: >
511+
:let do_no_lazyload_menus = 1
512+
502513
Note that the menu.vim is sourced when `:syntax on` or `:filetype on` is
503514
executed or after your .vimrc file is sourced. This means that the 'encoding'
504515
option and the language of messages (`:language messages`) must be set before

runtime/menu.vim

Lines changed: 93 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
" You can also use this as a start for your own set of menus.
33
"
44
" Maintainer: Bram Moolenaar <[email protected]>
5-
" Last Change: 2017 Mar 04
5+
" Last Change: 2017 Nov 09
66

77
" Note that ":an" (short for ":anoremenu") is often used to make a menu work
88
" in all modes and avoid side effects from mappings defined by the user.
@@ -159,15 +159,15 @@ nnoremenu 20.370 &Edit.Put\ &Before<Tab>[p [p
159159
inoremenu &Edit.Put\ &Before<Tab>[p <C-O>[p
160160
nnoremenu 20.380 &Edit.Put\ &After<Tab>]p ]p
161161
inoremenu &Edit.Put\ &After<Tab>]p <C-O>]p
162-
if has("win32") || has("win16")
162+
if has("win32")
163163
vnoremenu 20.390 &Edit.&Delete<Tab>x x
164164
endif
165165
noremenu <script> <silent> 20.400 &Edit.&Select\ All<Tab>ggVG :<C-U>call <SID>SelectAll()<CR>
166166
inoremenu <script> <silent> 20.400 &Edit.&Select\ All<Tab>ggVG <C-O>:call <SID>SelectAll()<CR>
167167
cnoremenu <script> <silent> 20.400 &Edit.&Select\ All<Tab>ggVG <C-U>call <SID>SelectAll()<CR>
168168

169169
an 20.405 &Edit.-SEP2- <Nop>
170-
if has("win32") || has("win16") || has("gui_gtk") || has("gui_kde") || has("gui_motif")
170+
if has("win32") || has("gui_gtk") || has("gui_kde") || has("gui_motif")
171171
an 20.410 &Edit.&Find\.\.\. :promptfind<CR>
172172
vunmenu &Edit.&Find\.\.\.
173173
vnoremenu <silent> &Edit.&Find\.\.\. y:promptfind <C-R>=<SID>FixFText()<CR><CR>
@@ -339,51 +339,65 @@ fun! s:FileFormat()
339339
endif
340340
endfun
341341

342+
let s:did_setup_color_schemes = 0
342343

343344
" Setup the Edit.Color Scheme submenu
345+
func! s:SetupColorSchemes() abort
346+
if s:did_setup_color_schemes
347+
return
348+
endif
349+
let s:did_setup_color_schemes = 1
344350

345-
" get NL separated string with file names
346-
let s:n = globpath(&runtimepath, "colors/*.vim")
351+
let n = globpath(&runtimepath, "colors/*.vim", 1, 1)
347352

348-
" split at NL, Ignore case for VMS and windows, sort on name
349-
let s:names = sort(map(split(s:n, "\n"), 'substitute(v:val, "\\c.*[/\\\\:\\]]\\([^/\\\\:]*\\)\\.vim", "\\1", "")'), 1)
353+
" Ignore case for VMS and windows, sort on name
354+
let names = sort(map(n, 'substitute(v:val, "\\c.*[/\\\\:\\]]\\([^/\\\\:]*\\)\\.vim", "\\1", "")'), 1)
350355

351-
" define all the submenu entries
352-
let s:idx = 100
353-
for s:name in s:names
354-
exe "an 20.450." . s:idx . ' &Edit.C&olor\ Scheme.' . s:name . " :colors " . s:name . "<CR>"
355-
let s:idx = s:idx + 10
356-
endfor
357-
unlet s:name s:names s:n s:idx
356+
" define all the submenu entries
357+
let idx = 100
358+
for name in names
359+
exe "an 20.450." . idx . ' &Edit.C&olor\ Scheme.' . name . " :colors " . name . "<CR>"
360+
let idx = idx + 10
361+
endfor
362+
silent! aunmenu &Edit.Show\ C&olor\ Schemes\ in\ Menu
363+
endfun
364+
if exists("do_no_lazyload_menus")
365+
call s:SetupColorSchemes()
366+
else
367+
an <silent> 20.450 &Edit.Show\ C&olor\ Schemes\ in\ Menu :call <SID>SetupColorSchemes()<CR>
368+
endif
358369

359370

360371
" Setup the Edit.Keymap submenu
361372
if has("keymap")
362-
let s:n = globpath(&runtimepath, "keymap/*.vim")
363-
if s:n != ""
364-
let s:idx = 100
365-
an 20.460.90 &Edit.&Keymap.None :set keymap=<CR>
366-
while strlen(s:n) > 0
367-
let s:i = stridx(s:n, "\n")
368-
if s:i < 0
369-
let s:name = s:n
370-
let s:n = ""
371-
else
372-
let s:name = strpart(s:n, 0, s:i)
373-
let s:n = strpart(s:n, s:i + 1, 19999)
374-
endif
375-
" Ignore case for VMS and windows
376-
let s:name = substitute(s:name, '\c.*[/\\:\]]\([^/\\:_]*\)\(_[0-9a-zA-Z-]*\)\=\.vim', '\1', '')
377-
exe "an 20.460." . s:idx . ' &Edit.&Keymap.' . s:name . " :set keymap=" . s:name . "<CR>"
378-
unlet s:name
379-
unlet s:i
380-
let s:idx = s:idx + 10
381-
endwhile
382-
unlet s:idx
373+
let s:did_setup_keymaps = 0
374+
375+
func! s:SetupKeymaps() abort
376+
if s:did_setup_keymaps
377+
return
378+
endif
379+
let s:did_setup_keymaps = 1
380+
381+
let n = globpath(&runtimepath, "keymap/*.vim", 1, 1)
382+
if !empty(n)
383+
let idx = 100
384+
an 20.460.90 &Edit.&Keymap.None :set keymap=<CR>
385+
for name in n
386+
" Ignore case for VMS and windows
387+
let name = substitute(name, '\c.*[/\\:\]]\([^/\\:_]*\)\(_[0-9a-zA-Z-]*\)\=\.vim', '\1', '')
388+
exe "an 20.460." . idx . ' &Edit.&Keymap.' . name . " :set keymap=" . name . "<CR>"
389+
let idx = idx + 10
390+
endfor
391+
endif
392+
silent! aunmenu &Edit.Show\ &Keymaps\ in\ Menu
393+
endfun
394+
if exists("do_no_lazyload_menus")
395+
call s:SetupKeymaps()
396+
else
397+
an <silent> 20.460 &Edit.Show\ &Keymaps\ in\ Menu :call <SID>SetupKeymaps()<CR>
383398
endif
384-
unlet s:n
385399
endif
386-
if has("win32") || has("win16") || has("gui_motif") || has("gui_gtk") || has("gui_kde") || has("gui_photon") || has("gui_mac")
400+
if has("win32") || has("gui_motif") || has("gui_gtk") || has("gui_kde") || has("gui_photon") || has("gui_mac")
387401
an 20.470 &Edit.Select\ Fo&nt\.\.\. :set guifont=*<CR>
388402
endif
389403

@@ -441,10 +455,10 @@ if has("spell")
441455
endif
442456

443457
let found = 0
444-
let s = globpath(&rtp, "spell/*." . enc . ".spl")
445-
if s != ""
458+
let s = globpath(&runtimepath, "spell/*." . enc . ".spl", 1, 1)
459+
if !empty(s)
446460
let n = 300
447-
for f in split(s, "\n")
461+
for f in s
448462
let nm = substitute(f, '.*spell[/\\]\(..\)\.[^/\\]*\.spl', '\1', "")
449463
if nm != "en" && nm !~ '/'
450464
let _nm = nm
@@ -574,27 +588,46 @@ func! s:XxdFind()
574588
endif
575589
endfun
576590

591+
let s:did_setup_compilers = 0
592+
577593
" Setup the Tools.Compiler submenu
578-
let s:n = globpath(&runtimepath, "compiler/*.vim")
579-
let s:idx = 100
580-
while strlen(s:n) > 0
581-
let s:i = stridx(s:n, "\n")
582-
if s:i < 0
583-
let s:name = s:n
584-
let s:n = ""
585-
else
586-
let s:name = strpart(s:n, 0, s:i)
587-
let s:n = strpart(s:n, s:i + 1, 19999)
594+
func! s:SetupCompilers() abort
595+
if s:did_setup_compilers
596+
return
588597
endif
589-
" Ignore case for VMS and windows
590-
let s:name = substitute(s:name, '\c.*[/\\:\]]\([^/\\:]*\)\.vim', '\1', '')
591-
exe "an 30.440." . s:idx . ' &Tools.Se&t\ Compiler.' . s:name . " :compiler " . s:name . "<CR>"
592-
unlet s:name
593-
unlet s:i
594-
let s:idx = s:idx + 10
595-
endwhile
596-
unlet s:n
597-
unlet s:idx
598+
let s:did_setup_compilers = 1
599+
600+
let n = globpath(&runtimepath, "compiler/*.vim", 1, 1)
601+
let idx = 100
602+
for name in n
603+
" Ignore case for VMS and windows
604+
let name = substitute(name, '\c.*[/\\:\]]\([^/\\:]*\)\.vim', '\1', '')
605+
exe "an 30.440." . idx . ' &Tools.Se&t\ Compiler.' . name . " :compiler " . name . "<CR>"
606+
let idx = idx + 10
607+
endfor
608+
silent! aunmenu &Tools.Show\ Compiler\ Se&ttings\ in\ Menu
609+
endfun
610+
if exists("do_no_lazyload_menus")
611+
call s:SetupCompilers()
612+
else
613+
an <silent> 30.440 &Tools.Show\ Compiler\ Se&ttings\ in\ Menu :call <SID>SetupCompilers()<CR>
614+
endif
615+
616+
" Load ColorScheme, Compiler Setting and Keymap menus when idle.
617+
if !exists("do_no_lazyload_menus")
618+
func! s:SetupLazyloadMenus()
619+
call s:SetupColorSchemes()
620+
call s:SetupCompilers()
621+
if has("keymap")
622+
call s:SetupKeymaps()
623+
endif
624+
endfunc
625+
augroup SetupLazyloadMenus
626+
au!
627+
au CursorHold,CursorHoldI * call <SID>SetupLazyloadMenus() | au! SetupLazyloadMenus
628+
augroup END
629+
endif
630+
598631

599632
if !exists("no_buffers_menu")
600633

@@ -1095,7 +1128,7 @@ if (exists("did_load_filetypes") || exists("syntax_on"))
10951128
if exists("do_syntax_sel_menu")
10961129
runtime! synmenu.vim
10971130
else
1098-
an 50.10 &Syntax.&Show\ File\ Types\ in\ Menu :let do_syntax_sel_menu = 1<Bar>runtime! synmenu.vim<Bar>aunmenu &Syntax.&Show\ File\ Types\ in\ Menu<CR>
1131+
an <silent> 50.10 &Syntax.&Show\ File\ Types\ in\ Menu :let do_syntax_sel_menu = 1<Bar>runtime! synmenu.vim<Bar>aunmenu &Syntax.&Show\ File\ Types\ in\ Menu<CR>
10991132
an 50.195 &Syntax.-SEP1- <Nop>
11001133
endif
11011134

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
1279,
764766
/**/
765767
1278,
766768
/**/

0 commit comments

Comments
 (0)