diff options
author | Shougo Matsushita <Shougo.Matsu@gmail.com> | 2015-05-02 09:44:54 +0900 |
---|---|---|
committer | Michael Reed <m.reed@mykolab.com> | 2015-06-04 21:20:09 -0400 |
commit | e6c62c80ef1138c6c6d177efbd765476c0283b71 (patch) | |
tree | 78afe36a6a4dc9f14602220193bea8b1e4b93ecf | |
parent | 2271b746d7853d336f63480415c43d57fa39fb44 (diff) | |
download | rneovim-e6c62c80ef1138c6c6d177efbd765476c0283b71.tar.gz rneovim-e6c62c80ef1138c6c6d177efbd765476c0283b71.tar.bz2 rneovim-e6c62c80ef1138c6c6d177efbd765476c0283b71.zip |
Add noinsert and noselect features in completeopt #2564
Backported from vim_dev:
https://groups.google.com/forum/#!searchin/vim_dev/completeopt/vim_dev/tVsk0pdOGvs/fCzBbPkA4w0J
Use case:
https://github.com/Shougo/neocomplcache.vim/issues/426
Reviewed-by: Felipe Morales <hel.sheep@gmail.com>
Reviewed-by: Scott Prager <splinterofchaos@gmail.com>
Reviewed-by: Michael Reed <m.reed@mykolab.com>
-rw-r--r-- | runtime/doc/options.txt | 8 | ||||
-rw-r--r-- | src/nvim/edit.c | 42 | ||||
-rw-r--r-- | src/nvim/option.c | 3 | ||||
-rw-r--r-- | test/functional/viml/completion_spec.lua | 26 |
4 files changed, 68 insertions, 11 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index e785dae714..08783ebbf3 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1609,6 +1609,14 @@ A jump table for the options with a short description can be found at |Q_op|. completion in the preview window. Only works in combination with "menu" or "menuone". + noinsert Do not insert any text for a match until the user selects + a match from the menu. Only works in combination with + "menu" or "menuone". No effect if "longest" is present. + + noselect Do not select a match in the menu, force the user to + select one from the menu. Only works in combination with + "menu" or "menuone". + *'concealcursor'* *'cocu'* 'concealcursor' 'cocu' string (default: "") diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 9704295aaa..d36168254a 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -154,6 +154,11 @@ static char_u *compl_leader = NULL; static int compl_get_longest = FALSE; /* put longest common string in compl_leader */ +static int compl_no_insert = FALSE; /* FALSE: select & insert + TRUE: noinsert */ +static int compl_no_select = FALSE; /* FALSE: select & insert + TRUE: noselect */ + static int compl_used_match; /* Selected one of the matches. When FALSE the match was edited or using the longest common string. */ @@ -2972,8 +2977,19 @@ static int ins_compl_prep(int c) /* Set "compl_get_longest" when finding the first matches. */ if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || (ctrl_x_mode == 0 && !compl_started)) { - compl_get_longest = (vim_strchr(p_cot, 'l') != NULL); + compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); compl_used_match = TRUE; + + if (strstr((char *)p_cot, "noselect") != NULL) { + compl_no_insert = FALSE; + compl_no_select = TRUE; + } else if (strstr((char *)p_cot, "noinsert") != NULL) { + compl_no_insert = TRUE; + compl_no_select = FALSE; + } else { + compl_no_insert = FALSE; + compl_no_select = FALSE; + } } if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET) { @@ -3875,6 +3891,7 @@ ins_compl_next ( compl_T *found_compl = NULL; int found_end = FALSE; int advance; + int started = compl_started; /* When user complete function return -1 for findstart which is next * time of 'always', compl_shown_match become NULL. */ @@ -3945,7 +3962,7 @@ ins_compl_next ( return -1; } - if (advance) { + if (!compl_no_select && advance) { if (compl_shows_dir == BACKWARD) --compl_pending; else @@ -3990,13 +4007,18 @@ ins_compl_next ( } /* Insert the text of the new completion, or the compl_leader. */ - if (insert_match) { - if (!compl_get_longest || compl_used_match) + if (compl_no_insert && !started) { + ins_bytes(compl_orig_text + ins_compl_len()); + compl_used_match = FALSE; + } else if (insert_match) { + if (!compl_get_longest || compl_used_match) { ins_compl_insert(); - else + } else { ins_bytes(compl_leader + ins_compl_len()); - } else + } + } else { compl_used_match = FALSE; + } if (!allow_get_expansion) { /* may undisplay the popup menu first */ @@ -4015,7 +4037,11 @@ ins_compl_next ( /* Enter will select a match when the match wasn't inserted and the popup * menu is visible. */ - compl_enter_selects = !insert_match && compl_match_array != NULL; + if (compl_no_insert && !started) { + compl_enter_selects = TRUE; + } else { + compl_enter_selects = !insert_match && compl_match_array != NULL; + } /* * Show the file name for the match (if any) @@ -4082,7 +4108,7 @@ void ins_compl_check_keys(int frequency) } } } - if (compl_pending != 0 && !got_int) { + if (compl_pending != 0 && !got_int && !compl_no_insert) { int todo = compl_pending > 0 ? compl_pending : -compl_pending; compl_pending = 0; diff --git a/src/nvim/option.c b/src/nvim/option.c index 6fb661b6e2..a5ef6b6e7e 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1705,7 +1705,8 @@ static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax", "diff", NULL}; static char *(p_fcl_values[]) = {"all", NULL}; -static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", NULL}; +static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", + "noinsert", "noselect", NULL}; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "option.c.generated.h" diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua index df4018e707..2a02dd9cf0 100644 --- a/test/functional/viml/completion_spec.lua +++ b/test/functional/viml/completion_spec.lua @@ -3,12 +3,12 @@ local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq local execute, source = helpers.execute, helpers.source -describe("completion", function() +describe('completion', function() before_each(function() clear() end) - describe("v:completed_item", function() + describe('v:completed_item', function() it('returns expected dict in normal completion', function() feed('ifoo<ESC>o<C-x><C-n><ESC>') eq('foo', eval('getline(2)')) @@ -53,4 +53,26 @@ describe("completion", function() eval('v:completed_item')) end) end) + describe('completeopt', function() + it('inserts the first candidate if default', function() + execute('set completeopt+=menuone') + feed('ifoo<ESC>o<C-x><C-n>bar<ESC>') + eq('foobar', eval('getline(2)')) + end) + it('selects the first candidate if noinsert', function() + execute('set completeopt+=menuone,noinsert') + feed('ifoo<ESC>o<C-x><C-n><C-y><ESC>') + eq('foo', eval('getline(2)')) + end) + it('does not insert the first candidate if noselect', function() + execute('set completeopt+=menuone,noselect') + feed('ifoo<ESC>o<C-x><C-n>bar<ESC>') + eq('bar', eval('getline(2)')) + end) + it('does not select/insert the first candidate if noselect and noinsert', function() + execute('set completeopt+=menuone,noselect,noinsert') + feed('ifoo<ESC>o<C-x><C-n><ESC>') + eq('', eval('getline(2)')) + end) + end) end) |