vim-patch:9.1.1742: complete: preinsert does not work well with 'autocomplete' (#35692)

Problem:  complete: preinsert does not work well with preinsert
Solution: Make "preinsert" completeopt value work with autocompletion
          (Girish Palya)

This change extends Insert mode autocompletion so that 'preinsert' also
works when 'autocomplete' is enabled.

Try: `:set ac cot=preinsert`

See `:help 'cot'` for more details.

closes: vim/vim#18213

fa6fd41a94

Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
zeertzjq
2025-09-09 11:35:41 +08:00
committed by GitHub
parent c553008e74
commit eb19206e03
16 changed files with 382 additions and 78 deletions

View File

@@ -262,7 +262,7 @@ describe('ui/cursor', function()
m.attr = { background = Screen.colors.DarkGray }
end
if m.id_lm then
m.id_lm = 76
m.id_lm = 77
m.attr_lm = {}
end
end

View File

@@ -475,12 +475,13 @@ func Test_highlight_completion()
call assert_equal('"hi clear', getreg(':'))
" A cleared group does not show up in completions.
hi clear Added
hi Anders ctermfg=green
call assert_equal(['Aardig', 'Added', 'Anders'], getcompletion('A', 'highlight'))
call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight'))
hi clear Aardig
call assert_equal(['Added', 'Anders'], getcompletion('A', 'highlight'))
call assert_equal(['Anders'], getcompletion('A', 'highlight'))
hi clear Anders
call assert_equal(['Added'], getcompletion('A', 'highlight'))
call assert_equal([], getcompletion('A', 'highlight'))
endfunc
func Test_getcompletion()

View File

@@ -5472,7 +5472,7 @@ func Test_autocomplete_timer()
call assert_equal(-1, b:selected)
" Test 7: Following 'cot' option values have no effect
set completeopt=menu,menuone,noselect,noinsert,longest,preinsert
set completeopt=menu,menuone,noselect,noinsert,longest
set complete=.,Ffunction('TestComplete'\\,\ [0\\,\ 0\\,\ 0])
let g:CallCount = 0
call feedkeys("Sab\<c-n>\<F2>\<F3>\<Esc>0", 'tx!')
@@ -5691,4 +5691,109 @@ func Test_autocompletedelay()
call StopVimInTerminal(buf)
endfunc
func Test_autocomplete_completeopt_preinsert()
func GetLine()
let g:line = getline('.')
let g:col = col('.')
endfunc
call Ntest_override("char_avail", 1)
new
inoremap <buffer><F5> <C-R>=GetLine()<CR>
set completeopt=preinsert autocomplete
call setline(1, ["foobar", "foozbar"])
call feedkeys("Go\<ESC>", 'tx')
func DoTest(typed, line, col)
call feedkeys($"S{a:typed}\<F5>\<ESC>", 'tx')
call assert_equal(a:line, g:line)
call assert_equal(a:col, g:col)
endfunc
call DoTest("f", 'foo', 2)
call DoTest("fo", 'foo', 3)
call DoTest("foo", 'foo', 4)
call DoTest("foob", 'foobar', 5)
call DoTest("foob\<BS>", 'foo', 4)
call DoTest("foob\<BS>\<BS>", 'foo', 3)
call DoTest("foo\<BS>", 'foo', 3)
call DoTest("foo\<BS>\<BS>", 'foo', 2)
call DoTest("foo\<BS>\<BS>\<BS>", '', 1)
call DoTest("foo \<BS>", 'foo', 4)
call DoTest("foo \<BS>\<BS>", 'foo', 3)
call DoTest("f\<C-N>", 'foozbar', 8)
call DoTest("f\<C-N>\<C-N>", 'foobar', 7)
call DoTest("f\<C-N>\<C-N>\<C-N>", 'foo', 2)
call DoTest("f\<C-N>\<C-N>\<C-N>\<C-N>", 'foozbar', 8)
call DoTest("f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'foo', 2)
call DoTest("f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>\<C-P>", 'foobar', 7)
call DoTest("f\<C-P>", 'foobar', 7)
call DoTest("fo\<BS>\<C-P>", 'foobar', 7)
call DoTest("zar\<C-O>0f", 'foozar', 2)
call DoTest("zar\<C-O>0f\<C-Y>", 'foozar', 4)
call DoTest("zar\<C-O>0f\<C-Y>\<BS>", 'foozar', 3)
call DoTest("zar\<C-O>0f\<C-N>", 'foozbarzar', 8)
call DoTest("zar\<C-O>0f\<C-N>\<C-N>", 'foobarzar', 7)
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>", 'foozar', 2)
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>\<C-N>", 'foozbarzar', 8)
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'foozar', 2)
call DoTest("zar\<C-O>0f\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>\<C-P>", 'foobarzar', 7)
call DoTest("zar\<C-O>0f\<C-P>", 'foobarzar', 7)
" Should not work with fuzzy
set cot+=fuzzy
call DoTest("f", 'f', 2)
%delete _
let &l:undolevels = &l:undolevels
normal! ifoo
let &l:undolevels = &l:undolevels
normal! ofoobar
let &l:undolevels = &l:undolevels
normal! ofoobaz
let &l:undolevels = &l:undolevels
func CheckUndo()
let g:errmsg = ''
call assert_equal(['foo', 'foobar', 'foobaz'], getline(1, '$'))
undo
call assert_equal(['foo', 'foobar'], getline(1, '$'))
undo
call assert_equal(['foo'], getline(1, '$'))
undo
call assert_equal([''], getline(1, '$'))
later 3
call assert_equal(['foo', 'foobar', 'foobaz'], getline(1, '$'))
call assert_equal('', v:errmsg)
endfunc
" Check that switching buffer with "preinsert" doesn't corrupt undo.
new
setlocal bufhidden=wipe
inoremap <buffer> <F2> <Cmd>enew!<CR>
call feedkeys("if\<F2>\<Esc>", 'tx')
bwipe!
call CheckUndo()
" Check that closing window with "preinsert" doesn't corrupt undo.
new
setlocal bufhidden=wipe
inoremap <buffer> <F2> <Cmd>close!<CR>
call feedkeys("if\<F2>\<Esc>", 'tx')
call CheckUndo()
%delete _
delfunc CheckUndo
bw!
set cot& autocomplete&
delfunc GetLine
delfunc DoTest
call Ntest_override("char_avail", 0)
endfunc
" vim: shiftwidth=2 sts=2 expandtab nofoldenable