Patch 8.2.0413
Problem:    Buffer menu does not handle special buffers properly.
Solution:   Keep a dictionary with buffer names to reliably keep track of
            entries.
            Also trigger BufFilePre and BufFilePost for command-line and
            terminal buffers when the name changes.
Files:      src/testdir/test_alot.vim, src/testdir/Make_all.mak,
            runtime/menu.vim, src/ex_getln.c, src/terminal.c,
            src/testdir/test_menu.vim


*** ../vim-8.2.0412/src/testdir/test_alot.vim   2020-01-28 21:53:24.039964573 
+0100
--- src/testdir/test_alot.vim   2020-03-19 17:45:57.938251215 +0100
***************
*** 19,25 ****
  source test_global.vim
  source test_jumps.vim
  source test_lispwords.vim
- source test_menu.vim
  source test_move.vim
  source test_put.vim
  source test_recover.vim
--- 19,24 ----
*** ../vim-8.2.0412/src/testdir/Make_all.mak    2020-03-06 20:35:46.120669845 
+0100
--- src/testdir/Make_all.mak    2020-03-19 17:46:29.514127093 +0100
***************
*** 175,183 ****
        test_matchadd_conceal \
        test_matchadd_conceal_utf8 \
        test_memory_usage \
-       test_method \
        test_menu \
        test_messages \
        test_mksession \
        test_mksession_utf8 \
        test_modeline \
--- 175,183 ----
        test_matchadd_conceal \
        test_matchadd_conceal_utf8 \
        test_memory_usage \
        test_menu \
        test_messages \
+       test_method \
        test_mksession \
        test_mksession_utf8 \
        test_modeline \
***************
*** 402,407 ****
--- 402,408 ----
        test_matchadd_conceal.res \
        test_matchadd_conceal_utf8.res \
        test_memory_usage.res \
+       test_menu.res \
        test_messages.res \
        test_method.res \
        test_mksession.res \
*** ../vim-8.2.0412/runtime/menu.vim    2019-12-10 22:06:33.000000000 +0100
--- runtime/menu.vim    2020-03-19 18:17:55.920722422 +0100
***************
*** 2,8 ****
  " You can also use this as a start for your own set of menus.
  "
  " Maintainer: Bram Moolenaar <[email protected]>
! " Last Change:        2019 Dec 10
  
  " Note that ":an" (short for ":anoremenu") is often used to make a menu work
  " in all modes and avoid side effects from mappings defined by the user.
--- 2,8 ----
  " You can also use this as a start for your own set of menus.
  "
  " Maintainer: Bram Moolenaar <[email protected]>
! " Last Change:        2020 Mar 19
  
  " Note that ":an" (short for ":anoremenu") is often used to make a menu work
  " in all modes and avoid side effects from mappings defined by the user.
***************
*** 139,149 ****
  an 10.610 &File.Sa&ve-Exit<Tab>:wqa           :confirm wqa<CR>
  an 10.620 &File.E&xit<Tab>:qa                 :confirm qa<CR>
  
! func! <SID>SelectAll()
    exe "norm! gg" . (&slm == "" ? "VG" : "gH\<C-O>G")
  endfunc
  
! func! s:FnameEscape(fname)
    if exists('*fnameescape')
      return fnameescape(a:fname)
    endif
--- 139,149 ----
  an 10.610 &File.Sa&ve-Exit<Tab>:wqa           :confirm wqa<CR>
  an 10.620 &File.E&xit<Tab>:qa                 :confirm qa<CR>
  
! func s:SelectAll()
    exe "norm! gg" . (&slm == "" ? "VG" : "gH\<C-O>G")
  endfunc
  
! func s:FnameEscape(fname)
    if exists('*fnameescape')
      return fnameescape(a:fname)
    endif
***************
*** 356,362 ****
  let s:did_setup_color_schemes = 0
  
  " Setup the Edit.Color Scheme submenu
! func! s:SetupColorSchemes() abort
    if s:did_setup_color_schemes
      return
    endif
