]> granicus.if.org Git - vim/commitdiff
patch 8.1.1957: more code can be moved to evalvars.c v8.1.1957
authorBram Moolenaar <Bram@vim.org>
Sun, 1 Sep 2019 14:01:30 +0000 (16:01 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 1 Sep 2019 14:01:30 +0000 (16:01 +0200)
Problem:    More code can be moved to evalvars.c.
Solution:   Move code to where it fits better. (Yegappan Lakshmanan,
            closes #4883)

13 files changed:
src/eval.c
src/evalvars.c
src/ex_getln.c
src/globals.h
src/if_py_both.h
src/proto/eval.pro
src/proto/evalvars.pro
src/proto/ex_getln.pro
src/proto/scriptfile.pro
src/scriptfile.c
src/session.c
src/version.c
src/viminfo.c

index f32092c82164775069a9b601a5c7df0504844716..e75624345a1d1181fb269923035f47b4863d9c64 100644 (file)
@@ -38,9 +38,6 @@ static int current_copyID = 0;
 
 static int echo_attr = 0;   /* attributes used for ":echo" */
 
-/* The names of packages that once were loaded are remembered. */
-static garray_T                ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
-
 /*
  * Info used by a ":for" loop.
  */
@@ -156,8 +153,8 @@ eval_clear(void)
     free_scriptnames();
     free_locales();
 
-    /* autoloaded script names */
-    ga_clear_strings(&ga_loaded);
+    // autoloaded script names
+    free_autoload_scriptnames();
 
     // unreferenced lists and dicts
     (void)garbage_collect(FALSE);
@@ -167,240 +164,6 @@ eval_clear(void)
 }
 #endif
 
-static lval_T  *redir_lval = NULL;
-#define EVALCMD_BUSY (redir_lval == (lval_T *)&redir_lval)
-static garray_T redir_ga;      /* only valid when redir_lval is not NULL */
-static char_u  *redir_endp = NULL;
-static char_u  *redir_varname = NULL;
-
-/*
- * Start recording command output to a variable
- * When "append" is TRUE append to an existing variable.
- * Returns OK if successfully completed the setup.  FAIL otherwise.
- */
-    int
-var_redir_start(char_u *name, int append)
-{
-    int                save_emsg;
-    int                err;
-    typval_T   tv;
-
-    /* Catch a bad name early. */
-    if (!eval_isnamec1(*name))
-    {
-       emsg(_(e_invarg));
-       return FAIL;
-    }
-
-    /* Make a copy of the name, it is used in redir_lval until redir ends. */
-    redir_varname = vim_strsave(name);
-    if (redir_varname == NULL)
-       return FAIL;
-
-    redir_lval = ALLOC_CLEAR_ONE(lval_T);
-    if (redir_lval == NULL)
-    {
-       var_redir_stop();
-       return FAIL;
-    }
-
-    /* The output is stored in growarray "redir_ga" until redirection ends. */
-    ga_init2(&redir_ga, (int)sizeof(char), 500);
-
-    /* Parse the variable name (can be a dict or list entry). */
-    redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
-                                                            FNE_CHECK_START);
-    if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
-    {
-       clear_lval(redir_lval);
-       if (redir_endp != NULL && *redir_endp != NUL)
-           /* Trailing characters are present after the variable name */
-           emsg(_(e_trailing));
-       else
-           emsg(_(e_invarg));
-       redir_endp = NULL;  /* don't store a value, only cleanup */
-       var_redir_stop();
-       return FAIL;
-    }
-
-    /* check if we can write to the variable: set it to or append an empty
-     * string */
-    save_emsg = did_emsg;
-    did_emsg = FALSE;
-    tv.v_type = VAR_STRING;
-    tv.vval.v_string = (char_u *)"";
-    if (append)
-       set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)".");
-    else
-       set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"=");
-    clear_lval(redir_lval);
-    err = did_emsg;
-    did_emsg |= save_emsg;
-    if (err)
-    {
-       redir_endp = NULL;  /* don't store a value, only cleanup */
-       var_redir_stop();
-       return FAIL;
-    }
-
-    return OK;
-}
-
-/*
- * Append "value[value_len]" to the variable set by var_redir_start().
- * The actual appending is postponed until redirection ends, because the value
- * appended may in fact be the string we write to, changing it may cause freed
- * memory to be used:
- *   :redir => foo
- *   :let foo
- *   :redir END
- */
-    void
-var_redir_str(char_u *value, int value_len)
-{
-    int                len;
-
-    if (redir_lval == NULL)
-       return;
-
-    if (value_len == -1)
-       len = (int)STRLEN(value);       /* Append the entire string */
-    else
-       len = value_len;                /* Append only "value_len" characters */
-
-    if (ga_grow(&redir_ga, len) == OK)
-    {
-       mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
-       redir_ga.ga_len += len;
-    }
-    else
-       var_redir_stop();
-}
-
-/*
- * Stop redirecting command output to a variable.
- * Frees the allocated memory.
- */
-    void
-var_redir_stop(void)
-{
-    typval_T   tv;
-
-    if (EVALCMD_BUSY)
-    {
-       redir_lval = NULL;
-       return;
-    }
-
-    if (redir_lval != NULL)
-    {
-       /* If there was no error: assign the text to the variable. */
-       if (redir_endp != NULL)
-       {
-           ga_append(&redir_ga, NUL);  /* Append the trailing NUL. */
-           tv.v_type = VAR_STRING;
-           tv.vval.v_string = redir_ga.ga_data;
-           /* Call get_lval() again, if it's inside a Dict or List it may
-            * have changed. */
-           redir_endp = get_lval(redir_varname, NULL, redir_lval,
-                                       FALSE, FALSE, 0, FNE_CHECK_START);
-           if (redir_endp != NULL && redir_lval->ll_name != NULL)
-               set_var_lval(redir_lval, redir_endp, &tv, FALSE, FALSE,
-                                                               (char_u *)".");
-           clear_lval(redir_lval);
-       }
-
-       /* free the collected output */
-       VIM_CLEAR(redir_ga.ga_data);
-
-       VIM_CLEAR(redir_lval);
-    }
-    VIM_CLEAR(redir_varname);
-}
-
-    int
-eval_charconvert(
-    char_u     *enc_from,
-    char_u     *enc_to,
-    char_u     *fname_from,
-    char_u     *fname_to)
-{
-    int                err = FALSE;
-
-    set_vim_var_string(VV_CC_FROM, enc_from, -1);
-    set_vim_var_string(VV_CC_TO, enc_to, -1);
-    set_vim_var_string(VV_FNAME_IN, fname_from, -1);
-    set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
-    if (eval_to_bool(p_ccv, &err, NULL, FALSE))
-       err = TRUE;
-    set_vim_var_string(VV_CC_FROM, NULL, -1);
-    set_vim_var_string(VV_CC_TO, NULL, -1);
-    set_vim_var_string(VV_FNAME_IN, NULL, -1);
-    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
-
-    if (err)
-       return FAIL;
-    return OK;
-}
-
-# if defined(FEAT_POSTSCRIPT) || defined(PROTO)
-    int
-eval_printexpr(char_u *fname, char_u *args)
-{
-    int                err = FALSE;
-
-    set_vim_var_string(VV_FNAME_IN, fname, -1);
-    set_vim_var_string(VV_CMDARG, args, -1);
-    if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
-       err = TRUE;
-    set_vim_var_string(VV_FNAME_IN, NULL, -1);
-    set_vim_var_string(VV_CMDARG, NULL, -1);
-
-    if (err)
-    {
-       mch_remove(fname);
-       return FAIL;
-    }
-    return OK;
-}
-# endif
-
-# if defined(FEAT_DIFF) || defined(PROTO)
-    void
-eval_diff(
-    char_u     *origfile,
-    char_u     *newfile,
-    char_u     *outfile)
-{
-    int                err = FALSE;
-
-    set_vim_var_string(VV_FNAME_IN, origfile, -1);
-    set_vim_var_string(VV_FNAME_NEW, newfile, -1);
-    set_vim_var_string(VV_FNAME_OUT, outfile, -1);
-    (void)eval_to_bool(p_dex, &err, NULL, FALSE);
-    set_vim_var_string(VV_FNAME_IN, NULL, -1);
-    set_vim_var_string(VV_FNAME_NEW, NULL, -1);
-    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
-}
-
-    void
-eval_patch(
-    char_u     *origfile,
-    char_u     *difffile,
-    char_u     *outfile)
-{
-    int                err;
-
-    set_vim_var_string(VV_FNAME_IN, origfile, -1);
-    set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
-    set_vim_var_string(VV_FNAME_OUT, outfile, -1);
-    (void)eval_to_bool(p_pex, &err, NULL, FALSE);
-    set_vim_var_string(VV_FNAME_IN, NULL, -1);
-    set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
-    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
-}
-# endif
-
 /*
  * Top level evaluation function, returning a boolean.
  * Sets "error" to TRUE if there was an error.
@@ -671,65 +434,6 @@ eval_to_number(char_u *expr)
     return retval;
 }
 
-#if defined(FEAT_SPELL) || defined(PROTO)
-/*
- * Evaluate an expression to a list with suggestions.
- * For the "expr:" part of 'spellsuggest'.
- * Returns NULL when there is an error.
- */
-    list_T *
-eval_spell_expr(char_u *badword, char_u *expr)
-{
-    typval_T   save_val;
-    typval_T   rettv;
-    list_T     *list = NULL;
-    char_u     *p = skipwhite(expr);
-
-    /* Set "v:val" to the bad word. */
-    prepare_vimvar(VV_VAL, &save_val);
-    set_vim_var_string(VV_VAL, badword, -1);
-    if (p_verbose == 0)
-       ++emsg_off;
-
-    if (eval1(&p, &rettv, TRUE) == OK)
-    {
-       if (rettv.v_type != VAR_LIST)
-           clear_tv(&rettv);
-       else
-           list = rettv.vval.v_list;
-    }
-
-    if (p_verbose == 0)
-       --emsg_off;
-    clear_tv(get_vim_var_tv(VV_VAL));
-    restore_vimvar(VV_VAL, &save_val);
-
-    return list;
-}
-
-/*
- * "list" is supposed to contain two items: a word and a number.  Return the
- * word in "pp" and the number as the return value.
- * Return -1 if anything isn't right.
- * Used to get the good word and score from the eval_spell_expr() result.
- */
-    int
-get_spellword(list_T *list, char_u **pp)
-{
-    listitem_T *li;
-
-    li = list->lv_first;
-    if (li == NULL)
-       return -1;
-    *pp = tv_get_string(&li->li_tv);
-
-    li = li->li_next;
-    if (li == NULL)
-       return -1;
-    return (int)tv_get_number(&li->li_tv);
-}
-#endif
-
 /*
  * Top level evaluation function.
  * Returns an allocated typval_T with the result.
@@ -1153,7 +857,7 @@ get_lval(
            if (lp->ll_di == NULL)
            {
                // Can't add "v:" or "a:" variable.
-               if (lp->ll_dict == &vimvardict
+               if (lp->ll_dict == get_vimvar_dict()
                         || &lp->ll_dict->dv_hashtab == get_funccal_args_ht())
                {
                    semsg(_(e_illvar), name);
@@ -1921,31 +1625,6 @@ set_context_for_expression(
     xp->xp_pattern = arg;
 }
 
-#if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
-/*
- * Delete all "menutrans_" variables.
- */
-    void
-del_menutrans_vars(void)
-{
-    hashitem_T *hi;
-    int                todo;
-
-    hash_lock(&globvarht);
-    todo = (int)globvarht.ht_used;
-    for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
-    {
-       if (!HASHITEM_EMPTY(hi))
-       {
-           --todo;
-           if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
-               delete_var(&globvarht, hi);
-       }
-    }
-    hash_unlock(&globvarht);
-}
-#endif
-
 /*
  * Return TRUE if "pat" matches "text".
  * Does not use 'cpo' and always uses 'magic'.
@@ -4215,7 +3894,7 @@ garbage_collect(int testing)
        abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
                                                                  NULL, NULL);
     /* global variables */
