Skip to content

Commit cda0d17

Browse files
ychinchrisbra
authored andcommitted
patch 9.1.1622: Patch v9.1.1432 causes performance regressions
Problem: Patch v9.1.1432 causes performance regressions Solution: Revert "patch 9.1.1432: GTK GUI: Buffer menu does not handle unicode correctly" (Yee Cheng Chin). This reverts commit 08896dd. The previous change to support Unicode characters properly in the buffers menu resorted to removing all buffer menus and re-add the buffers after doing a sort, per each buffer addition. This was quite slow because if Vim is trying to load in multiple buffers at once (e.g. when loading a session) this scales in O(n^2) and Vim can freeze for dozens of seconds when adding a few hundred buffers. related: #17405 related: #17928 fixes: #17897 Signed-off-by: Yee Cheng Chin <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent da9c966 commit cda0d17

3 files changed

Lines changed: 39 additions & 36 deletions

File tree

runtime/menu.vim

Lines changed: 37 additions & 23 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: The Vim Project <https://github.com/vim/vim>
5-
" Last Change: 2025 Jun 04
5+
" Last Change: 2023 Aug 10
66
" Former Maintainer: Bram Moolenaar <[email protected]>
77

88
" Note that ":an" (short for ":anoremenu") is often used to make a menu work
@@ -693,7 +693,12 @@ def s:BMAdd()
693693
if s:bmenu_count == &menuitems && s:bmenu_short == 0
694694
s:BMShow()
695695
else
696-
s:BMRedraw()
696+
var name = expand("<afile>")
697+
var num = str2nr(expand("<abuf>"))
698+
if s:BMCanAdd(name, num)
699+
s:BMFilename(name, num)
700+
s:bmenu_count += 1
701+
endif
697702
endif
698703
endif
699704
enddef
@@ -741,10 +746,6 @@ def s:BMShow()
741746
s:bmenu_count = 0
742747
s:bmenu_items = {}
743748

744-
s:BMRedraw()
745-
enddef
746-
747-
def s:BMRedraw()
748749
# Remove old menu, if it exists; keep one entry to avoid a torn off menu to
749750
# disappear. Use try/catch to avoid setting v:errmsg
750751
try
@@ -767,30 +768,26 @@ def s:BMRedraw()
767768
unmenu &Buffers.Dummy
768769

769770
# figure out how many buffers there are
770-
var buffer_menu_items = []
771771
var buf = 1
772772
while buf <= bufnr('$')
773-
var name = bufname(buf)
774-
if s:BMCanAdd(name, buf)
775-
add(buffer_menu_items, [substitute(name, ".", '\L\0', ""), name, buf])
773+
if s:BMCanAdd(bufname(buf), buf)
774+
s:bmenu_count = s:bmenu_count + 1
776775
endif
777776
buf += 1
778777
endwhile
779-
s:bmenu_count = len(buffer_menu_items)
780-
781778
if s:bmenu_count <= &menuitems
782779
s:bmenu_short = 0
783780
endif
784781

785782
# iterate through buffer list, adding each buffer to the menu:
786-
sort(buffer_menu_items)
787-
788-
var i = 0
789-
for menu_item in buffer_menu_items
790-
s:BMFilename(menu_item[1], menu_item[2], i)
791-
i += 1
792-
endfor
793-
783+
buf = 1
784+
while buf <= bufnr('$')
785+
var name = bufname(buf)
786+
if s:BMCanAdd(name, buf)
787+
call s:BMFilename(name, buf)
788+
endif
789+
buf += 1
790+
endwhile
794791
s:bmenu_wait = 0
795792
aug buffer_list
796793
au!
@@ -799,6 +796,22 @@ def s:BMRedraw()
799796
aug END
800797
enddef
801798

799+
def s:BMHash(name: string): number
800+
# Make name all upper case, so that chars are between 32 and 96
801+
var nm = substitute(name, ".*", '\U\0', "")
802+
var sp: number
803+
if has("ebcdic")
804+
# HACK: Replace all non alphabetics with 'Z'
805+
# Just to make it work for now.
806+
nm = substitute(nm, "[^A-Z]", 'Z', "g")
807+
sp = char2nr('A') - 1
808+
else
809+
sp = char2nr(' ')
810+
endif
811+
# convert first six chars into a number for sorting:
812+
return (char2nr(nm[0]) - sp) * 0x800000 + (char2nr(nm[1]) - sp) * 0x20000 + (char2nr(nm[2]) - sp) * 0x1000 + (char2nr(nm[3]) - sp) * 0x80 + (char2nr(nm[4]) - sp) * 0x20 + (char2nr(nm[5]) - sp)
813+
enddef
814+
802815
def s:BMHash2(name: string): string
803816
var nm = substitute(name, ".", '\L\0', "")
804817
if nm[0] < 'a' || nm[0] > 'z'
@@ -819,16 +832,17 @@ def s:BMHash2(name: string): string
819832
enddef
820833

821834
" Insert a buffer name into the buffer menu.
822-
def s:BMFilename(name: string, num: number, index: number)
835+
def s:BMFilename(name: string, num: number)
823836
var munge = s:BMMunge(name, num)
837+
var hash = s:BMHash(munge)
824838
var cmd: string
825839
if s:bmenu_short == 0
826840
s:bmenu_items[num] = munge
827-
cmd = 'an ' .. g:bmenu_priority .. '.9999.' .. index .. ' &Buffers.' .. munge
841+
cmd = 'an ' .. g:bmenu_priority .. '.' .. hash .. ' &Buffers.' .. munge
828842
else
829843
var menu_name = s:BMHash2(munge) .. munge
830844
s:bmenu_items[num] = menu_name
831-
cmd = 'an ' .. g:bmenu_priority .. '.9999.0.' .. index .. ' &Buffers.' .. menu_name
845+
cmd = 'an ' .. g:bmenu_priority .. '.' .. hash .. '.' .. hash .. ' &Buffers.' .. menu_name
832846
endif
833847
exe cmd .. ' :confirm b' .. num .. '<CR>'
834848
enddef

src/testdir/test_gui.vim

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,17 +1767,4 @@ func Test_CursorHold_not_triggered_at_startup()
17671767
call assert_equal(['g:cursorhold_triggered=0'], found)
17681768
endfunc
17691769

1770-
" Test that buffer names are shown at the end in the :Buffers menu
1771-
func Test_Buffers_Menu()
1772-
doautocmd LoadBufferMenu VimEnter
1773-
1774-
let name = ''
1775-
exe ':badd ' .. name
1776-
let nr = bufnr('$')
1777-
1778-
let cmd = printf(':amenu Buffers.%s\ (%d)', name, nr)
1779-
let menu = split(execute(cmd), '\n')[1]
1780-
call assert_match('^9999 '.. name, menu)
1781-
endfunc
1782-
17831770
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

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

720720
static int included_patches[] =
721721
{ /* Add new patch number below this line */
722+
/**/
723+
1622,
722724
/**/
723725
1621,
724726
/**/

0 commit comments

Comments
 (0)