--- 356,362 ----
  let s:did_setup_color_schemes = 0
  
  " Setup the Edit.Color Scheme submenu
! func s:SetupColorSchemes() abort
    if s:did_setup_color_schemes
      return
    endif
***************
*** 388,394 ****
  if has("keymap")
    let s:did_setup_keymaps = 0
  
!   func! s:SetupKeymaps() abort
      if s:did_setup_keymaps
        return
      endif
--- 388,394 ----
  if has("keymap")
    let s:did_setup_keymaps = 0
  
!   func s:SetupKeymaps() abort
      if s:did_setup_keymaps
        return
      endif
***************
*** 454,460 ****
    an <silent> 40.335.270 &Tools.&Spelling.&Find\ More\ Languages      :call 
<SID>SpellLang()<CR>
  
    let s:undo_spellang = ['aun &Tools.&Spelling.&Find\ More\ Languages']
!   func! s:SpellLang()
      for cmd in s:undo_spellang
        exe "silent! " . cmd
      endfor
--- 454,460 ----
    an <silent> 40.335.270 &Tools.&Spelling.&Find\ More\ Languages      :call 
<SID>SpellLang()<CR>
  
    let s:undo_spellang = ['aun &Tools.&Spelling.&Find\ More\ Languages']
!   func s:SpellLang()
      for cmd in s:undo_spellang
        exe "silent! " . cmd
      endfor
***************
*** 566,572 ****
  
  " Use a function to do the conversion, so that it also works with 'insertmode'
  " set.
! func! s:XxdConv()
    let mod = &mod
    if has("vms")
      %!mc vim:xxd
--- 566,572 ----
  
  " Use a function to do the conversion, so that it also works with 'insertmode'
  " set.
! func s:XxdConv()
    let mod = &mod
    if has("vms")
      %!mc vim:xxd
***************
*** 580,586 ****
    let &mod = mod
  endfun
  
! func! s:XxdBack()
    let mod = &mod
    if has("vms")
      %!mc vim:xxd -r
--- 580,586 ----
    let &mod = mod
  endfun
  
! func s:XxdBack()
    let mod = &mod
    if has("vms")
      %!mc vim:xxd -r
***************
*** 593,599 ****
    let &mod = mod
  endfun
  
! func! s:XxdFind()
    if !exists("g:xxdprogram")
      " On the PC xxd may not be in the path but in the install directory
      if has("win32") && !executable("xxd")
--- 593,599 ----
    let &mod = mod
  endfun
  
! func s:XxdFind()
    if !exists("g:xxdprogram")
      " On the PC xxd may not be in the path but in the install directory
      if has("win32") && !executable("xxd")
***************
*** 610,616 ****
  let s:did_setup_compilers = 0
  
  " Setup the Tools.Compiler submenu
! func! s:SetupCompilers() abort
    if s:did_setup_compilers
      return
    endif
--- 610,616 ----
  let s:did_setup_compilers = 0
  
  " Setup the Tools.Compiler submenu
! func s:SetupCompilers() abort
    if s:did_setup_compilers
      return
    endif
***************
*** 634,640 ****
  
  " Load ColorScheme, Compiler Setting and Keymap menus when idle.
  if !exists("do_no_lazyload_menus")
!   func! s:SetupLazyloadMenus()
      call s:SetupColorSchemes()
      call s:SetupCompilers()
      if has("keymap")
--- 634,640 ----
  
  " Load ColorScheme, Compiler Setting and Keymap menus when idle.
  if !exists("do_no_lazyload_menus")
!   func s:SetupLazyloadMenus()
      call s:SetupColorSchemes()
      call s:SetupCompilers()
      if has("keymap")
***************
*** 656,706 ****
  " startup faster.
  let s:bmenu_wait = 1
  
  if !exists("bmenu_priority")
    let bmenu_priority = 60
  endif
  
