Describe the bug
When using complete() to create a completion menu, CTRL-L fails to insert a character from the current match. Instead, a literal ^L is inserted.
CTRL-L Add one character from the current match, may reduce the number of matches.
To Reproduce
minimal.vim:
" From :help complete() inoremap <C-j> <C-R>=ListMonths()<CR> func! ListMonths() call complete(col('.'), ['January', 'February', 'March', \ 'April', 'May', 'June', 'July', 'August', 'September', \ 'October', 'November', 'December']) return '' endfunc " Set options that avoid filling first completion. set completeopt=menuone,noinsert,noselect
Detailed steps to reproduce the behavior:
gvim --clean minimal.vim (see above)source % to load minimal.vimExpected behavior
The letter a (the next character in the first match "March") is inserted just like it is for ins-completion.
Actual behavior
A literal ^L is inserted.
Environment (please complete the following information):
Vim version
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Dec 7 2020 23:02:04)
MS-Windows 64-bit GUI version with OLE support
Included patches: 1-2107
Compiled by appveyor@APPVYR-WIN
OS: Windows 10 OS Build 18363.1256
GUI
Additional context
Encountered this using asyncomplete which uses complete() in prabirshrestha/asyncomplete.vim#177.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.![]()
Run gvim --clean minimal.vim (see above) source % to load minimal.vim Start inserting type C-n to open ins-completion menu type M to limit to March, May type C-L to insert 'a' works!
Typing Ctrl-N starts keyword completion mode. In that mode, after limiting the popup menu, typing Ctrl-L does add one character from the popup menu. Note: this does not use the completion function ListMonths().
type C-u to clear type C-j to open complete() completion menu type M to limit to March, May type C-L to insert 'a'
You are in insert mode completion here (CTRL_X_EVAL). In that mode, Ctrl-L will always be inserted literally. This might need to be added to the documentation.
Here is a tentative fix, I don't know how much does this break:
diff --git a/src/edit.c b/src/edit.c index a152d8449..b10726693 100644 --- a/src/edit.c +++ b/src/edit.c @@ -627,7 +627,7 @@ edit( // "compl_leader". Except when at the original match and // there is nothing to add, CTRL-L works like CTRL-P then. if (c == Ctrl_L - && (!ctrl_x_mode_line_or_eval() + && (!ctrl_x_mode_whole_line() || ins_compl_long_shown_match())) { ins_compl_addfrommatch(); diff --git a/src/insexpand.c b/src/insexpand.c index 02f593d7c..8ed512fcc 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -1195,7 +1195,7 @@ ins_compl_dictionaries( // When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern // to only match at the start of a line. Otherwise just match the // pattern. Also need to double backslashes. - if (ctrl_x_mode_line_or_eval()) + if (ctrl_x_mode_whole_line()) { char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\"); size_t len;
Haven't tested it very thoroughly yet.
Test failure:
Failures:
From test_popup.vim:
Found errors in Test_popup_complete():
command line..script /home/chrisbra/code/vim-src/src/testdir/runtest.vim[468]..function RunTheTest[39]..Test_popup_complete line 57: Expected ['J\f'] but got ['Ja']
this would be expected however. Not sure we should change this however, I am not sure if people rely on the current behaviour.
I found a related issue from the past committed in e421450:
Patch 7.4.653
Problem: Insert mode completion with complete() may have CTRL-L work like
CTRL-P.
Solution: Handle completion with complete() differently. (Yasuhiro
Matsumoto, Christian Brabandt, Hirohito Higashi)
Files: src/edit.c
I think the most relevant part of that commit is these lines where Ctrl_L is removed from "relevant inputs" for CTRL_X_EVAL. (Most of the commit is replacing CTRL_X_WHOLE_LINE with CTRL_X_MODE_LINE_OR_EVAL to add the new CTRL_X_EVAL id.) It seems CTRL_X_EVAL was originally implemented as CTRL_X_WHOLE_LINE (instead of keyword completion as I'd expect). And that commit is specifically allowing ^L to be inserted?
I dug up the report for that patch and I think the bug was that people didn't want Ctrl-L to behave like Ctrl-P in CTRL_X_EVAL, but I don't understand if the irritation was the inability to insert literal ^L? @mattn, you originally reported and authored the patch. Is it correct that you rely on inserting literal ^L?
To me, CTRL_X mode would work the same regardless of which submode you're in -- all of the inputs described in :h popupmenu-keys should work. But if that would break people's workflows, is there an alternative? Is there a way for me to map ins_compl_addfrommatch() to a key (it doesn't appear to be exposed)?