-    abort = abort || set_ref_in_ht(&globvarht, copyID, NULL);
+    abort = abort || garbage_collect_globvars(copyID);
 
     /* function-local variables */
     abort = abort || set_ref_in_call_stack(copyID);
@@ -4630,20 +4309,6 @@ set_ref_in_item(
     return abort;
 }
 
-    static char *
-get_var_special_name(int nr)
-{
-    switch (nr)
-    {
-       case VVAL_FALSE: return "v:false";
-       case VVAL_TRUE:  return "v:true";
-       case VVAL_NONE:  return "v:none";
-       case VVAL_NULL:  return "v:null";
-    }
-    internal_error("get_var_special_name()");
-    return "42";
-}
-
 /*
  * Return a string with the string representation of a variable.
  * If the memory is allocated "tofree" is set to it, otherwise NULL.
@@ -6203,112 +5868,6 @@ item_copy(
     return ret;
 }
 
-/*
- * This function is used by f_input() and f_inputdialog() functions. The third
- * argument to f_input() specifies the type of completion to use at the
- * prompt. The third argument to f_inputdialog() specifies the value to return
- * when the user cancels the prompt.
- */
-    void
-get_user_input(
-    typval_T   *argvars,
-    typval_T   *rettv,
-    int                inputdialog,
-    int                secret)
-{
-    char_u     *prompt = tv_get_string_chk(&argvars[0]);
-    char_u     *p = NULL;
-    int                c;
-    char_u     buf[NUMBUFLEN];
-    int                cmd_silent_save = cmd_silent;
-    char_u     *defstr = (char_u *)"";
-    int                xp_type = EXPAND_NOTHING;
-    char_u     *xp_arg = NULL;
-
-    rettv->v_type = VAR_STRING;
-    rettv->vval.v_string = NULL;
-
-#ifdef NO_CONSOLE_INPUT
-    /* While starting up, there is no place to enter text. When running tests
-     * with --not-a-term we assume feedkeys() will be used. */
-    if (no_console_input() && !is_not_a_term())
-       return;
-#endif
-
-    cmd_silent = FALSE;                /* Want to see the prompt. */
-    if (prompt != NULL)
-    {
-       /* Only the part of the message after the last NL is considered as
-        * prompt for the command line */
-       p = vim_strrchr(prompt, '\n');
-       if (p == NULL)
-           p = prompt;
-       else
-       {
-           ++p;
-           c = *p;
-           *p = NUL;
-           msg_start();
-           msg_clr_eos();
-           msg_puts_attr((char *)prompt, echo_attr);
-           msg_didout = FALSE;
-           msg_starthere();
-           *p = c;
-       }
-       cmdline_row = msg_row;
-
-       if (argvars[1].v_type != VAR_UNKNOWN)
-       {
-           defstr = tv_get_string_buf_chk(&argvars[1], buf);
-           if (defstr != NULL)
-               stuffReadbuffSpec(defstr);
-
-           if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
-           {
-               char_u  *xp_name;
-               int     xp_namelen;
-               long    argt;
-
-               /* input() with a third argument: completion */
-               rettv->vval.v_string = NULL;
-
-               xp_name = tv_get_string_buf_chk(&argvars[2], buf);
-               if (xp_name == NULL)
-                   return;
-
-               xp_namelen = (int)STRLEN(xp_name);
-
-               if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
-                                                            &xp_arg) == FAIL)
-                   return;
-           }
-       }
-
-       if (defstr != NULL)
-       {
-           int save_ex_normal_busy = ex_normal_busy;
-
-           ex_normal_busy = 0;
-           rettv->vval.v_string =
-               getcmdline_prompt(secret ? NUL : '@', p, echo_attr,
-                                                             xp_type, xp_arg);
-           ex_normal_busy = save_ex_normal_busy;
-       }
-       if (inputdialog && rettv->vval.v_string == NULL
-               && argvars[1].v_type != VAR_UNKNOWN
-               && argvars[2].v_type != VAR_UNKNOWN)
-           rettv->vval.v_string = vim_strsave(tv_get_string_buf(
-                                                          &argvars[2], buf));
-
-       vim_free(xp_arg);
-
-       /* since the user typed this, no need to wait for return */
-       need_wait_return = FALSE;
-       msg_didout = FALSE;
-    }
-    cmd_silent = cmd_silent_save;
-}
-
 /*
  * ":echo expr1 ..."   print each argument separated with a space, add a
  *                     newline at the end.
@@ -6424,6 +5983,15 @@ ex_echohl(exarg_T *eap)
     echo_attr = syn_name2attr(eap->arg);
 }
 
+/*
+ * Returns the :echo attribute
+ */
+    int
+get_echo_attr(void)
+{
+    return echo_attr;
+}
+
 /*
  * ":execute expr1 ..."        execute the result of an expression.
  * ":echomsg expr1 ..."        Print a message
@@ -6550,78 +6118,6 @@ find_option_end(char_u **arg, int *opt_flags)
     return p;
 }
 
-/*
- * Return the autoload script name for a function or variable name.
- * Returns NULL when out of memory.
- * Caller must make sure that "name" contains AUTOLOAD_CHAR.
- */
-    char_u *
-autoload_name(char_u *name)
-{
-    char_u     *p, *q = NULL;
-    char_u     *scriptname;
-
-    // Get the script file name: replace '#' with '/', append ".vim".
-    scriptname = alloc(STRLEN(name) + 14);
-    if (scriptname == NULL)
-       return NULL;
-    STRCPY(scriptname, "autoload/");
-    STRCAT(scriptname, name);
-    for (p = scriptname + 9; (p = vim_strchr(p, AUTOLOAD_CHAR)) != NULL;
-                                                                   q = p, ++p)
-       *p = '/';
-    STRCPY(q, ".vim");
-    return scriptname;
-}
-
-/*
- * If "name" has a package name try autoloading the script for it.
- * Return TRUE if a package was loaded.
- */
-    int
-script_autoload(
-    char_u     *name,
-    int                reload)     /* load script again when already loaded */
-{
-    char_u     *p;
-    char_u     *scriptname, *tofree;
-    int                ret = FALSE;
-    int                i;
-
-    /* If there is no '#' after name[0] there is no package name. */
-    p = vim_strchr(name, AUTOLOAD_CHAR);
-    if (p == NULL || p == name)
-       return FALSE;
-
-    tofree = scriptname = autoload_name(name);
-    if (scriptname == NULL)
-       return FALSE;
-
-    /* Find the name in the list of previously loaded package names.  Skip
-     * "autoload/", it's always the same. */
-    for (i = 0; i < ga_loaded.ga_len; ++i)
-       if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
-           break;
-    if (!reload && i < ga_loaded.ga_len)
-       ret = FALSE;        /* was loaded already */
-    else
-    {
-       /* Remember the name if it wasn't loaded already. */
-       if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
-       {
-           ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
-           tofree = NULL;
-       }
-
-       /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
-       if (source_runtime(scriptname, 0) == OK)
-           ret = TRUE;
-    }
-
-    vim_free(tofree);
-    return ret;
-}
-
 /*
  * Display script name where an item was last set.
  * Should only be invoked when 'verbose' is non-zero.
@@ -7739,6 +7235,8 @@ filter_map(typval_T *argvars, typval_T *rettv, int map)
        prepare_vimvar(VV_KEY, &save_key);
        if (argvars[0].v_type == VAR_DICT)
        {
+           set_vim_var_type(VV_KEY, VAR_STRING);
+
            ht = &d->dv_hashtab;
            hash_lock(ht);
            todo = (int)ht->ht_used;
index d7a565af2096eb17acc21d5c1ecc764d743a1c7c..e6fb3d8988b660176e836dcbdfbe447b800ae5ec 100644 (file)
@@ -18,6 +18,8 @@
 static char *e_letunexp        = N_("E18: Unexpected characters in :let");
 
 static dictitem_T      globvars_var;           // variable used for g:
+static dict_T          globvardict;            // Dictionary with g: variables
+#define globvarht globvardict.dv_hashtab
 
 /*
  * Old Vim variables such as "v:version" are also available without the "v:".
@@ -154,6 +156,7 @@ static struct vimvar
 #define vv_tv          vv_di.di_tv
 
 static dictitem_T      vimvars_var;            // variable used for v:
+static dict_T          vimvardict;             // Dictionary with v: variables
 #define vimvarht  vimvardict.dv_hashtab
 
 // for VIM_VERSION_ defines
@@ -185,6 +188,7 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep);
 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit);
 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock);
 static void item_lock(typval_T *tv, int deep, int lock);
+static void delete_var(hashtab_T *ht, hashitem_T *hi);
 static void list_one_var(dictitem_T *v, char *prefix, int *first);
 static void list_one_var_a(char *prefix, char_u *name, int type, char_u *string, int *first);
 
@@ -295,6 +299,12 @@ evalvars_clear(void)
 }
 #endif
 
+    int
+garbage_collect_globvars(int copyID)
+{
+    return set_ref_in_ht(&globvarht, copyID, NULL);
+}
+
     int
 garbage_collect_vimvars(int copyID)
 {
@@ -335,6 +345,148 @@ set_internal_string_var(char_u *name, char_u *value)
     }
 }
 
+    int
+eval_charconvert(
+    char_u     *enc_from,
+    char_u     *enc_to,
+    char_u     *fname_from,
+    char_u     *fname_to)
+{
+    int                err = FALSE;
+
+    set_vim_var_string(VV_CC_FROM, enc_from, -1);
+    set_vim_var_string(VV_CC_TO, enc_to, -1);
+    set_vim_var_string(VV_FNAME_IN, fname_from, -1);
+    set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
+    if (eval_to_bool(p_ccv, &err, NULL, FALSE))
+       err = TRUE;
+    set_vim_var_string(VV_CC_FROM, NULL, -1);
+    set_vim_var_string(VV_CC_TO, NULL, -1);
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+
+    if (err)
+       return FAIL;
+    return OK;
+}
+
+# if defined(FEAT_POSTSCRIPT) || defined(PROTO)
+    int
+eval_printexpr(char_u *fname, char_u *args)
+{
+    int                err = FALSE;
+
+    set_vim_var_string(VV_FNAME_IN, fname, -1);
+    set_vim_var_string(VV_CMDARG, args, -1);
+    if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
+       err = TRUE;
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_CMDARG, NULL, -1);
+
+    if (err)
+    {
+       mch_remove(fname);
+       return FAIL;
+    }
+    return OK;
+}
+# endif
+
+# if defined(FEAT_DIFF) || defined(PROTO)
+    void
+eval_diff(
+    char_u     *origfile,
+    char_u     *newfile,
+    char_u     *outfile)
+{
+    int                err = FALSE;
+
+    set_vim_var_string(VV_FNAME_IN, origfile, -1);
+    set_vim_var_string(VV_FNAME_NEW, newfile, -1);
+    set_vim_var_string(VV_FNAME_OUT, outfile, -1);
+    (void)eval_to_bool(p_dex, &err, NULL, FALSE);
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_FNAME_NEW, NULL, -1);
+    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+}
+
+    void
+eval_patch(
+    char_u     *origfile,
+    char_u     *difffile,
+    char_u     *outfile)
+{
+    int                err;
+
+    set_vim_var_string(VV_FNAME_IN, origfile, -1);
+    set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
+    set_vim_var_string(VV_FNAME_OUT, outfile, -1);
+    (void)eval_to_bool(p_pex, &err, NULL, FALSE);
+    set_vim_var_string(VV_FNAME_IN, NULL, -1);
+    set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
+    set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+}
+# endif
+
+#if defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Evaluate an expression to a list with suggestions.
+ * For the "expr:" part of 'spellsuggest'.
+ * Returns NULL when there is an error.
+ */
+    list_T *
+eval_spell_expr(char_u *badword, char_u *expr)
+{
+    typval_T   save_val;
+    typval_T   rettv;
+    list_T     *list = NULL;
+    char_u     *p = skipwhite(expr);
+
+    // Set "v:val" to the bad word.
+    prepare_vimvar(VV_VAL, &save_val);
+    set_vim_var_string(VV_VAL, badword, -1);
+    if (p_verbose == 0)
+       ++emsg_off;
+
+    if (eval1(&p, &rettv, TRUE) == OK)
+    {
+       if (rettv.v_type != VAR_LIST)
+           clear_tv(&rettv);
+       else
+           list = rettv.vval.v_list;
+    }
+
+    if (p_verbose == 0)
+       --emsg_off;
+    clear_tv(get_vim_var_tv(VV_VAL));
+    restore_vimvar(VV_VAL, &save_val);
+
+    return list;
+}
+
+/*
+ * "list" is supposed to contain two items: a word and a number.  Return the
+ * word in "pp" and the number as the return value.
+ * Return -1 if anything isn't right.
+ * Used to get the good word and score from the eval_spell_expr() result.
+ */
+    int
+get_spellword(list_T *list, char_u **pp)
+{
+    listitem_T *li;
+
+    li = list->lv_first;
+    if (li == NULL)
+       return -1;
+    *pp = tv_get_string(&li->li_tv);
+
+    li = li->li_next;
+    if (li == NULL)
+       return -1;
+    return (int)tv_get_number(&li->li_tv);
+}
+#endif
+
 /*
  * Prepare v: variable "idx" to be used.
  * Save the current typeval in "save_tv".
@@ -1569,6 +1721,31 @@ item_lock(typval_T *tv, int deep, int lock)
     --recurse;
 }
 
+#if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
+/*
+ * Delete all "menutrans_" variables.
+ */
+    void
+del_menutrans_vars(void)
+{
+    hashitem_T *hi;
+    int                todo;
+
+    hash_lock(&globvarht);
+    todo = (int)globvarht.ht_used;
+    for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
+    {
+       if (!HASHITEM_EMPTY(hi))
+       {
+           --todo;
+           if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
+               delete_var(&globvarht, hi);
+       }
+    }
+    hash_unlock(&globvarht);
+}
+#endif
+
 /*
  * Local string buffer for the next two functions to store a variable name
  * with its prefix. Allocated in cat_prefix_varname(), freed later in
@@ -1688,6 +1865,47 @@ get_user_var_name(expand_T *xp, int idx)
     return NULL;
 }
 
+    char *
+get_var_special_name(int nr)
+{
+    switch (nr)
+    {
+       case VVAL_FALSE: return "v:false";
+       case VVAL_TRUE:  return "v:true";
+       case VVAL_NONE:  return "v:none";
+       case VVAL_NULL:  return "v:null";
+    }
+    internal_error("get_var_special_name()");
+    return "42";
+}
+
+/*
+ * Returns the global variable dictionary
+ */
+    dict_T *
+get_globvar_dict(void)
+{
+    return &globvardict;
+}
+
+/*
+ * Returns the global variable hash table
+ */
+    hashtab_T *
+get_globvar_ht(void)
+{
+    return &globvarht;
+}
+
+/*
+ * Returns the v: variable dictionary
+ */
+    dict_T *
+get_vimvar_dict(void)
+{
+    return &vimvardict;
+}
+
 /*
  * Set type of v: variable to "type".
  */