! func! s:BMAdd()
    if s:bmenu_wait == 0
      " when adding too many buffers, redraw in short format
      if s:bmenu_count == &menuitems && s:bmenu_short == 0
        call s:BMShow()
      else
!       call <SID>BMFilename(expand("<afile>"), expand("<abuf>"))
!       let s:bmenu_count = s:bmenu_count + 1
      endif
    endif
  endfunc
  
! func! s:BMRemove()
    if s:bmenu_wait == 0
!     let name = expand("<afile>")
!     if isdirectory(name)
!       return
      endif
!     let munge = <SID>BMMunge(name, expand("<abuf>"))
  
!     if s:bmenu_short == 0
!       exe 'silent! aun &Buffers.' . munge
!     else
!       exe 'silent! aun &Buffers.' . <SID>BMHash2(munge) . munge
!     endif
!     let s:bmenu_count = s:bmenu_count - 1
    endif
  endfunc
  
  " Create the buffer menu (delete an existing one first).
! func! s:BMShow(...)
    let s:bmenu_wait = 1
    let s:bmenu_short = 1
    let s:bmenu_count = 0
    "
    " get new priority, if exists
    if a:0 == 1
      let g:bmenu_priority = a:1
    endif
  
!   " Remove old menu, if exists; keep one entry to avoid a torn off menu to
    " disappear.  Use try/catch to avoid setting v:errmsg
    try | unmenu &Buffers | catch | endtry
    exe 'noremenu ' . g:bmenu_priority . ".1 &Buffers.Dummy l"
--- 656,730 ----
  " startup faster.
  let s:bmenu_wait = 1
  
+ " Dictionary of buffer number to name. This helps prevent problems where a
+ " buffer as renamed and we didn't keep track of that.
+ let s:bmenu_items = {}
+ 
  if !exists("bmenu_priority")
    let bmenu_priority = 60
  endif
  
! " invoked from a BufCreate or BufFilePost autocommand
! func s:BMAdd()
    if s:bmenu_wait == 0
      " when adding too many buffers, redraw in short format
      if s:bmenu_count == &menuitems && s:bmenu_short == 0
        call s:BMShow()
      else
!       let name = expand("<afile>")
!       let num = expand("<abuf>")
!       if s:BMCanAdd(name, num)
!       call <SID>BMFilename(name, num)
!       let s:bmenu_count += 1
!       endif
      endif
    endif
  endfunc
  
! " invoked from a BufDelete or BufFilePre autocommand
! func s:BMRemove()
    if s:bmenu_wait == 0
!     let bufnum = expand("<abuf>")
!     if s:bmenu_items->has_key(bufnum)
!       let menu_name = s:bmenu_items[bufnum]
!       exe 'silent! aun &Buffers.' . menu_name
!       let s:bmenu_count = s:bmenu_count - 1
!       unlet s:bmenu_items[bufnum]
      endif
!   endif
! endfunc
  
! " Return non-zero if buffer with number "name" / "num" is useful to add in the
! " buffer menu.
! func s:BMCanAdd(name, num)
!   " no directory or unlisted buffer
!   if isdirectory(a:name) || !buflisted(a:num)
!     return 0
!   endif
! 
!   " no special buffer, such as terminal or popup
!   let buftype = getbufvar(a:num, '&buftype')
!   if buftype != '' && buftype != 'nofile' && buftype != 'nowrite'
!     return 0
    endif
+ 
+   " only existing buffers
+   return bufexists(a:num)
  endfunc
  
  " Create the buffer menu (delete an existing one first).
! func s:BMShow(...)
    let s:bmenu_wait = 1
    let s:bmenu_short = 1
    let s:bmenu_count = 0
+   let s:bmenu_items = {}
    "
    " get new priority, if exists
    if a:0 == 1
      let g:bmenu_priority = a:1
    endif
  
!   " 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 | unmenu &Buffers | catch | endtry
    exe 'noremenu ' . g:bmenu_priority . ".1 &Buffers.Dummy l"
***************
*** 721,727 ****
    " figure out how many buffers there are
    let buf = 1
    while buf <= bufnr('$')
