]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0624: C-N/C-P cannot be mapped in complete() completion v9.2.0624
authorThomas M Kehrenberg <tmke8@posteo.net>
Sat, 13 Jun 2026 14:36:58 +0000 (14:36 +0000)
committerChristian Brabandt <cb@256bit.org>
Sat, 13 Jun 2026 14:36:58 +0000 (14:36 +0000)
Problem:  Keys valid in CTRL-X mode are never mapped while insert
          completion is active, so <C-N> and <C-P> cannot be remapped
  for completion started by complete().
Solution: Do not disable mappings in CTRL_X_EVAL mode.  In this mode a
          mapping cannot interfere with selecting the completion
          method, which is what the no-mapping rule exists for.

related: #6440
related: #16880
closes:  #20489

Signed-off-by: Thomas M Kehrenberg <tmke8@posteo.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/builtin.txt
runtime/doc/insert.txt
runtime/doc/version9.txt
src/getchar.c
src/insexpand.c
src/proto/insexpand.pro
src/testdir/test_ins_complete.vim
src/version.c

index e8b9518e536146ec87fd5213740a8263bf97d7a4..caad78ceba5deffe193f45ec817fcfa1ce38558c 100644 (file)
@@ -1,4 +1,4 @@
-*builtin.txt*  For Vim version 9.2.  Last change: 2026 Jun 09
+*builtin.txt*  For Vim version 9.2.  Last change: 2026 Jun 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1986,6 +1986,14 @@ complete({startcol}, {matches})                          *complete()* *E785*
                The match can be selected with CTRL-N and CTRL-P as usual with
                Insert mode completion.  The popup menu will appear if
                specified, see |ins-completion-menu|.
+               Unlike with other |ins-completion| modes, the CTRL-N and
+               CTRL-P keys can be mapped while this completion is active.
+               For example, to make CTRL-N move the selection without
+               inserting the match: >
+
+               inoremap <expr> <C-N> complete_info().mode ==# 'eval'
+                       \ ? '<Down>' : '<C-N>'
+<
 
                Example (using legacy Vim script): >
 
index 5946f26e760c23d298f8d33161d9d0d63b04444a..688d65fb3f08b1097e07357deffeb8a04a639b44 100644 (file)
@@ -1,4 +1,4 @@
-*insert.txt*   For Vim version 9.2.  Last change: 2026 Jun 09
+*insert.txt*   For Vim version 9.2.  Last change: 2026 Jun 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -690,7 +690,8 @@ When the popup menu is displayed there are a few more special keys, see
 Note: The keys that are valid in CTRL-X mode are not mapped.  This allows for
 `:map <C-F> <C-X><C-F>` to work (assuming "<" is not in 'cpo').  The key that
 ends CTRL-X mode (any key that is not a valid CTRL-X mode command) is mapped.
-Also, when doing completion with 'complete' mappings apply as usual.
+Also, when doing completion with 'complete' or when completion was started
+with |complete()| mappings apply as usual.
 
                                                                *E565*
 Note: While completion is active Insert mode can't be used recursively and
index 937bf4f216c8726c086b407228d10b7988417378..b78a3738a69ce3fa414730f946ebf821fb4ee2a0 100644 (file)
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.2.  Last change: 2026 Jun 09
+*version9.txt* For Vim version 9.2.  Last change: 2026 Jun 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -52677,6 +52677,8 @@ Changed ~
 - On Unix, filename completion for single-file Ex commands now treats embedded
   whitespace as part of the filename, like on other platforms.
 - Rewrite the clientserver socketserver backend to use channels and JSON.
+- During |complete()|-triggered completion, CTRL-N and CTRL-P are now subject
+  to insert-mode mappings.
 
 
                                                        *added-9.3*
index d02b9009cb5a2dd9e80af9fe0456be86af7b6a61..25422be0d1253705f677471a501f7c89e8b7fa32 100644 (file)
@@ -2718,6 +2718,7 @@ typedef enum {
 /*
  * Check if the bytes at the start of the typeahead buffer are a character used
  * in Insert mode completion.  This includes the form with a CTRL modifier.
+ * During completion started by complete() keys are mapped as usual.
  */
     static int
 at_ins_compl_key(void)
@@ -2733,8 +2734,9 @@ at_ins_compl_key(void)
            // to the CTRL-N/CTRL-P completion keys here.
            && !(p[2] & MOD_MASK_SHIFT))
        c = p[3] & 0x1f;