@@ -2321,7 +2539,7 @@ vars_clear_ext(hashtab_T *ht, int free_val)
  * Delete a variable from hashtab "ht" at item "hi".
  * Clear the variable value and free the dictitem.
  */
-    void
+    static void
 delete_var(hashtab_T *ht, hashitem_T *hi)
 {
     dictitem_T *di = HI2DI(hi);
@@ -2853,6 +3071,157 @@ var_exists(char_u *var)
     return n;
 }
 
+static lval_T  *redir_lval = NULL;
+#define EVALCMD_BUSY (redir_lval == (lval_T *)&redir_lval)
+static garray_T redir_ga;      // only valid when redir_lval is not NULL
+static char_u  *redir_endp = NULL;
+static char_u  *redir_varname = NULL;
+
+/*
+ * Start recording command output to a variable
+ * When "append" is TRUE append to an existing variable.
+ * Returns OK if successfully completed the setup.  FAIL otherwise.
+ */
+    int
+var_redir_start(char_u *name, int append)
+{
+    int                save_emsg;
+    int                err;
+    typval_T   tv;
+
+    // Catch a bad name early.
+    if (!eval_isnamec1(*name))
+    {
+       emsg(_(e_invarg));
+       return FAIL;
+    }
+
+    // Make a copy of the name, it is used in redir_lval until redir ends.
+    redir_varname = vim_strsave(name);
+    if (redir_varname == NULL)
+       return FAIL;
+
+    redir_lval = ALLOC_CLEAR_ONE(lval_T);
+    if (redir_lval == NULL)
+    {
+       var_redir_stop();
+       return FAIL;
+    }
+
+    // The output is stored in growarray "redir_ga" until redirection ends.
+    ga_init2(&redir_ga, (int)sizeof(char), 500);
+
+    // Parse the variable name (can be a dict or list entry).
+    redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
+                                                            FNE_CHECK_START);
+    if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
+    {
+       clear_lval(redir_lval);
+       if (redir_endp != NULL && *redir_endp != NUL)
+           // Trailing characters are present after the variable name
+           emsg(_(e_trailing));
+       else
+           emsg(_(e_invarg));
+       redir_endp = NULL;  // don't store a value, only cleanup
+       var_redir_stop();
+       return FAIL;
+    }
+
+    // check if we can write to the variable: set it to or append an empty
+    // string
+    save_emsg = did_emsg;
+    did_emsg = FALSE;
+    tv.v_type = VAR_STRING;
+    tv.vval.v_string = (char_u *)"";
+    if (append)
+       set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)".");
+    else
+       set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"=");
+    clear_lval(redir_lval);
+    err = did_emsg;
+    did_emsg |= save_emsg;
+    if (err)
+    {
+       redir_endp = NULL;  // don't store a value, only cleanup
+       var_redir_stop();
+       return FAIL;
+    }
+
+    return OK;
+}
+
+/*
+ * Append "value[value_len]" to the variable set by var_redir_start().
+ * The actual appending is postponed until redirection ends, because the value
+ * appended may in fact be the string we write to, changing it may cause freed
+ * memory to be used:
+ *   :redir => foo
+ *   :let foo
+ *   :redir END
+ */
+    void
+var_redir_str(char_u *value, int value_len)
+{
+    int                len;
+
+    if (redir_lval == NULL)
+       return;
+
+    if (value_len == -1)
+       len = (int)STRLEN(value);       // Append the entire string
+    else
+       len = value_len;                // Append only "value_len" characters
+
+    if (ga_grow(&redir_ga, len) == OK)
+    {
+       mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
+       redir_ga.ga_len += len;
+    }
+    else
+       var_redir_stop();
+}
+
+/*
+ * Stop redirecting command output to a variable.
+ * Frees the allocated memory.
+ */
+    void
+var_redir_stop(void)
+{
+    typval_T   tv;
+
+    if (EVALCMD_BUSY)
+    {
+       redir_lval = NULL;
+       return;
+    }
+
+    if (redir_lval != NULL)
+    {
+       // If there was no error: assign the text to the variable.
+       if (redir_endp != NULL)
+       {
+           ga_append(&redir_ga, NUL);  // Append the trailing NUL.
+           tv.v_type = VAR_STRING;
+           tv.vval.v_string = redir_ga.ga_data;
+           // Call get_lval() again, if it's inside a Dict or List it may
+           // have changed.
+           redir_endp = get_lval(redir_varname, NULL, redir_lval,
+                                       FALSE, FALSE, 0, FNE_CHECK_START);
+           if (redir_endp != NULL && redir_lval->ll_name != NULL)
+               set_var_lval(redir_lval, redir_endp, &tv, FALSE, FALSE,
+                                                               (char_u *)".");
+           clear_lval(redir_lval);
+       }
+
+       // free the collected output
+       VIM_CLEAR(redir_ga.ga_data);
+
+       VIM_CLEAR(redir_lval);
+    }
+    VIM_CLEAR(redir_varname);
+}
+
 /*
  * "gettabvar()" function
  */