!     if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
        let s:bmenu_count = s:bmenu_count + 1
      endif
      let buf = buf + 1
--- 745,751 ----
    " figure out how many buffers there are
    let buf = 1
    while buf <= bufnr('$')
!     if s:BMCanAdd(bufname(buf), buf)
        let s:bmenu_count = s:bmenu_count + 1
      endif
      let buf = buf + 1
***************
*** 733,740 ****
    " iterate through buffer list, adding each buffer to the menu:
    let buf = 1
    while buf <= bufnr('$')
!     if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
!       call <SID>BMFilename(bufname(buf), buf)
      endif
      let buf = buf + 1
    endwhile
--- 757,765 ----
    " iterate through buffer list, adding each buffer to the menu:
    let buf = 1
    while buf <= bufnr('$')
!     let name = bufname(buf)
!     if s:BMCanAdd(name, buf)
!       call <SID>BMFilename(name, buf)
      endif
      let buf = buf + 1
    endwhile
***************
*** 746,752 ****
    aug END
  endfunc
  
! func! s:BMHash(name)
    " Make name all upper case, so that chars are between 32 and 96
    let nm = substitute(a:name, ".*", '\U\0', "")
    if has("ebcdic")
--- 771,777 ----
    aug END
  endfunc
  
! func s:BMHash(name)
    " Make name all upper case, so that chars are between 32 and 96
    let nm = substitute(a:name, ".*", '\U\0', "")
    if has("ebcdic")
***************
*** 761,767 ****
    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)
  endfunc
  
! func! s:BMHash2(name)
    let nm = substitute(a:name, ".", '\L\0', "")
    " Not exactly right for EBCDIC...
    if nm[0] < 'a' || nm[0] > 'z'
--- 786,792 ----
    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)
  endfunc
  
! func s:BMHash2(name)
    let nm = substitute(a:name, ".", '\L\0', "")
    " Not exactly right for EBCDIC...
    if nm[0] < 'a' || nm[0] > 'z'
***************
*** 781,802 ****
    endif
  endfunc
  
! " insert a buffer name into the buffer menu:
! func! s:BMFilename(name, num)
!   if isdirectory(a:name)
!     return
!   endif
    let munge = <SID>BMMunge(a:name, a:num)
    let hash = <SID>BMHash(munge)
    if s:bmenu_short == 0
!     let name = 'an ' . g:bmenu_priority . '.' . hash . ' &Buffers.' . munge
    else
!     let name = 'an ' . g:bmenu_priority . '.' . hash . '.' . hash . ' 
&Buffers.' . <SID>BMHash2(munge) . munge
    endif
    " set 'cpo' to include the <CR>
    let cpo_save = &cpo
    set cpo&vim
!   exe name . ' :confirm b' . a:num . '<CR>'
    let &cpo = cpo_save
  endfunc
  
--- 806,827 ----
    endif
  endfunc
  
! " Insert a buffer name into the buffer menu.
! func s:BMFilename(name, num)
    let munge = <SID>BMMunge(a:name, a:num)
    let hash = <SID>BMHash(munge)
    if s:bmenu_short == 0
!     let s:bmenu_items[a:num] = munge
!     let cmd = 'an ' . g:bmenu_priority . '.' . hash . ' &Buffers.' . munge
    else
!     let menu_name = <SID>BMHash2(munge) . munge
!     let s:bmenu_items[a:num] = menu_name
!     let cmd = 'an ' . g:bmenu_priority . '.' . hash . '.' . hash . ' 
&Buffers.' . menu_name
    endif
    " set 'cpo' to include the <CR>
    let cpo_save = &cpo
    set cpo&vim
!   exe cmd . ' :confirm b' . a:num . '<CR>'
    let &cpo = cpo_save
  endfunc
  
***************
*** 804,810 ****
  if !exists("g:bmenu_max_pathlen")
    let g:bmenu_max_pathlen = 35
  endif
