• R/O
  • SSH

vim: コミット

Mirror of the Vim source from https://github.com/vim/vim


コミットメタ情報

リビジョンa10936038ec94f4ce9fec5d7fae57468f5b66c35 (tree)
日時2022-01-18 05:15:02
作者Bram Moolenaar <Bram@vim....>
コミッターBram Moolenaar

ログメッセージ

patch 8.2.4123: complete function cannot be import.Name

Commit: https://github.com/vim/vim/commit/15d1635e50896002fbd4ebbc896b78a155b2487d
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jan 17 20:09:08 2022 +0000

patch 8.2.4123: complete function cannot be import.Name
Problem: Complete function cannot be import.Name.
Solution: Dereference the function name if needed. Also: do not see
"import.Name" as a builtin function. (closes #9541)

変更サマリ

差分

diff -r f06a8d622851 -r a10936038ec9 src/eval.c
--- a/src/eval.c Mon Jan 17 20:15:03 2022 +0100
+++ b/src/eval.c Mon Jan 17 21:15:02 2022 +0100
@@ -626,6 +626,63 @@
626626 }
627627
628628 /*
629+ * "*arg" points to what can be a function name in the form of "import.Name" or
630+ * "Funcref". Return the name of the function. Set "tofree" to something that
631+ * was allocated.
632+ * If "verbose" is FALSE no errors are given.
633+ * Return NULL for any failure.
634+ */
635+ static char_u *
636+deref_function_name(
637+ char_u **arg,
638+ char_u **tofree,
639+ evalarg_T *evalarg,
640+ int verbose)
641+{
642+ typval_T ref;
643+ char_u *name = *arg;
644+
645+ ref.v_type = VAR_UNKNOWN;
646+ if (eval7(arg, &ref, evalarg, FALSE) == FAIL)
647+ return NULL;
648+ if (*skipwhite(*arg) != NUL)
649+ {
650+ if (verbose)
651+ semsg(_(e_trailing_characters_str), *arg);
652+ name = NULL;
653+ }
654+ else if (ref.v_type == VAR_FUNC && ref.vval.v_string != NULL)
655+ {
656+ name = ref.vval.v_string;
657+ ref.vval.v_string = NULL;
658+ *tofree = name;
659+ }
660+ else if (ref.v_type == VAR_PARTIAL && ref.vval.v_partial != NULL)
661+ {
662+ if (ref.vval.v_partial->pt_argc > 0
663+ || ref.vval.v_partial->pt_dict != NULL)
664+ {
665+ if (verbose)
666+ emsg(_(e_cannot_use_partial_here));
667+ name = NULL;
668+ }
669+ else
670+ {
671+ name = vim_strsave(partial_name(ref.vval.v_partial));
672+ *tofree = name;
673+ }
674+ }
675+ else
676+ {
677+ if (verbose)
678+ semsg(_(e_not_callable_type_str), name);
679+ name = NULL;
680+ }
681+ clear_tv(&ref);
682+ return name;
683+}
684+
685+/*
629686 * Call some Vim script function and return the result in "*rettv".
630687 * Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc]
631688 * should have type VAR_UNKNOWN.
@@ -640,15 +697,27 @@
640697 {
641698 int ret;
642699 funcexe_T funcexe;
700+ char_u *arg;
701+ char_u *name;
702+ char_u *tofree = NULL;
643703
644704 rettv->v_type = VAR_UNKNOWN; // clear_tv() uses this
645705 CLEAR_FIELD(funcexe);
646706 funcexe.fe_firstline = curwin->w_cursor.lnum;
647707 funcexe.fe_lastline = curwin->w_cursor.lnum;
648708 funcexe.fe_evaluate = TRUE;
649- ret = call_func(func, -1, rettv, argc, argv, &funcexe);
709+
710+ // The name might be "import.Func" or "Funcref".
711+ arg = func;
712+ name = deref_function_name(&arg, &tofree, &EVALARG_EVALUATE, FALSE);
713+ if (name == NULL)
714+ name = func;
715+
716+ ret = call_func(name, -1, rettv, argc, argv, &funcexe);
717+
650718 if (ret == FAIL)
651719 clear_tv(rettv);
720+ vim_free(tofree);
652721
653722 return ret;
654723 }
@@ -3979,57 +4048,16 @@
39794048 if (**arg != '(' && alias == NULL
39804049 && (paren = vim_strchr(*arg, '(')) != NULL)
39814050 {
3982- typval_T ref;
3983-
39844051 *arg = name;
39854052 *paren = NUL;
3986- ref.v_type = VAR_UNKNOWN;
3987- if (eval7(arg, &ref, evalarg, FALSE) == FAIL)
4053+ name = deref_function_name(arg, &tofree, evalarg, verbose);
4054+ if (name == NULL)
39884055 {
39894056 *arg = name + len;
39904057 ret = FAIL;
39914058 }
3992- else if (*skipwhite(*arg) != NUL)
3993- {
3994- if (verbose)
3995- semsg(_(e_trailing_characters_str), *arg);
3996- ret = FAIL;
3997- }
3998- else if (ref.v_type == VAR_FUNC && ref.vval.v_string != NULL)
3999- {
4000- name = ref.vval.v_string;
4001- ref.vval.v_string = NULL;
4002- tofree = name;
4059+ else
40034060 len = STRLEN(name);
4004- }
4005- else if (ref.v_type == VAR_PARTIAL && ref.vval.v_partial != NULL)
4006- {
4007- if (ref.vval.v_partial->pt_argc > 0
4008- || ref.vval.v_partial->pt_dict != NULL)
4009- {
4010- emsg(_(e_cannot_use_partial_here));
4011- ret = FAIL;
4012- }
4013- else
4014- {
4015- name = vim_strsave(partial_name(ref.vval.v_partial));
4016- tofree = name;
4017- if (name == NULL)
4018- {
4019- ret = FAIL;
4020- name = *arg;
4021- }
4022- else
4023- len = STRLEN(name);
4024- }
4025- }
4026- else
4027- {
4028- if (verbose)
4029- semsg(_(e_not_callable_type_str), name);
4030- ret = FAIL;
4031- }
4032- clear_tv(&ref);
40334061 *paren = '(';
40344062 }
40354063
diff -r f06a8d622851 -r a10936038ec9 src/testdir/test_vim9_import.vim
--- a/src/testdir/test_vim9_import.vim Mon Jan 17 20:15:03 2022 +0100
+++ b/src/testdir/test_vim9_import.vim Mon Jan 17 21:15:02 2022 +0100
@@ -580,6 +580,29 @@
580580 nunmap <F3>
581581 enddef
582582
583+def Test_use_import_in_completion()
584+ var lines =<< trim END
585+ vim9script
586+ export def Complete(..._): list<string>
587+ return ['abcd']
588+ enddef
589+ END
590+ writefile(lines, 'Xscript.vim')
591+
592+ lines =<< trim END
593+ vim9script
594+ import './Xscript.vim'
595+
596+ command -nargs=1 -complete=customlist,Xscript.Complete Cmd echo 'ok'
597+ feedkeys(":Cmd ab\<Tab>\<C-B>#\<CR>", 'xnt')
598+ assert_equal('#Cmd abcd', @:)
599+ END
600+ CheckScriptSuccess(lines)
601+
602+ delcommand Cmd
603+ delete('Xscript.vim')
604+enddef
605+
583606 def Test_export_fails()
584607 CheckScriptFailure(['export var some = 123'], 'E1042:')
585608 CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
diff -r f06a8d622851 -r a10936038ec9 src/userfunc.c
--- a/src/userfunc.c Mon Jan 17 20:15:03 2022 +0100
+++ b/src/userfunc.c Mon Jan 17 21:15:02 2022 +0100
@@ -3119,18 +3119,30 @@
31193119
31203120 /*
31213121 * Return TRUE if "name" looks like a builtin function name: starts with a
3122- * lower case letter and doesn't contain AUTOLOAD_CHAR or ':'.
3122+ * lower case letter, doesn't contain AUTOLOAD_CHAR or ':', no "." after the
3123+ * name.
31233124 * "len" is the length of "name", or -1 for NUL terminated.
31243125 */
31253126 int
31263127 builtin_function(char_u *name, int len)
31273128 {
3128- char_u *p;
3129+ int i;
31293130
31303131 if (!ASCII_ISLOWER(name[0]) || name[1] == ':')
31313132 return FALSE;
3132- p = vim_strchr(name, AUTOLOAD_CHAR);
3133- return p == NULL || (len > 0 && p > name + len);
3133+ for (i = 0; name[i] != NUL && (len < 0 || i < len); ++i)
3134+ {
3135+ if (name[i] == AUTOLOAD_CHAR)
3136+ return FALSE;
3137+ if (!eval_isnamec(name[i]))
3138+ {
3139+ // "name.something" is not a builtin function
3140+ if (name[i] == '.')
3141+ return FALSE;
3142+ break;
3143+ }
3144+ }
3145+ return TRUE;
31343146 }
31353147
31363148 int
diff -r f06a8d622851 -r a10936038ec9 src/version.c
--- a/src/version.c Mon Jan 17 20:15:03 2022 +0100
+++ b/src/version.c Mon Jan 17 21:15:02 2022 +0100
@@ -751,6 +751,8 @@
751751 static int included_patches[] =
752752 { /* Add new patch number below this line */
753753 /**/
754+ 4123,
755+/**/
754756 4122,
755757 /**/
756758 4121,
旧リポジトリブラウザで表示