index 5d1c8efb7f1a9d4dbaf8f68e6e30575e95fa48a9..857c9c74fa587f147b6d19cb5142c0066d3eda8a 100644 (file)
@@ -4317,3 +4317,111 @@ script_get(exarg_T *eap, char_u *cmd)
 
     return (char_u *)ga.ga_data;
 }
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * This function is used by f_input() and f_inputdialog() functions. The third
+ * argument to f_input() specifies the type of completion to use at the
+ * prompt. The third argument to f_inputdialog() specifies the value to return
+ * when the user cancels the prompt.
+ */
+    void
+get_user_input(
+    typval_T   *argvars,
+    typval_T   *rettv,
+    int                inputdialog,
+    int                secret)
+{
+    char_u     *prompt = tv_get_string_chk(&argvars[0]);
+    char_u     *p = NULL;
+    int                c;
+    char_u     buf[NUMBUFLEN];
+    int                cmd_silent_save = cmd_silent;
+    char_u     *defstr = (char_u *)"";
+    int                xp_type = EXPAND_NOTHING;
+    char_u     *xp_arg = NULL;
+
+    rettv->v_type = VAR_STRING;
+    rettv->vval.v_string = NULL;
+
+#ifdef NO_CONSOLE_INPUT
+    // While starting up, there is no place to enter text. When running tests
+    // with --not-a-term we assume feedkeys() will be used.
+    if (no_console_input() && !is_not_a_term())
+       return;
+#endif
+
+    cmd_silent = FALSE;                // Want to see the prompt.
+    if (prompt != NULL)
+    {
+       // Only the part of the message after the last NL is considered as
+       // prompt for the command line
+       p = vim_strrchr(prompt, '\n');
+       if (p == NULL)
+           p = prompt;
+       else
+       {
+           ++p;
+           c = *p;
+           *p = NUL;
+           msg_start();
+           msg_clr_eos();
+           msg_puts_attr((char *)prompt, get_echo_attr());
+           msg_didout = FALSE;
+           msg_starthere();
+           *p = c;
+       }
+       cmdline_row = msg_row;
+
+       if (argvars[1].v_type != VAR_UNKNOWN)
+       {
+           defstr = tv_get_string_buf_chk(&argvars[1], buf);
+           if (defstr != NULL)
+               stuffReadbuffSpec(defstr);
+
+           if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
+           {
+               char_u  *xp_name;
+               int     xp_namelen;
+               long    argt;
+
+               // input() with a third argument: completion
+               rettv->vval.v_string = NULL;
+
+               xp_name = tv_get_string_buf_chk(&argvars[2], buf);
+               if (xp_name == NULL)
+                   return;
+
+               xp_namelen = (int)STRLEN(xp_name);
+
+               if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
+                                                            &xp_arg) == FAIL)
+                   return;
+           }
+       }
+
+       if (defstr != NULL)
+       {
+           int save_ex_normal_busy = ex_normal_busy;
+
+           ex_normal_busy = 0;
+           rettv->vval.v_string =
+               getcmdline_prompt(secret ? NUL : '@', p, get_echo_attr(),
+                                                             xp_type, xp_arg);
+           ex_normal_busy = save_ex_normal_busy;
+       }
+       if (inputdialog && rettv->vval.v_string == NULL
+               && argvars[1].v_type != VAR_UNKNOWN
+               && argvars[2].v_type != VAR_UNKNOWN)
+           rettv->vval.v_string = vim_strsave(tv_get_string_buf(
+                                                          &argvars[2], buf));
+
+       vim_free(xp_arg);
+
+       // since the user typed this, no need to wait for return
+       need_wait_return = FALSE;
+       msg_didout = FALSE;
+    }
+    cmd_silent = cmd_silent_save;
+}
+#endif
index f94ab582adf3a9004862d2ff5c11d3e84191a2de..1cc7b9fae9749f5c8c6fe948727c485438891694 100644 (file)
@@ -191,9 +191,6 @@ EXTERN int  emsg_skip INIT(= 0);        // don't display errors for
 EXTERN int     emsg_severe INIT(= FALSE);  // use message of next of several
                                            // emsg() calls for throw
 EXTERN int     did_endif INIT(= FALSE);    // just had ":endif"
