]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1622: Patch v9.1.1432 causes performance regressions v9.1.1622
authorYee Cheng Chin <ychin.git@gmail.com>
Sun, 10 Aug 2025 08:03:26 +0000 (10:03 +0200)
committerChristian Brabandt <cb@256bit.org>
Sun, 10 Aug 2025 08:05:29 +0000 (10:05 +0200)
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 08896dd330c6dc8324618fde482db968e6f71088.

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 <ychin.git@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/menu.vim
src/testdir/test_gui.vim
src/version.c

index afe61d637ee2bb02faf57855e5282a62f4b6d1c8..c9acf76ca8083671024fbf441b4b8acbc38de914 100644 (file)
@@ -2,7 +2,7 @@
 " You can also use this as a start for your own set of menus.
 "
 " Maintainer:  The Vim Project <https://github.com/vim/vim>
-" Last Change: 2025 Jun 04
+" Last Change: 2023 Aug 10
 " Former Maintainer:   Bram Moolenaar <Bram@vim.org>
 
 " Note that ":an" (short for ":anoremenu") is often used to make a menu work
@@ -693,7 +693,12 @@ def s:BMAdd()
     if s:bmenu_count == &menuitems && s:bmenu_short == 0
       s:BMShow()
     else
-      s:BMRedraw()
+      var name = expand("<afile>")
+      var num = str2nr(expand("<abuf>"))
+      if s:BMCanAdd(name, num)
+       s:BMFilename(name, num)
+       s:bmenu_count += 1
+      endif
     endif
   endif
 enddef
@@ -741,10 +746,6 @@ def s:BMShow()
   s:bmenu_count = 0
   s:bmenu_items = {}
 
-  s:BMRedraw()
-enddef
-
-def s:BMRedraw()
   # Remove old menu, if it exists; keep one entry to avoid a torn off menu to
   # disappear.  Use try/catch to avoid setting v:errmsg
   try 
@@ -767,30 +768,26 @@ def s:BMRedraw()
   unmenu &Buffers.Dummy
 
   # figure out how many buffers there are
-  var buffer_menu_items = []
   var buf = 1
   while buf <= bufnr('$')
-    var name = bufname(buf)
-    if s:BMCanAdd(name, buf)
-      add(buffer_menu_items, [substitute(name, ".", '\L\0', ""), name, buf])
+    if s:BMCanAdd(bufname(buf), buf)
+      s:bmenu_count = s:bmenu_count + 1
     endif
     buf += 1
   endwhile
-  s:bmenu_count = len(buffer_menu_items)
-
   if s:bmenu_count <= &menuitems
     s:bmenu_short = 0
   endif
 
   # iterate through buffer list, adding each buffer to the menu:
-  sort(buffer_menu_items)
-
-  var i = 0
-  for menu_item in buffer_menu_items
-    s:BMFilename(menu_item[1], menu_item[2], i)
-    i += 1
-  endfor
-
+  buf = 1
+  while buf <= bufnr('$')
+    var name = bufname(buf)
+    if s:BMCanAdd(name, buf)
+      call s:BMFilename(name, buf)
+    endif
+    buf += 1
+  endwhile
   s:bmenu_wait = 0
   aug buffer_list
     au!
@@ -799,6 +796,22 @@ def s:BMRedraw()
   aug END
 enddef
 
+def s:BMHash(name: string): number
+  # Make name all upper case, so that chars are between 32 and 96
+  var nm = substitute(name, ".*", '\U\0', "")
+  var sp: number
+  if has("ebcdic")
+    # HACK: Replace all non alphabetics with 'Z'
+    #       Just to make it work for now.
+    nm = substitute(nm, "[^A-Z]", 'Z', "g")
+    sp = char2nr('A') - 1
+  else
+    sp = char2nr(' ')
+  endif
+  # convert first six chars into a number for sorting:
+  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)
+enddef
+
 def s:BMHash2(name: string): string
   var nm = substitute(name, ".", '\L\0', "")
   if nm[0] < 'a' || nm[0] > 'z'
@@ -819,16 +832,17 @@ def s:BMHash2(name: string): string
 enddef
 
 " Insert a buffer name into the buffer menu.
-def s:BMFilename(name: string, num: number, index: number)
+def s:BMFilename(name: string, num: number)
   var munge = s:BMMunge(name, num)
+  var hash = s:BMHash(munge)
   var cmd: string
   if s:bmenu_short == 0
     s:bmenu_items[num] = munge
-    cmd = 'an ' .. g:bmenu_priority .. '.9999.' .. index .. ' &Buffers.' .. munge
+    cmd = 'an ' .. g:bmenu_priority .. '.' .. hash .. ' &Buffers.' .. munge
   else
     var menu_name = s:BMHash2(munge) .. munge
     s:bmenu_items[num] = menu_name
-    cmd = 'an ' .. g:bmenu_priority .. '.9999.0.' .. index .. ' &Buffers.' .. menu_name
+    cmd = 'an ' .. g:bmenu_priority .. '.' .. hash .. '.' .. hash .. ' &Buffers.' .. menu_name
   endif
   exe cmd .. ' :confirm b' .. num .. '<CR>'
 enddef
index 9fd840a53a85308ff41d9574a750d0579058f041..16e8f9134d935d97e5585abea34ff09c1212418a 100644 (file)
@@ -1767,17 +1767,4 @@ func Test_CursorHold_not_triggered_at_startup()
   call assert_equal(['g:cursorhold_triggered=0'], found)
 endfunc
 
-" Test that buffer names are shown at the end in the :Buffers menu
-func Test_Buffers_Menu()
-  doautocmd LoadBufferMenu VimEnter
-
-  let name = '天'
-  exe ':badd ' .. name
-  let nr = bufnr('$')
-
-  let cmd = printf(':amenu Buffers.%s\ (%d)', name, nr)
-  let menu = split(execute(cmd), '\n')[1]
-  call assert_match('^9999 '.. name, menu)
-endfunc
-
 " vim: shiftwidth=2 sts=2 expandtab
index ee0bf8b413a3e68307d1e3050977d8162a386f10..b28e3b2a4afd6fcbfec47ffd5b4ca951642a7d4a 100644 (file)
@@ -719,6 +719,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1622,
 /**/
     1621,
 /**/