! func! s:BMTruncName(fname)
    let name = a:fname
    if g:bmenu_max_pathlen < 5
      let name = ""
--- 829,835 ----
  if !exists("g:bmenu_max_pathlen")
    let g:bmenu_max_pathlen = 35
  endif
! func s:BMTruncName(fname)
    let name = a:fname
    if g:bmenu_max_pathlen < 5
      let name = ""
***************
*** 824,830 ****
    return name
  endfunc
  
! func! s:BMMunge(fname, bnum)
    let name = a:fname
    if name == ''
      if !exists("g:menutrans_no_file")
--- 849,855 ----
    return name
  endfunc
  
! func s:BMMunge(fname, bnum)
    let name = a:fname
    if name == ''
      if !exists("g:menutrans_no_file")
***************
*** 941,947 ****
  if has("spell")
    " Spell suggestions in the popup menu.  Note that this will slow down the
    " appearance of the menu!
!   func! <SID>SpellPopup()
      if exists("s:changeitem") && s:changeitem != ''
        call <SID>SpellDel()
      endif
--- 966,972 ----
  if has("spell")
    " Spell suggestions in the popup menu.  Note that this will slow down the
    " appearance of the menu!
!   func s:SpellPopup()
      if exists("s:changeitem") && s:changeitem != ''
        call <SID>SpellDel()
      endif
***************
*** 997,1003 ****
      call cursor(0, curcol)    " put the cursor back where it was
    endfunc
  
!   func! <SID>SpellReplace(n)
      let l = getline('.')
      " Move the cursor to the start of the word.
      call spellbadword()
--- 1022,1028 ----
      call cursor(0, curcol)    " put the cursor back where it was
    endfunc
  
!   func s:SpellReplace(n)
      let l = getline('.')
      " Move the cursor to the start of the word.
      call spellbadword()
***************
*** 1005,1011 ****
          \ . strpart(l, col('.') + len(s:fromword) - 1))
    endfunc
  
!   func! <SID>SpellDel()
      exe "aunmenu PopUp." . s:changeitem
      exe "aunmenu PopUp." . s:additem
      exe "aunmenu PopUp." . s:ignoreitem
--- 1030,1036 ----
          \ . strpart(l, col('.') + len(s:fromword) - 1))
    endfunc
  
!   func s:SpellDel()
      exe "aunmenu PopUp." . s:changeitem
      exe "aunmenu PopUp." . s:additem
      exe "aunmenu PopUp." . s:ignoreitem