-EXTERN dict_T  vimvardict;                 // Dictionary with v: variables
-EXTERN dict_T  globvardict;                // Dictionary with g: variables
-#define globvarht globvardict.dv_hashtab
 #endif
 EXTERN int     did_emsg;                   // set by emsg() when the message
                                            // is displayed or thrown
index d836c7c91b882abe01ece312850e49fc54fe120f..aa44bf8e31493a6c862b6b1e9df2bac4aae509dc 100644 (file)
@@ -6847,8 +6847,8 @@ populate_module(PyObject *m)
        return -1;
     ADD_OBJECT(m, "error", VimError);
 
-    ADD_CHECKED_OBJECT(m, "vars",  NEW_DICTIONARY(&globvardict));
-    ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
+    ADD_CHECKED_OBJECT(m, "vars",  NEW_DICTIONARY(get_globvar_dict()));
+    ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(get_vimvar_dict()));
     ADD_CHECKED_OBJECT(m, "options",
            OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
 
index 1fd171c8b80c63649e1b59d465d907b9f2b52ddb..b91774b540aba8319b821b0768a290b3b33fd329 100644 (file)
@@ -3,13 +3,6 @@ varnumber_T num_divide(varnumber_T n1, varnumber_T n2);
 varnumber_T num_modulus(varnumber_T n1, varnumber_T n2);
 void eval_init(void);
 void eval_clear(void);
-int var_redir_start(char_u *name, int append);
-void var_redir_str(char_u *value, int value_len);
-void var_redir_stop(void);
-int eval_charconvert(char_u *enc_from, char_u *enc_to, char_u *fname_from, char_u *fname_to);
-int eval_printexpr(char_u *fname, char_u *args);
-void eval_diff(char_u *origfile, char_u *newfile, char_u *outfile);
-void eval_patch(char_u *origfile, char_u *difffile, char_u *outfile);
 int eval_to_bool(char_u *arg, int *error, char_u **nextcmd, int skip);
 int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv);
 int eval_expr_to_bool(typval_T *expr, int *error);
