From 2c6469aca451027648c3317f11ffb6b35b7f835b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 28 Nov 2025 10:10:31 +0800 Subject: [PATCH] vim-patch:9.1.1933: completion: complete_match() is not useful (#36726) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: completion: complete_match() Vim script function and 'isexpand' option are not that useful and confusing (after v9.1.1341) Solution: Remove function and option and clean up code and documentation (Girish Palya). complete_match() and 'isexpand' add no real functionality to Vim. They duplicate what `strridx()` already does, yet pretend to be part of the completion system. They have nothing to do with the completion mechanism. * `f_complete_match()` in `insexpand.c` does not call any completion code. It’s just a `STRNCMP()` wrapper with fluff logic. * `'isexpand'` exists only as a proxy argument to that function. It does nothing on its own and amounts to misuse of a new option. The following Vim script function can be used to implement the same functionality: ```vim func CompleteMatch(triggers, sep=',') let line = getline('.')->strpart(0, col('.') - 1) let result = [] for trig in split(a:triggers, a:sep) let idx = strridx(line, trig) if l:idx >= 0 call add(result, [idx + 1, trig]) endif endfor return result endfunc ``` related: vim/vim#16716 fixes: vim/vim#18563 closes: vim/vim#18790 https://github.com/vim/vim/commit/cbcbff871224115c45bbd14582749a487c6fad30 Co-authored-by: Girish Palya --- runtime/doc/credits.txt | 2 +- runtime/doc/news.txt | 5 +- runtime/doc/options.txt | 17 ----- runtime/doc/usr_41.txt | 2 - runtime/doc/vimfn.txt | 50 -------------- runtime/lua/vim/_meta/options.lua | 25 ------- runtime/lua/vim/_meta/vimfn.lua | 47 ------------- runtime/scripts/optwin.lua | 1 - src/nvim/buffer.c | 1 - src/nvim/buffer_defs.h | 1 - src/nvim/eval.lua | 51 -------------- src/nvim/insexpand.c | 88 ------------------------ src/nvim/option.c | 5 -- src/nvim/option_vars.h | 1 - src/nvim/options.lua | 27 -------- src/nvim/optionstr.c | 39 ----------- test/old/testdir/gen_opt_test.vim | 1 - test/old/testdir/test_ins_complete.vim | 93 -------------------------- 18 files changed, 5 insertions(+), 451 deletions(-) diff --git a/runtime/doc/credits.txt b/runtime/doc/credits.txt index c303c8c6f0..dd904e4c96 100644 --- a/runtime/doc/credits.txt +++ b/runtime/doc/credits.txt @@ -93,7 +93,7 @@ Vim would never have become what it is now, without the help of these people! improvements Doug Kearns Runtime file maintainer Foxe Chen Wayland support, new features - glepnir completion feature + glepnir work on improving completion feature, fixes Girish Palya autocompletion (ins/cmdline), omnifunc composing, search/subst completion, and more. Hirohito Higashi lots of patches and fixes diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index b9e01e65b9..99931d7244 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -33,7 +33,7 @@ LSP OPTIONS -• `'completefuzzycollect'` has been removed. +• `'completefuzzycollect'` and `'isexpand'` have been removed. TREESITTER @@ -43,6 +43,9 @@ UI • `progress` attribute removed form |ui-messages| msg_show event +VIMSCRIPT + +• `complete_match()` has been removed. ============================================================================== BREAKING CHANGES *news-breaking* diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 9a2e06ae07..c312975b24 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3739,23 +3739,6 @@ A jump table for the options with a short description can be found at |Q_op|. and there is a letter before it, the completed part is made uppercase. With 'noinfercase' the match is used as-is. - *'isexpand'* *'ise'* -'isexpand' 'ise' string (default "") - global or local to buffer |global-local| - Defines characters and patterns for completion in insert mode. Used - by the |complete_match()| function to determine the starting position - for completion. This is a comma-separated list of triggers. Each - trigger can be: - - A single character like "." or "/" - - A sequence of characters like "->", "/*", or "/**" - - Note: Use "\\," to add a literal comma as trigger character, see - |option-backslash|. - - Examples: >vim - set isexpand=.,->,/*,\\, -< - *'isfname'* *'isf'* 'isfname' 'isf' string (default for Windows: "@,48-57,/,\,.,-,_,+,,,#,$,%,{,},[,],@-@,!,~,=" diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index f93ace1ebe..619d8a3626 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -943,8 +943,6 @@ Insert mode completion: *completion-functions* complete_add() add to found matches complete_check() check if completion should be aborted complete_info() get current completion information - complete_match() get insert completion start match col and - trigger text preinserted() check if text is inserted after cursor pumvisible() check if the popup menu is displayed pum_getpos() position and size of popup menu if visible diff --git a/runtime/doc/vimfn.txt b/runtime/doc/vimfn.txt index 7aaf306027..7dd9c0595f 100644 --- a/runtime/doc/vimfn.txt +++ b/runtime/doc/vimfn.txt @@ -1281,56 +1281,6 @@ complete_info([{what}]) *complete_info()* Return: ~ (`table`) -complete_match([{lnum}, {col}]) *complete_match()* - Searches backward from the given position and returns a List - of matches according to the 'isexpand' option. When no - arguments are provided, uses the current cursor position. - - Each match is represented as a List containing - [startcol, trigger_text] where: - - startcol: column position where completion should start, - or -1 if no trigger position is found. For multi-character - triggers, returns the column of the first character. - - trigger_text: the matching trigger string from 'isexpand', - or empty string if no match was found or when using the - default 'iskeyword' pattern. - - When 'isexpand' is empty, uses the 'iskeyword' pattern "\k\+$" - to find the start of the current keyword. - - Examples: >vim - set isexpand=.,->,/,/*,abc - func CustomComplete() - let res = complete_match() - if res->len() == 0 | return | endif - let [col, trigger] = res[0] - let items = [] - if trigger == '/*' - let items = ['/** */'] - elseif trigger == '/' - let items = ['/*! */', '// TODO:', '// fixme:'] - elseif trigger == '.' - let items = ['length()'] - elseif trigger =~ '^\->' - let items = ['map()', 'reduce()'] - elseif trigger =~ '^\abc' - let items = ['def', 'ghk'] - endif - if items->len() > 0 - let startcol = trigger =~ '^/' ? col : col + len(trigger) - call complete(startcol, items) - endif - endfunc - inoremap call CustomComplete() -< - - Parameters: ~ - • {lnum} (`integer?`) - • {col} (`integer?`) - - Return: ~ - (`table`) - confirm({msg} [, {choices} [, {default} [, {type}]]]) *confirm()* confirm() offers the user a dialog, from which a choice can be made. It returns the number of the choice. For the first diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 130e296b6c..f847ee1520 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -3656,31 +3656,6 @@ vim.o.inf = vim.o.infercase vim.bo.infercase = vim.o.infercase vim.bo.inf = vim.bo.infercase ---- Defines characters and patterns for completion in insert mode. Used ---- by the `complete_match()` function to determine the starting position ---- for completion. This is a comma-separated list of triggers. Each ---- trigger can be: ---- - A single character like "." or "/" ---- - A sequence of characters like "->", "/*", or "/**" ---- ---- Note: Use "\\," to add a literal comma as trigger character, see ---- `option-backslash`. ---- ---- Examples: ---- ---- ```vim ---- set isexpand=.,->,/*,\\, ---- ``` ---- ---- ---- @type string -vim.o.isexpand = "" -vim.o.ise = vim.o.isexpand -vim.bo.isexpand = vim.o.isexpand -vim.bo.ise = vim.bo.isexpand -vim.go.isexpand = vim.o.isexpand -vim.go.ise = vim.go.isexpand - --- The characters specified by this option are included in file names and --- path names. Filenames are used for commands like "gf", "[i" and in --- the tags file. It is also used for "\f" in a `pattern`. diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index a540476931..5a2ec2fe84 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -1127,53 +1127,6 @@ function vim.fn.complete_check() end --- @return table function vim.fn.complete_info(what) end ---- Searches backward from the given position and returns a List ---- of matches according to the 'isexpand' option. When no ---- arguments are provided, uses the current cursor position. ---- ---- Each match is represented as a List containing ---- [startcol, trigger_text] where: ---- - startcol: column position where completion should start, ---- or -1 if no trigger position is found. For multi-character ---- triggers, returns the column of the first character. ---- - trigger_text: the matching trigger string from 'isexpand', ---- or empty string if no match was found or when using the ---- default 'iskeyword' pattern. ---- ---- When 'isexpand' is empty, uses the 'iskeyword' pattern "\k\+$" ---- to find the start of the current keyword. ---- ---- Examples: >vim ---- set isexpand=.,->,/,/*,abc ---- func CustomComplete() ---- let res = complete_match() ---- if res->len() == 0 | return | endif ---- let [col, trigger] = res[0] ---- let items = [] ---- if trigger == '/*' ---- let items = ['/** */'] ---- elseif trigger == '/' ---- let items = ['/*! */', '// TODO:', '// fixme:'] ---- elseif trigger == '.' ---- let items = ['length()'] ---- elseif trigger =~ '^\->' ---- let items = ['map()', 'reduce()'] ---- elseif trigger =~ '^\abc' ---- let items = ['def', 'ghk'] ---- endif ---- if items->len() > 0 ---- let startcol = trigger =~ '^/' ? col : col + len(trigger) ---- call complete(startcol, items) ---- endif ---- endfunc ---- inoremap call CustomComplete() ---- < ---- ---- @param lnum? integer ---- @param col? integer ---- @return table -function vim.fn.complete_match(lnum, col) end - --- confirm() offers the user a dialog, from which a choice can be --- made. It returns the number of the choice. For the first --- choice this is 1. diff --git a/runtime/scripts/optwin.lua b/runtime/scripts/optwin.lua index 631c5cedfa..ca3c48e775 100644 --- a/runtime/scripts/optwin.lua +++ b/runtime/scripts/optwin.lua @@ -406,7 +406,6 @@ local options_list = { header = N_ 'language specific', { 'isfname', N_ 'specifies the characters in a file name' }, { 'isident', N_ 'specifies the characters in an identifier' }, - { 'isexpand', N_ 'defines trigger strings for complete_match()' }, { 'iskeyword', N_ 'specifies the characters in a keyword' }, { 'isprint', N_ 'specifies printable characters' }, { 'quoteescape', N_ 'specifies escape characters in a string' }, diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 50d9277c11..aeb1f8517a 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2105,7 +2105,6 @@ void free_buf_options(buf_T *buf, bool free_p_ff) clear_string_option(&buf->b_p_cinw); clear_string_option(&buf->b_p_cot); clear_string_option(&buf->b_p_cpt); - clear_string_option(&buf->b_p_ise); clear_string_option(&buf->b_p_cfu); callback_free(&buf->b_cfu_cb); clear_string_option(&buf->b_p_ofu); diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 16ccd0c466..7db9ddc75e 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -575,7 +575,6 @@ struct file_buffer { char *b_p_fo; ///< 'formatoptions' char *b_p_flp; ///< 'formatlistpat' int b_p_inf; ///< 'infercase' - char *b_p_ise; ///< 'isexpand' local value char *b_p_isk; ///< 'iskeyword' char *b_p_def; ///< 'define' local value char *b_p_inc; ///< 'include' diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 78f384a08c..a2cb13a78a 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -1494,57 +1494,6 @@ M.funcs = { returns = 'table', signature = 'complete_info([{what}])', }, - complete_match = { - args = { 0, 2 }, - base = 0, - desc = [=[ - Searches backward from the given position and returns a List - of matches according to the 'isexpand' option. When no - arguments are provided, uses the current cursor position. - - Each match is represented as a List containing - [startcol, trigger_text] where: - - startcol: column position where completion should start, - or -1 if no trigger position is found. For multi-character - triggers, returns the column of the first character. - - trigger_text: the matching trigger string from 'isexpand', - or empty string if no match was found or when using the - default 'iskeyword' pattern. - - When 'isexpand' is empty, uses the 'iskeyword' pattern "\k\+$" - to find the start of the current keyword. - - Examples: >vim - set isexpand=.,->,/,/*,abc - func CustomComplete() - let res = complete_match() - if res->len() == 0 | return | endif - let [col, trigger] = res[0] - let items = [] - if trigger == '/*' - let items = ['/** */'] - elseif trigger == '/' - let items = ['/*! */', '// TODO:', '// fixme:'] - elseif trigger == '.' - let items = ['length()'] - elseif trigger =~ '^\->' - let items = ['map()', 'reduce()'] - elseif trigger =~ '^\abc' - let items = ['def', 'ghk'] - endif - if items->len() > 0 - let startcol = trigger =~ '^/' ? col : col + len(trigger) - call complete(startcol, items) - endif - endfunc - inoremap call CustomComplete() - < - ]=], - name = 'complete_match', - params = { { 'lnum', 'integer' }, { 'col', 'integer' } }, - returns = 'table', - signature = 'complete_match([{lnum}, {col}])', - }, confirm = { args = { 1, 4 }, base = 1, diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index c833cc7999..05bd31061c 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -3458,94 +3458,6 @@ void f_complete_check(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) RedrawingDisabled = saved; } -/// Add match item to the return list. -static void add_match_to_list(typval_T *rettv, char *str, int pos) -{ - list_T *match = tv_list_alloc(2); - tv_list_append_number(match, pos + 1); - tv_list_append_string(match, str, -1); - tv_list_append_list(rettv->vval.v_list, match); -} - -/// "complete_match()" function -void f_complete_match(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) -{ - tv_list_alloc_ret(rettv, kListLenUnknown); - - char *ise = curbuf->b_p_ise[0] != NUL ? curbuf->b_p_ise : p_ise; - - linenr_T lnum = 0; - colnr_T col = 0; - char part[MAXPATHL]; - if (argvars[0].v_type == VAR_UNKNOWN) { - lnum = curwin->w_cursor.lnum; - col = curwin->w_cursor.col; - } else if (argvars[1].v_type == VAR_UNKNOWN) { - emsg(_(e_invarg)); - return; - } else { - lnum = (linenr_T)tv_get_number(&argvars[0]); - col = (colnr_T)tv_get_number(&argvars[1]); - if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) { - semsg(_(e_invalid_line_number_nr), lnum); - return; - } - if (col < 1 || col > ml_get_buf_len(curbuf, lnum)) { - semsg(_(e_invalid_column_number_nr), col + 1); - return; - } - } - - char *line = ml_get_buf(curbuf, lnum); - if (line == NULL) { - return; - } - - char *before_cursor = xstrnsave(line, (size_t)col); - - if (ise == NULL || *ise == NUL) { - regmatch_T regmatch; - regmatch.regprog = vim_regcomp("\\k\\+$", RE_MAGIC); - if (regmatch.regprog != NULL) { - if (vim_regexec_nl(®match, before_cursor, (colnr_T)0)) { - char *trig = xstrnsave(regmatch.startp[0], (size_t)(regmatch.endp[0] - regmatch.startp[0])); - int bytepos = (int)(regmatch.startp[0] - before_cursor); - add_match_to_list(rettv, trig, bytepos); - xfree(trig); - } - vim_regfree(regmatch.regprog); - } - } else { - char *p = ise; - char *p_space = NULL; - char *cur_end = before_cursor + (int)strlen(before_cursor); - - while (*p != NUL) { - size_t len = 0; - if (p_space) { - len = (size_t)(p - p_space - 1); - memcpy(part, p_space + 1, len); - p_space = NULL; - } else { - char *next_comma = strchr((*p == ',') ? p + 1 : p, ','); - if (next_comma && *(next_comma + 1) == ' ') { - p_space = next_comma; - } - len = copy_option_part(&p, part, MAXPATHL, ","); - } - - if (len > 0 && (int)len <= col) { - if (strncmp(cur_end - len, part, len) == 0) { - int bytepos = col - (int)len; - add_match_to_list(rettv, part, bytepos); - } - } - } - } - - xfree(before_cursor); -} - /// Return Insert completion mode name string static char *ins_compl_mode(void) { diff --git a/src/nvim/option.c b/src/nvim/option.c index 196077c047..714f69a1ec 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4467,8 +4467,6 @@ void *get_varp_scope_from(vimoption_T *p, int opt_flags, buf_T *buf, win_T *win) return &(buf->b_p_inc); case kOptCompleteopt: return &(buf->b_p_cot); - case kOptIsexpand: - return &(buf->b_p_ise); case kOptDictionary: return &(buf->b_p_dict); case kOptDiffanchors: @@ -4558,8 +4556,6 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win) return *buf->b_p_inc != NUL ? &(buf->b_p_inc) : p->var; case kOptCompleteopt: return *buf->b_p_cot != NUL ? &(buf->b_p_cot) : p->var; - case kOptIsexpand: - return *buf->b_p_ise != NUL ? &(buf->b_p_ise) : p->var; case kOptDictionary: return *buf->b_p_dict != NUL ? &(buf->b_p_dict) : p->var; case kOptDiffanchors: @@ -5267,7 +5263,6 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_dict = empty_string_option; buf->b_p_dia = empty_string_option; buf->b_p_tsr = empty_string_option; - buf->b_p_ise = empty_string_option; buf->b_p_tsrfu = empty_string_option; buf->b_p_qe = xstrdup(p_qe); COPY_OPT_SCTX(buf, kBufOptQuoteescape); diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index 947350e9d2..f972d59cce 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -379,7 +379,6 @@ EXTERN int p_is; ///< 'incsearch' EXTERN char *p_inde; ///< 'indentexpr' EXTERN char *p_indk; ///< 'indentkeys' EXTERN char *p_icm; ///< 'inccommand' -EXTERN char *p_ise; ///< 'isexpand' EXTERN char *p_isf; ///< 'isfname' EXTERN char *p_isi; ///< 'isident' EXTERN char *p_isk; ///< 'iskeyword' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index ec1d5579c6..be4e5db1e6 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -4799,33 +4799,6 @@ local options = { type = 'boolean', immutable = true, }, - { - abbreviation = 'ise', - cb = 'did_set_isexpand', - defaults = '', - deny_duplicates = true, - desc = [=[ - Defines characters and patterns for completion in insert mode. Used - by the |complete_match()| function to determine the starting position - for completion. This is a comma-separated list of triggers. Each - trigger can be: - - A single character like "." or "/" - - A sequence of characters like "->", "/*", or "/**" - - Note: Use "\\," to add a literal comma as trigger character, see - |option-backslash|. - - Examples: >vim - set isexpand=.,->,/*,\\, - < - ]=], - full_name = 'isexpand', - list = 'onecomma', - scope = { 'global', 'buf' }, - short_desc = N_('Defines characters and patterns for completion in insert mode'), - type = 'string', - varname = 'p_ise', - }, { abbreviation = 'isf', cb = 'did_set_isopt', diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 2301cc3fc0..ac4990e1b6 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -90,7 +90,6 @@ void didset_string_options(void) check_str_opt(kOptCasemap, NULL); check_str_opt(kOptBackupcopy, NULL); check_str_opt(kOptBelloff, NULL); - check_str_opt(kOptIsexpand, NULL); check_str_opt(kOptCompleteopt, NULL); check_str_opt(kOptSessionoptions, NULL); check_str_opt(kOptViewoptions, NULL); @@ -1384,44 +1383,6 @@ const char *did_set_inccommand(optset_T *args FUNC_ATTR_UNUSED) return did_set_str_generic(args); } -/// The 'isexpand' option is changed. -const char *did_set_isexpand(optset_T *args) -{ - char *ise = p_ise; - char *p; - bool last_was_comma = false; - - if (args->os_flags & OPT_LOCAL) { - ise = curbuf->b_p_ise; - } - - for (p = ise; *p != NUL;) { - if (*p == '\\' && p[1] == ',') { - p += 2; - last_was_comma = false; - continue; - } - - if (*p == ',') { - if (last_was_comma) { - return e_invarg; - } - last_was_comma = true; - p++; - continue; - } - - last_was_comma = false; - MB_PTR_ADV(p); - } - - if (last_was_comma) { - return e_invarg; - } - - return NULL; -} - /// The 'iskeyword' option is changed. const char *did_set_iskeyword(optset_T *args) { diff --git a/test/old/testdir/gen_opt_test.vim b/test/old/testdir/gen_opt_test.vim index bcfd6c09df..af968181e3 100644 --- a/test/old/testdir/gen_opt_test.vim +++ b/test/old/testdir/gen_opt_test.vim @@ -265,7 +265,6 @@ let test_values = { \ 'helplang': [['', 'de', 'de,it'], ['xxx']], "\ 'highlight': [['', 'e:Error'], ['xxx']], "\ 'imactivatekey': [['', 'S-space'], ['xxx']], - \ 'isexpand': [['', '.,->', '/,/*,\\,'], [',,', '\\,,']], \ 'isfname': [['', '@', '@,48-52'], ['xxx', '@48']], \ 'isident': [['', '@', '@,48-52'], ['xxx', '@48']], \ 'iskeyword': [['', '@', '@,48-52'], ['xxx', '@48']], diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index 5ec0129e37..c6f64840a5 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -4919,99 +4919,6 @@ func Test_nearest_cpt_option() delfunc PrintMenuWords endfunc -func Test_complete_match() - set isexpand=.,/,->,abc,/*,_ - func TestComplete() - let res = complete_match() - if res->len() == 0 - return - endif - let [startcol, expandchar] = res[0] - - if startcol >= 0 - let line = getline('.') - - let items = [] - if expandchar == '/*' - let items = ['/** */'] - elseif expandchar =~ '^/' - let items = ['/*! */', '// TODO:', '// fixme:'] - elseif expandchar =~ '^\.' && startcol < 4 - let items = ['length()', 'push()', 'pop()', 'slice()'] - elseif expandchar =~ '^\.' && startcol > 4 - let items = ['map()', 'filter()', 'reduce()'] - elseif expandchar =~ '^\abc' - let items = ['def', 'ghk'] - elseif expandchar =~ '^\->' - let items = ['free()', 'xfree()'] - else - let items = ['test1', 'test2', 'test3'] - endif - - call complete(expandchar =~ '^/' ? startcol : startcol + strlen(expandchar), items) - endif - endfunc - - new - inoremap call TestComplete() - - call feedkeys("S/*\\", 'tx') - call assert_equal('/** */', getline('.')) - - call feedkeys("S/\\\", 'tx') - call assert_equal('// TODO:', getline('.')) - - call feedkeys("Swp.\\\", 'tx') - call assert_equal('wp.push()', getline('.')) - - call feedkeys("Swp.property.\\\", 'tx') - call assert_equal('wp.property.filter()', getline('.')) - - call feedkeys("Sp->\\\", 'tx') - call assert_equal('p->xfree()', getline('.')) - - call feedkeys("Swp->property.\\", 'tx') - call assert_equal('wp->property.map()', getline('.')) - - call feedkeys("Sabc\\", 'tx') - call assert_equal('abcdef', getline('.')) - - call feedkeys("S_\\", 'tx') - call assert_equal('_test1', getline('.')) - - set ise& - call feedkeys("Sabc \:let g:result=complete_match()\", 'tx') - call assert_equal([[1, 'abc']], g:result) - - call assert_fails('call complete_match(99, 0)', 'E966:') - call assert_fails('call complete_match(1, 99)', 'E964:') - call assert_fails('call complete_match(1)', 'E474:') - - set ise=你好,好 - call feedkeys("S你好 \:let g:result=complete_match()\", 'tx') - call assert_equal([[1, '你好'], [4, '好']], g:result) - - set ise=\\,,-> - call feedkeys("Sabc, \:let g:result=complete_match()\", 'tx') - call assert_equal([[4, ',']], g:result) - - set ise=\ ,= - call feedkeys("Sif true \:let g:result=complete_match()\", 'tx') - call assert_equal([[8, ' ']], g:result) - call feedkeys("Slet a = \:let g:result=complete_match()\", 'tx') - call assert_equal([[7, '=']], g:result) - set ise={,\ ,= - call feedkeys("Sif true \:let g:result=complete_match()\", 'tx') - call assert_equal([[8, ' ']], g:result) - call feedkeys("S{ \:let g:result=complete_match()\", 'tx') - call assert_equal([[1, '{']], g:result) - - bw! - unlet g:result - set isexpand& - delfunc TestComplete -endfunc - func Test_register_completion() let @a = "completion test apple application" let @b = "banana behavior better best"