*** ../vim-8.2.0412/src/ex_getln.c      2020-03-18 15:23:10.979695103 +0100
--- src/ex_getln.c      2020-03-19 17:51:08.053044242 +0100
***************
*** 4195,4201 ****
--- 4195,4203 ----
  
      // Create the command-line buffer empty.
      (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
+     apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
      (void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
+     apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
      set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
      curbuf->b_p_ma = TRUE;
  #ifdef FEAT_FOLDING
*** ../vim-8.2.0412/src/terminal.c      2020-03-11 19:29:57.853088812 +0100
--- src/terminal.c      2020-03-19 17:51:08.053044242 +0100
***************
*** 523,528 ****
--- 523,530 ----
      term->tl_next = first_term;
      first_term = term;
  
+     apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
+ 
      if (opt->jo_term_name != NULL)
        curbuf->b_ffname = vim_strsave(opt->jo_term_name);
      else if (argv != NULL)
***************
*** 571,576 ****
--- 573,580 ----
      curbuf->b_sfname = vim_strsave(curbuf->b_ffname);
      curbuf->b_fname = curbuf->b_ffname;
  
+     apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
+ 
      if (opt->jo_term_opencmd != NULL)
        term->tl_opencmd = vim_strsave(opt->jo_term_opencmd);
  
*** ../vim-8.2.0412/src/testdir/test_menu.vim   2020-03-15 16:12:16.552208654 
+0100
--- src/testdir/test_menu.vim   2020-03-19 18:45:21.857156136 +0100
***************
*** 19,24 ****
--- 19,59 ----
    call assert_equal('', v:errmsg)
  endfunc
  
+ func Test_buffer_menu_special_buffers()
+   " Load in runtime menus
+   try
+     source $VIMRUNTIME/menu.vim
+   catch
+     call assert_report('error while loading menus: ' . v:exception)
+   endtry
+ 
+   let v:errmsg = ''
+   doautocmd LoadBufferMenu VimEnter
+   call assert_equal('', v:errmsg)
+ 
+   let orig_buffer_menus = execute("nmenu Buffers")
+ 
+   " Make a new command-line window, test that it does not create a new buffer
+   " menu.
+   call feedkeys("q::let cmdline_buffer_menus=execute('nmenu 
Buffers')\<CR>:q\<CR>", 'ntx')
+   call assert_equal(len(split(orig_buffer_menus, "\n")), 
len(split(cmdline_buffer_menus, "\n")))
+   call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
+ 
+   if has('terminal')
+     " Open a terminal window and test that it does not create a buffer menu
+     " item.
+     terminal
+     let term_buffer_menus = execute('nmenu Buffers')
+     call assert_equal(len(split(orig_buffer_menus, "\n")), 
len(split(term_buffer_menus, "\n")))
+     bwipe!
+     call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
+   endif
+ 
+   " Remove menus to clean up
+   source $VIMRUNTIME/delmenu.vim
+   call assert_equal('', v:errmsg)
+ endfunc
+ 
  func Test_translate_menu()
    if !has('multi_lang')
      return
***************
*** 121,126 ****
--- 156,162 ----
  " Test for menu item completion in command line
  func Test_menu_expand()
    " Create the menu itmes for test
+   menu Dummy.Nothing lll
    for i in range(1, 4)
      let m = 'menu Xmenu.A' .. i .. '.A' .. i
      for j in range(1, 4)
***************
*** 146,152 ****
    " Test for <Up> to go up a menu
    call feedkeys(":emenu Xmenu.A\<Tab>\<Down>\<Up>\<Up>\<Up>" ..
          \ "\<C-A>\<C-B>\"\<CR>", 'xt')
!   call assert_equal('"emenu Buffers. Xmenu.', @:)
  
    " Test for expanding only submenus
    call feedkeys(":popup Xmenu.\<C-A>\<C-B>\"\<CR>", 'xt')
--- 182,188 ----
    " Test for <Up> to go up a menu
    call feedkeys(":emenu Xmenu.A\<Tab>\<Down>\<Up>\<Up>\<Up>" ..
          \ "\<C-A>\<C-B>\"\<CR>", 'xt')
!   call assert_equal('"emenu Dummy. Xmenu.', @:)
  
    " Test for expanding only submenus
    call feedkeys(":popup Xmenu.\<C-A>\<C-B>\"\<CR>", 'xt')
***************
*** 166,171 ****
--- 202,208 ----
  
    set wildmenu&
    unmenu Xmenu
+   unmenu Dummy
  
    " Test for expanding popup menus with some hidden items
    menu Xmenu.foo.A1 a1
***************
*** 175,181 ****
    call feedkeys(":popup Xmenu.\<C-A>\<C-B>\"\<CR>", 'xt')
    call assert_equal('"popup Xmenu.foo', @:)
    unmenu Xmenu
- 
  endfunc
  
  " Test for the menu_info() function
--- 212,217 ----
*** ../vim-8.2.0412/src/version.c       2020-03-19 17:13:36.646135855 +0100
--- src/version.c       2020-03-19 18:45:49.712997574 +0100
***************
*** 740,741 ****
--- 740,743 ----
  {   /* Add new patch number below this line */
+ /**/
+     413,
  /**/

-- 
"My particular problem is with registry entries, which seem to just
accumulate like plastic coffee cups..."           -- Paul Moore

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202003191747.02JHlxPe010991%40masaka.moolenaar.net.

Raspunde prin e-mail lui