@@ -33,7 +26,6 @@ void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip);
 int next_for_item(void *fi_void, char_u *arg);
 void free_for_info(void *fi_void);
 void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
-void del_menutrans_vars(void);
 int pattern_match(char_u *pat, char_u *text, int ic);
 int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate);
 int eval1(char_u **arg, typval_T *rettv, int evaluate);
@@ -76,13 +68,11 @@ char_u *tv_get_string_chk(typval_T *varp);
 char_u *tv_get_string_buf_chk(typval_T *varp, char_u *buf);
 void copy_tv(typval_T *from, typval_T *to);
 int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
-void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog, int secret);
 void ex_echo(exarg_T *eap);
 void ex_echohl(exarg_T *eap);
+int get_echo_attr(void);
 void ex_execute(exarg_T *eap);
 char_u *find_option_end(char_u **arg, int *opt_flags);
-char_u *autoload_name(char_u *name);
-int script_autoload(char_u *name, int reload);
 void last_set_msg(sctx_T script_ctx);
 int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is, int ic);
 char_u *typval_tostring(typval_T *arg);
index fdb2e34dd95a8de89cfcaf08e0a176b89440b3d7..b0314178430804e00bab549713ce50bf06168546 100644 (file)
@@ -1,9 +1,14 @@
 /* evalvars.c */
 void evalvars_init(void);
 void evalvars_clear(void);
