diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-09 21:36:37 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-09 21:36:37 +0000 |
commit | dc4451df61a6aa12a0661817b7094fb32f09e11d (patch) | |
tree | 98d2ef08366773a3eadb41ec581b1c5e652e3114 /src/vim9script.c | |
parent | 5f25c3855071bd7e26255c68bf458b1b5cf92f39 (diff) | |
download | vim-git-dc4451df61a6aa12a0661817b7094fb32f09e11d.tar.gz |
patch 8.2.4050: Vim9: need to prefix every item in an autoload scriptv8.2.4050
Problem: Vim9: need to prefix every item in an autoload script.
Solution: First step in supporting "vim9script autoload" and "import
autoload".
Diffstat (limited to 'src/vim9script.c')
-rw-r--r-- | src/vim9script.c | 109 |
1 files changed, 88 insertions, 21 deletions
diff --git a/src/vim9script.c b/src/vim9script.c index 3ebeab366..a8b76bb6c 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -68,6 +68,9 @@ ex_vim9script(exarg_T *eap UNUSED) #ifdef FEAT_EVAL int sid = current_sctx.sc_sid; scriptitem_T *si; + int found_noclear = FALSE; + int found_autoload = FALSE; + char_u *p; if (!getline_equal(eap->getline, eap->cookie, getsourceline)) { @@ -81,12 +84,40 @@ ex_vim9script(exarg_T *eap UNUSED) emsg(_(e_vim9script_must_be_first_command_in_script)); return; } - if (!IS_WHITE_OR_NUL(*eap->arg) && STRCMP(eap->arg, "noclear") != 0) + + for (p = eap->arg; !IS_WHITE_OR_NUL(*p); p = skipwhite(skiptowhite(p))) { - semsg(_(e_invalid_argument_str), eap->arg); - return; + if (STRNCMP(p, "noclear", 7) == 0 && IS_WHITE_OR_NUL(p[7])) + { + if (found_noclear) + { + semsg(_(e_duplicate_argument_str), p); + return; + } + found_noclear = TRUE; + } + else if (STRNCMP(p, "autoload", 8) == 0 && IS_WHITE_OR_NUL(p[8])) + { + if (found_autoload) + { + semsg(_(e_duplicate_argument_str), p); + return; + } + found_autoload = TRUE; + if (script_name_after_autoload(si) == NULL) + { + emsg(_(e_using_autoload_in_script_not_under_autoload_directory)); + return; + } + } + else + { + semsg(_(e_invalid_argument_str), eap->arg); + return; + } } - if (si->sn_state == SN_STATE_RELOAD && IS_WHITE_OR_NUL(*eap->arg)) + + if (si->sn_state == SN_STATE_RELOAD && !found_noclear) { hashtab_T *ht = &SCRIPT_VARS(sid); @@ -101,6 +132,8 @@ ex_vim9script(exarg_T *eap UNUSED) } si->sn_state = SN_STATE_HAD_COMMAND; + si->sn_is_autoload = found_autoload; + current_sctx.sc_version = SCRIPT_VERSION_VIM9; si->sn_version = SCRIPT_VERSION_VIM9; @@ -366,6 +399,7 @@ handle_import( { char_u *arg = arg_start; char_u *nextarg; + int is_autoload = FALSE; int getnext; char_u *expr_end; int ret = FAIL; @@ -377,6 +411,12 @@ handle_import( garray_T *import_gap; int i; + if (STRNCMP(arg, "autoload", 8) == 0 && VIM_ISWHITE(arg[8])) + { + is_autoload = TRUE; + arg = skipwhite(arg + 8); + } + // The name of the file can be an expression, which must evaluate to a // string. ret = eval0_retarg(arg, &tv, NULL, evalarg, &expr_end); @@ -402,23 +442,48 @@ handle_import( char_u *tail = gettail(si->sn_name); char_u *from_name; - // Relative to current script: "./name.vim", "../../name.vim". - len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2; - from_name = alloc((int)len); - if (from_name == NULL) - goto erret; - vim_strncpy(from_name, si->sn_name, tail - si->sn_name); - add_pathsep(from_name); - STRCAT(from_name, tv.vval.v_string); - simplify_filename(from_name); + if (is_autoload) + res = FAIL; + else + { - res = do_source(from_name, FALSE, DOSO_NONE, &sid); - vim_free(from_name); + // Relative to current script: "./name.vim", "../../name.vim". + len = STRLEN(si->sn_name) - STRLEN(tail) + + STRLEN(tv.vval.v_string) + 2; + from_name = alloc((int)len); + if (from_name == NULL) + goto erret; + vim_strncpy(from_name, si->sn_name, tail - si->sn_name); + add_pathsep(from_name); + STRCAT(from_name, tv.vval.v_string); + simplify_filename(from_name); + + res = do_source(from_name, FALSE, DOSO_NONE, &sid); + vim_free(from_name); + } } else if (mch_isFullName(tv.vval.v_string)) { // Absolute path: "/tmp/name.vim" - res = do_source(tv.vval.v_string, FALSE, DOSO_NONE, &sid); + if (is_autoload) + res = FAIL; + else + res = do_source(tv.vval.v_string, FALSE, DOSO_NONE, &sid); + } + else if (is_autoload) + { + size_t len = 9 + STRLEN(tv.vval.v_string) + 1; + char_u *from_name; + + // Find file in "autoload" subdirs in 'runtimepath'. + from_name = alloc((int)len); + if (from_name == NULL) + goto erret; + vim_snprintf((char *)from_name, len, "autoload/%s", tv.vval.v_string); + // we need a scriptitem without loading the script + sid = find_script_in_rtp(from_name); + vim_free(from_name); + res = SCRIPT_ID_VALID(sid) ? OK : FAIL; } else { @@ -428,9 +493,7 @@ handle_import( // Find file in "import" subdirs in 'runtimepath'. from_name = alloc((int)len); if (from_name == NULL) - { goto erret; - } vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string); res = source_in_path(p_rtp, from_name, DIP_NOAFTER, &sid); vim_free(from_name); @@ -438,7 +501,9 @@ handle_import( if (res == FAIL || sid <= 0) { - semsg(_(e_could_not_import_str), tv.vval.v_string); + semsg(_(is_autoload && sid <= 0 + ? e_autoload_import_cannot_use_absolute_or_relative_path + : e_could_not_import_str), tv.vval.v_string); goto erret; } @@ -451,7 +516,7 @@ handle_import( { if (import->imp_flags & IMP_FLAGS_RELOAD) { - // encountering same script first ime on a reload is OK + // encountering same script first time on a reload is OK import->imp_flags &= ~IMP_FLAGS_RELOAD; break; } @@ -513,7 +578,7 @@ handle_import( { imported_T *imported; - imported = find_imported(as_name, STRLEN(as_name), cctx); + imported = find_imported(as_name, FALSE, STRLEN(as_name), cctx); if (imported != NULL && imported->imp_sid != sid) { semsg(_(e_name_already_defined_str), as_name); @@ -529,6 +594,8 @@ handle_import( imported->imp_name = as_name; as_name = NULL; imported->imp_sid = sid; + if (is_autoload) + imported->imp_flags = IMP_FLAGS_AUTOLOAD; } erret: |