-    return (ctrl_x_mode_not_default() && vim_is_ctrl_x_key(c))
-               || (compl_status_local() && (c == Ctrl_N || c == Ctrl_P));
+    return !ctrl_x_mode_eval()
+           && ((ctrl_x_mode_not_default() && vim_is_ctrl_x_key(c))
+               || (compl_status_local() && (c == Ctrl_N || c == Ctrl_P)));
 }
 
 /*
@@ -2872,7 +2874,8 @@ handle_mapping(
      * - in insert or cmdline mode and 'paste' option set
      * - waiting for "hit return to continue" and CR or SPACE typed
      * - waiting for a char with --more--
-     * - in Ctrl-X mode, and we get a valid char for that mode
+     * - in Ctrl-X mode (not started by complete()), and we get a valid char
+     *   for that mode
      * - currently receiving OSC sequence
      */
     tb_c1 = typebuf.tb_buf[typebuf.tb_off];
index bbb15b003ea5488e0e5a9fb01656405e7c631cf9..c63b49c7f40636446e2c7044b40d686f3af3dc58 100644 (file)
@@ -359,7 +359,7 @@ int ctrl_x_mode_omni(void)
     { return ctrl_x_mode == CTRL_X_OMNI; }
 int ctrl_x_mode_spell(void)
     { return ctrl_x_mode == CTRL_X_SPELL; }
-static int ctrl_x_mode_eval(void)
+int ctrl_x_mode_eval(void)
     { return ctrl_x_mode == CTRL_X_EVAL; }
 int ctrl_x_mode_line_or_eval(void)
     { return ctrl_x_mode == CTRL_X_WHOLE_LINE || ctrl_x_mode == CTRL_X_EVAL; }
index e973eac4f7b5651416f990293ded87bfabe42f95..2c1882dc198cc67412f692cf30a73274f977d452 100644 (file)
@@ -14,6 +14,7 @@ int ctrl_x_mode_cmdline(void);
 int ctrl_x_mode_function(void);
 int ctrl_x_mode_omni(void);
 int ctrl_x_mode_spell(void);
+int ctrl_x_mode_eval(void);
 int ctrl_x_mode_line_or_eval(void);
 int ctrl_x_mode_register(void);
 int ctrl_x_mode_not_default(void);
index 7eda457e1a3b234efe3fffbdf3684025b74b8538..c741fd1e73866601285a308c2f72bd487fb1bf47 100644 (file)
@@ -6331,4 +6331,30 @@ func Test_completion_with_mapped_ctrl_r()
   bwipe!
 endfunc
 
+" Keys are mapped during completion started by complete(), but not in other
+" CTRL-X modes.
+func Test_mapped_ctrl_n_during_complete_function()
+  new
+  inoremap <buffer> <F2> <Cmd>call complete(1, ['foo', 'foobar'])<CR>
+  inoremap <buffer> <F3> <Cmd>let b:info =
+        \ [getline('.'), complete_info(['selected']).selected]<CR>
+
+  " During completion started by complete() the <C-N> mapping applies:
+  " <Down> moves the selection without inserting it.
+  inoremap <buffer> <expr> <C-N> complete_info().mode ==# 'eval' ? '<Down>' : '<C-N>'
+  call feedkeys("i\<F2>\<*C-N>\<F3>\<C-Y>\<Esc>", 'tx')
+  call assert_equal(['foo', 1], b:info)
+  call assert_equal('foobar', getline(1))
+
+  " In other CTRL-X modes the mapping is ignored: the builtin <C-N> selects
+  " and inserts the next match.
+  %delete _
+  call setline(1, ['foo', 'foobar', ''])
+  inoremap <buffer> <expr> <C-N> pumvisible() ? '<Down>' : '<C-N>'
+  call feedkeys("3GAf\<C-X>\<C-N>\<C-N>\<F3>\<C-Y>\<Esc>", 'tx')
+  call assert_equal(['foobar', 1], b:info)
+
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab nofoldenable
index b798c6348c1f2564595f7af18ea4d753ce2b5074..28606e3d3e665ab1222e70f91800c8967caf54cd 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    624,
 /**/
     623,
 /**/