+int garbage_collect_globvars(int copyID);
 int garbage_collect_vimvars(int copyID);
 int garbage_collect_scriptvars(int copyID);
 void set_internal_string_var(char_u *name, char_u *value);
+int eval_charconvert(char_u *enc_from, char_u *enc_to, char_u *fname_from, char_u *fname_to);
+int eval_printexpr(char_u *fname, char_u *args);
+void eval_diff(char_u *origfile, char_u *newfile, char_u *outfile);
+void eval_patch(char_u *origfile, char_u *difffile, char_u *outfile);
 void prepare_vimvar(int idx, typval_T *save_tv);
 void restore_vimvar(int idx, typval_T *save_tv);
 void ex_let(exarg_T *eap);
@@ -14,7 +19,12 @@ void list_hashtable_vars(hashtab_T *ht, char *prefix, int empty, int *first);
 void ex_unlet(exarg_T *eap);
 void ex_lockvar(exarg_T *eap);
 int do_unlet(char_u *name, int forceit);
+void del_menutrans_vars(void);
 char_u *get_user_var_name(expand_T *xp, int idx);
+char *get_var_special_name(int nr);
+dict_T *get_globvar_dict(void);
+hashtab_T *get_globvar_ht(void);
+dict_T *get_vimvar_dict(void);
 void set_vim_var_type(int idx, vartype_T type);
 void set_vim_var_nr(int idx, varnumber_T val);
 typval_T *get_vim_var_tv(int idx);
@@ -44,7 +54,6 @@ void init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope);
 void unref_var_dict(dict_T *dict);
 void vars_clear(hashtab_T *ht);
 void vars_clear_ext(hashtab_T *ht, int free_val);
-void delete_var(hashtab_T *ht, hashitem_T *hi);
 void set_var(char_u *name, typval_T *tv, int copy);
 void set_var_const(char_u *name, typval_T *tv, int copy, int is_const);
 int var_check_ro(int flags, char_u *name, int use_gettext);
@@ -55,6 +64,9 @@ int valid_varname(char_u *varname);
 void reset_v_option_vars(void);
 void assert_error(garray_T *gap);
 int var_exists(char_u *var);
+int var_redir_start(char_u *name, int append);
+void var_redir_str(char_u *value, int value_len);
+void var_redir_stop(void);
 void f_gettabvar(typval_T *argvars, typval_T *rettv);
 void f_gettabwinvar(typval_T *argvars, typval_T *rettv);
 void f_getwinvar(typval_T *argvars, typval_T *rettv);
index 61215e02dd14f68e655c8c553a6ecccb0daaa377..12fd3bef41e41bb7651afa09c587aa100348a69b 100644 (file)
@@ -35,4 +35,5 @@ int get_cmdline_type(void);
 int get_cmdline_firstc(void);
 int get_list_range(char_u **str, int *num1, int *num2);
 char_u *script_get(exarg_T *eap, char_u *cmd);
+void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog, int secret);
 /* vim: set ft=c : */
index 98f82108c37613d518a3e04ff1bb70ae8f237470..c56b1c6c13a4000906605bf61ebb005c0569a5e1 100644 (file)
@@ -20,6 +20,7 @@ void ex_scriptnames(exarg_T *eap);
 void scriptnames_slash_adjust(void);
 char_u *get_scriptname(scid_T id);
 void free_scriptnames(void);
+void free_autoload_scriptnames(void);
 linenr_T get_sourced_lnum(char_u *(*fgetline)(int, void *, int, int), void *cookie);
 char_u *getsourceline(int c, void *cookie, int indent, int do_concat);
 void ex_scriptencoding(exarg_T *eap);
@@ -27,4 +28,6 @@ void ex_scriptversion(exarg_T *eap);
 void ex_finish(exarg_T *eap);
 void do_finish(exarg_T *eap, int reanimate);
 int source_finished(char_u *(*fgetline)(int, void *, int, int), void *cookie);
+char_u *autoload_name(char_u *name);
+int script_autoload(char_u *name, int reload);
 /* vim: set ft=c : */
index 15096e5cca50342ee13ad4408086702513f6396d..ca4abab1a0fd6637624e03e73e98fda75fea6eb8 100644 (file)
 
 #include "vim.h"
 
+#if defined(FEAT_EVAL) || defined(PROTO)
+// The names of packages that once were loaded are remembered.
+static garray_T                ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
+#endif
+
 /*
  * ":runtime [what] {name}"
  */
@@ -1334,6 +1339,12 @@ free_scriptnames(void)
        vim_free(SCRIPT_ITEM(i).sn_name);
     ga_clear(&script_items);
 }
+
+    void
+free_autoload_scriptnames(void)
+{
+    ga_clear_strings(&ga_loaded);
+}
 # endif
 
 #endif
@@ -1690,4 +1701,76 @@ source_finished(
            && ((struct source_cookie *)getline_cookie(
                                                fgetline, cookie))->finished);
 }
+
+/*
+ * Return the autoload script name for a function or variable name.
+ * Returns NULL when out of memory.
+ * Caller must make sure that "name" contains AUTOLOAD_CHAR.
+ */
+    char_u *
+autoload_name(char_u *name)
+{
+    char_u     *p, *q = NULL;
+    char_u     *scriptname;
+
+    // Get the script file name: replace '#' with '/', append ".vim".
+    scriptname = alloc(STRLEN(name) + 14);
+    if (scriptname == NULL)
+       return NULL;
+    STRCPY(scriptname, "autoload/");
+    STRCAT(scriptname, name);
+    for (p = scriptname + 9; (p = vim_strchr(p, AUTOLOAD_CHAR)) != NULL;
+                                                                   q = p, ++p)
+       *p = '/';
+    STRCPY(q, ".vim");
+    return scriptname;
+}
+
+/*
+ * If "name" has a package name try autoloading the script for it.
+ * Return TRUE if a package was loaded.
+ */
+    int
+script_autoload(
+    char_u     *name,
+    int                reload)     // load script again when already loaded
+{
+    char_u     *p;
+    char_u     *scriptname, *tofree;
+    int                ret = FALSE;
+    int                i;
+
+    // If there is no '#' after name[0] there is no package name.
+    p = vim_strchr(name, AUTOLOAD_CHAR);
+    if (p == NULL || p == name)
+       return FALSE;
+
+    tofree = scriptname = autoload_name(name);
+    if (scriptname == NULL)
+       return FALSE;
+
+    // Find the name in the list of previously loaded package names.  Skip
+    // "autoload/", it's always the same.
+    for (i = 0; i < ga_loaded.ga_len; ++i)
+       if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
+           break;
+    if (!reload && i < ga_loaded.ga_len)
+       ret = FALSE;        // was loaded already
+    else
+    {
+       // Remember the name if it wasn't loaded already.
+       if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
+       {
+           ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
+           tofree = NULL;
+       }
+
+       // Try loading the package from $VIMRUNTIME/autoload/<name>.vim
+       if (source_runtime(scriptname, 0) == OK)
+           ret = TRUE;
+    }
+
+    vim_free(tofree);
+    return ret;
+}
 #endif
index 473d94f883a82d542859918d6cc0eb354e63cd22..7139c52358d9e091f0a4896fb60b6e8d4d40fa35 100644 (file)
@@ -500,13 +500,14 @@ put_view(
     static int
 store_session_globals(FILE *fd)
 {
+    hashtab_T  *gvht = get_globvar_ht();
     hashitem_T *hi;
     dictitem_T *this_var;
     int                todo;
     char_u     *p, *t;
 
-    todo = (int)globvarht.ht_used;
-    for (hi = globvarht.ht_array; todo > 0; ++hi)
+    todo = (int)gvht->ht_used;
+    for (hi = gvht->ht_array; todo > 0; ++hi)
     {
        if (!HASHITEM_EMPTY(hi))
        {
index 5c29e3c77aa105620fb774208c0e06ce03ae0043..89922c2415c5eb8e8f57ebf7a2ae92bcbd53f7be 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1957,
 /**/
     1956,
 /**/
index 608c5cc7547dcb61e3c5659575a946e8ce4ed336..276e1b3bfc2dab52504f9619976b4c381acf728e 100644 (file)
@@ -1277,6 +1277,7 @@ read_viminfo_varlist(vir_T *virp, int writing)
     static void
 write_viminfo_varlist(FILE *fp)
 {
+    hashtab_T  *gvht = get_globvar_ht();
     hashitem_T *hi;
     dictitem_T *this_var;
     int                todo;
@@ -1290,8 +1291,8 @@ write_viminfo_varlist(FILE *fp)
 
     fputs(_("\n# global variables:\n"), fp);
 
-    todo = (int)globvarht.ht_used;
-    for (hi = globvarht.ht_array; todo > 0; ++hi)
+    todo = (int)gvht->ht_used;
+    for (hi = gvht->ht_array; todo > 0; ++hi)
     {
        if (!HASHITEM_EMPTY(hi))
        {