> There is. The very good probability of such bugs is one of the reasons why I 
> did not even consider adding similar global in extended funcref patch when I 
> encountered similar problems (and removed no_autoload from there once it got 
> my attention).

This patch replaces global with arguments in flags passed to some functions.

Changed behavior: lockvar and islocked() no longer trigger script autoloading 
(except for evaluating nested expressions like 
islocked('not#autoloaded#dict[autoloaded#function()]')). Do not think anybody 
actually relied on this.

# HG changeset patch
# User ZyX <kp-...@ya.ru>
# Date 1389066029 -14400
#      Tue Jan 07 07:40:29 2014 +0400
# Branch remove-no_autoload-global
# Node ID 7b182c0bfaf563de5b977e8773c409fef2457297
# Parent  bc19475ed196b91bf1ecda2224d88a47b5b497bb
Replace no_autoload global with arguments and flags

diff -r bc19475ed196 -r 7b182c0bfaf5 src/eval.c
--- a/src/eval.c        Mon Jan 06 15:51:55 2014 +0100
+++ b/src/eval.c        Tue Jan 07 07:40:29 2014 +0400
@@ -125,9 +125,6 @@
  */
 static hashtab_T       compat_hashtab;
 
-/* When using exists() don't auto-load a script. */
-static int             no_autoload = FALSE;
-
 /*
  * When recursively copying lists and dicts we need to remember which ones we
  * have done to avoid endless recursiveness.  This unique ID is used for that.
@@ -156,6 +153,14 @@
 /* Values for trans_function_name() argument: */
 #define TFN_INT                1       /* internal function name OK */
 #define TFN_QUIET      2       /* no error messages */
+#define TFN_NO_AUTOLOAD        4       /* do not use script autoloading */
+
+/* #define TFN_TO_GLVAL(flags) (flags&(TFN_QUIET|TFN_NO_AUTOLOAD)) */
+#define TFN_TO_GLV(flags)      (flags)
+
+/* Values for get_lval() flags argument: */
+#define GLV_QUIET      TFN_QUIET       /* no error messages */
+#define GLV_NO_AUTOLOAD        TFN_NO_AUTOLOAD /* do not use script 
autoloading */
 
 /*
  * Structure to hold info for a user function.
@@ -390,7 +395,7 @@
 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u 
*endchars, char_u *op));
 static int check_changedtick __ARGS((char_u *arg));
-static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int 
unlet, int skip, int quiet, int fne_flags));
+static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int 
unlet, int skip, int flags, int fne_flags));
 static void clear_lval __ARGS((lval_T *lp));
 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, 
int copy, char_u *op));
 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u  *op));
@@ -770,7 +775,7 @@
 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u 
*expr_start, char_u *expr_end, char_u *in_end));
 static int eval_isnamec __ARGS((int c));
 static int eval_isnamec1 __ARGS((int c));
-static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int 
verbose));
+static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int 
verbose, int no_autoload));
 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int 
evaluate, int verbose));
 static typval_T *alloc_tv __ARGS((void));
 static typval_T *alloc_string_tv __ARGS((char_u *string));
@@ -781,8 +786,8 @@
 static char_u *get_tv_string __ARGS((typval_T *varp));
 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
-static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp));
-static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u 
*varname, int writing));
+static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp, int 
no_autoload));
+static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u 
*varname, int no_autoload));
 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
@@ -1059,7 +1064,7 @@
     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, FALSE,
+    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)
     {
@@ -1150,7 +1155,7 @@
            /* 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, FALSE, FNE_CHECK_START);
+                                       FALSE, FALSE, 0, FNE_CHECK_START);
            if (redir_endp != NULL && redir_lval->ll_name != NULL)
                set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
            clear_lval(redir_lval);
@@ -2239,7 +2244,7 @@
            {
                if (tofree != NULL)
                    name = tofree;
-               if (get_var_tv(name, len, &tv, TRUE) == FAIL)
+               if (get_var_tv(name, len, &tv, TRUE, FALSE) == FAIL)
                    error = TRUE;
                else
                {
@@ -2474,7 +2479,7 @@
     {
        lval_T  lv;
 
-       p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START);
+       p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
        if (p != NULL && lv.ll_name != NULL)
        {
            if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
@@ -2519,18 +2524,22 @@
  * "unlet" is TRUE for ":unlet": slightly different behavior when something is
  * wrong; must end in space or cmd separator.
  *
+ * flags:
+ *  GLV_QUIET:       do not give error messages
+ *  GLV_NO_AUTOLOAD: do not use script autoloading
+ *
  * Returns a pointer to just after the name, including indexes.
  * When an evaluation error occurs "lp->ll_name" is NULL;
  * Returns NULL for a parsing error.  Still need to free items in "lp"!
  */
     static char_u *
-get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
+get_lval(name, rettv, lp, unlet, skip, flags, fne_flags)
     char_u     *name;
     typval_T   *rettv;
     lval_T     *lp;
     int                unlet;
     int                skip;
-    int                quiet;      /* don't give error messages */
+    int                flags;      /* don't give error messages */
     int                fne_flags;  /* flags for find_name_end() */
 {
     char_u     *p;
@@ -2573,7 +2582,7 @@
            /* Report an invalid expression in braces, unless the
             * expression evaluation has been cancelled due to an
             * aborting error, an interrupt, or an exception. */
-           if (!aborting() && !quiet)
+           if (!aborting() && !(flags & GLV_QUIET))
            {
                emsg_severe = TRUE;
                EMSG2(_(e_invarg2), name);
@@ -2591,8 +2600,8 @@
 
     cc = *p;
     *p = NUL;
-    v = find_var(lp->ll_name, &ht);
-    if (v == NULL && !quiet)
+    v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
+    if (v == NULL && !(flags & GLV_QUIET))
        EMSG2(_(e_undefvar), lp->ll_name);
     *p = cc;
     if (v == NULL)
@@ -2608,13 +2617,13 @@
                && !(lp->ll_tv->v_type == VAR_DICT
                                           && lp->ll_tv->vval.v_dict != NULL))
        {
-           if (!quiet)
+           if (!(flags & GLV_QUIET))
                EMSG(_("E689: Can only index a List or Dictionary"));
            return NULL;
        }
        if (lp->ll_range)
        {
-           if (!quiet)
+           if (!(flags & GLV_QUIET))
                EMSG(_("E708: [:] must come last"));
            return NULL;
        }
@@ -2627,7 +2636,7 @@
                ;
            if (len == 0)
            {
-               if (!quiet)
+               if (!(flags & GLV_QUIET))
                    EMSG(_(e_emptykey));
                return NULL;
            }
@@ -2657,7 +2666,7 @@
            {
                if (lp->ll_tv->v_type == VAR_DICT)
                {
-                   if (!quiet)
+                   if (!(flags & GLV_QUIET))
                        EMSG(_(e_dictrange));
                    if (!empty1)
                        clear_tv(&var1);
@@ -2666,7 +2675,7 @@
                if (rettv != NULL && (rettv->v_type != VAR_LIST
                                               || rettv->vval.v_list == NULL))
                {
-                   if (!quiet)
+                   if (!(flags & GLV_QUIET))
                        EMSG(_("E709: [:] requires a List value"));
                    if (!empty1)
                        clear_tv(&var1);
@@ -2700,7 +2709,7 @@
 
            if (*p != ']')
            {
-               if (!quiet)
+               if (!(flags & GLV_QUIET))
                    EMSG(_(e_missbrac));
                if (!empty1)
                    clear_tv(&var1);
@@ -2721,7 +2730,7 @@
                key = get_tv_string(&var1);     /* is number or string */
                if (*key == NUL)
                {
-                   if (!quiet)
+                   if (!(flags & GLV_QUIET))
                        EMSG(_(e_emptykey));
                    clear_tv(&var1);
                    return NULL;
@@ -2768,7 +2777,7 @@
                /* Key does not exist in dict: may need to add it. */
                if (*p == '[' || *p == '.' || unlet)
                {
-                   if (!quiet)
+                   if (!(flags & GLV_QUIET))
                        EMSG2(_(e_dictkey), key);
                    if (len == -1)
                        clear_tv(&var1);
@@ -2819,7 +2828,7 @@
            {
                if (lp->ll_range && !lp->ll_empty2)
                    clear_tv(&var2);
-               if (!quiet)
+               if (!(flags & GLV_QUIET))
                    EMSGN(_(e_listidx), lp->ll_n1);
                return NULL;
            }
@@ -2839,7 +2848,7 @@
                    ni = list_find(lp->ll_list, lp->ll_n2);
                    if (ni == NULL)
                    {
-                       if (!quiet)
+                       if (!(flags & GLV_QUIET))
                            EMSGN(_(e_listidx), lp->ll_n2);
                        return NULL;
                    }
@@ -2851,7 +2860,7 @@
                    lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
                if (lp->ll_n2 < lp->ll_n1)
                {
-                   if (!quiet)
+                   if (!(flags & GLV_QUIET))
                        EMSGN(_(e_listidx), lp->ll_n2);
                    return NULL;
                }
@@ -2904,7 +2913,7 @@
 
                /* handle +=, -= and .= */
                if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
-                                                            &tv, TRUE) == OK)
+                                                       &tv, TRUE, FALSE) == OK)
                {
                    if (tv_op(&tv, rettv, op) == OK)
                        set_var(lp->ll_name, &tv, FALSE);
@@ -3556,7 +3565,7 @@
     do
     {
        /* Parse the name and find the end. */
-       name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE,
+       name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
                                                             FNE_CHECK_START);
        if (lv.ll_name == NULL)
            error = TRUE;           /* error but continue parsing */
@@ -3709,7 +3718,7 @@
            ret = FAIL;
        else
        {
-           di = find_var(lp->ll_name, NULL);
+           di = find_var(lp->ll_name, NULL, TRUE);
            if (di == NULL)
                ret = FAIL;
            else
@@ -5179,7 +5188,7 @@
                }
            }
            else if (evaluate)
-               ret = get_var_tv(s, len, rettv, TRUE);
+               ret = get_var_tv(s, len, rettv, TRUE, FALSE);
            else
                ret = OK;
        }
@@ -8284,7 +8293,7 @@
 
     cc = name[*lenp];
     name[*lenp] = NUL;
-    v = find_var(name, NULL);
+    v = find_var(name, NULL, FALSE);
     name[*lenp] = cc;
     if (v != NULL && v->di_tv.v_type == VAR_FUNC)
     {
@@ -10039,8 +10048,6 @@
     int                n = FALSE;
     int                len = 0;
 
-    no_autoload = TRUE;
-
     p = get_tv_string(&argvars[0]);
     if (*p == '$')                     /* environment variable */
     {
@@ -10091,7 +10098,7 @@
        {
            if (tofree != NULL)
                name = tofree;
-           n = (get_var_tv(name, len, &tv, FALSE) == OK);
+           n = (get_var_tv(name, len, &tv, FALSE, TRUE) == OK);
            if (n)
            {
                /* handle d.key, l[idx], f(expr) */
@@ -10107,8 +10114,6 @@
     }
 
     rettv->vval.v_number = n;
-
-    no_autoload = FALSE;
 }
 
 #ifdef FEAT_FLOAT
@@ -13344,8 +13349,8 @@
     dictitem_T *di;
 
     rettv->vval.v_number = -1;
-    end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE,
-                                                            FNE_CHECK_START);
+    end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
+                                       GLV_NO_AUTOLOAD, FNE_CHECK_START);
     if (end != NULL && lv.ll_name != NULL)
     {
        if (*end != NUL)
@@ -13358,7 +13363,7 @@
                    rettv->vval.v_number = 1;       /* always locked */
                else
                {
-                   di = find_var(lv.ll_name, NULL);
+                   di = find_var(lv.ll_name, NULL, TRUE);
                    if (di != NULL)
                    {
                        /* Consider a variable locked when:
@@ -19774,11 +19779,12 @@
  * Return OK or FAIL.
  */
     static int
-get_var_tv(name, len, rettv, verbose)
+get_var_tv(name, len, rettv, verbose, no_autoload)
     char_u     *name;
     int                len;            /* length of "name" */
     typval_T   *rettv;         /* NULL when only checking existence */
     int                verbose;        /* may give error message */
+    int                no_autoload;    /* do not use script autoloading */
 {
     int                ret = OK;
     typval_T   *tv = NULL;
@@ -19805,7 +19811,7 @@
      */
     else
     {
-       v = find_var(name, NULL);
+       v = find_var(name, NULL, no_autoload);
        if (v != NULL)
            tv = &v->di_tv;
     }
@@ -20207,9 +20213,10 @@
  * hashtab_T used.
  */
     static dictitem_T *
-find_var(name, htp)
+find_var(name, htp, no_autoload)
     char_u     *name;
     hashtab_T  **htp;
+    int                no_autoload;
 {
     char_u     *varname;
     hashtab_T  *ht;
@@ -20219,7 +20226,7 @@
        *htp = ht;
     if (ht == NULL)
        return NULL;
-    return find_var_in_ht(ht, *name, varname, htp != NULL);
+    return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
 }
 
 /*
@@ -20227,11 +20234,11 @@
  * Returns NULL if not found.
  */
     static dictitem_T *
-find_var_in_ht(ht, htname, varname, writing)
+find_var_in_ht(ht, htname, varname, no_autoload)
     hashtab_T  *ht;
     int                htname;
     char_u     *varname;
-    int                writing;
+    int                no_autoload;
 {
     hashitem_T *hi;
 
@@ -20263,7 +20270,7 @@
         * worked find the variable again.  Don't auto-load a script if it was
         * loaded already, otherwise it would be loaded every time when
         * checking if a function name is a Funcref variable. */
-       if (ht == &globvarht && !writing)
+       if (ht == &globvarht && !no_autoload)
        {
            /* Note: script_autoload() may make "hi" invalid. It must either
             * be obtained again or not used. */
@@ -20343,7 +20350,7 @@
 {
     dictitem_T *v;
 
-    v = find_var(name, NULL);
+    v = find_var(name, NULL, FALSE);
     if (v == NULL)
        return NULL;
     return get_tv_string(&v->di_tv);
@@ -21672,7 +21679,7 @@
      */
     if (fudi.fd_dict == NULL)
     {
-       v = find_var(name, &ht);
+       v = find_var(name, &ht, FALSE);
        if (v != NULL && v->di_tv.v_type == VAR_FUNC)
        {
            emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
@@ -21830,8 +21837,9 @@
  * Also handles a Funcref in a List or Dictionary.
  * Returns the function name in allocated memory, or NULL for failure.
  * flags:
- * TFN_INT:   internal function name OK
- * TFN_QUIET: be quiet
+ * TFN_INT:         internal function name OK
+ * TFN_QUIET:       be quiet
+ * TFN_NO_AUTOLOAD: do not use script autoloading
  * Advances "pp" to just after the function name (if no error).
  */
     static char_u *
@@ -21869,7 +21877,7 @@
     if (lead > 2)
        start += lead;
 
-    end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET,
+    end = get_lval(start, NULL, &lv, FALSE, skip, TFN_TO_GLV(flags),
                                              lead > 2 ? 0 : FNE_CHECK_START);
     if (end == start)
     {
@@ -22146,7 +22154,8 @@
     char_u  *p;
     int            n = FALSE;
 
-    p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
+    p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
+                           NULL);
     nm = skipwhite(nm);
 
     /* Only accept "funcname", "funcname ", "funcname (..." and
@@ -22393,10 +22402,6 @@
     int                ret = FALSE;
     int                i;
 
-    /* Return quickly when autoload disabled. */
-    if (no_autoload)
-       return FALSE;
-
     /* If there is no '#' after name[0] there is no package name. */
     p = vim_strchr(name, AUTOLOAD_CHAR);
     if (p == NULL || p == name)
diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test55.in
--- a/src/testdir/test55.in     Mon Jan 06 15:51:55 2014 +0100
+++ b/src/testdir/test55.in     Tue Jan 07 07:40:29 2014 +0400
@@ -282,6 +282,13 @@
 :    $put =ps
 :  endfor
 :endfor
+:" :lockvar/islocked() triggering script autoloading
+:set rtp+=./sautest
+:lockvar g:foo#x
+:unlockvar g:foo#x
+:$put ='locked g:foo#x:'.islocked('g:foo#x')
+:$put ='exists g:foo#x:'.exists('g:foo#x')
+:$put ='g:foo#x: '.g:foo#x
 :"
 :" a:000 function argument
 :" first the tests that should fail
diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test55.ok
--- a/src/testdir/test55.ok     Mon Jan 06 15:51:55 2014 +0100
+++ b/src/testdir/test55.ok     Tue Jan 07 07:40:29 2014 +0400
@@ -86,6 +86,9 @@
 FFpFFpp
 0000-000
 ppppppp
+locked g:foo#x:-1
+exists g:foo#x:0
+g:foo#x: 1
 caught a:000
 caught a:000[0]
 caught a:000[2]
diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test60.in
--- a/src/testdir/test60.in     Mon Jan 06 15:51:55 2014 +0100
+++ b/src/testdir/test60.in     Tue Jan 07 07:40:29 2014 +0400
@@ -1,4 +1,4 @@
-Tests for the exists() function.  vim: set ft=vim :
+Tests for the exists() function.  vim: set ft=vim ts=8 :
 
 STARTTEST
 :so small.vim
@@ -11,8 +11,10 @@
 endfunction
 :function! TestExists()
     augroup myagroup
-       autocmd! BufEnter *.my echo 'myfile edited'
+       autocmd! BufEnter       *.my     echo "myfile edited"
+       autocmd! FuncUndefined  UndefFun exec "fu UndefFun()\nendfu"
     augroup END
+    set rtp+=./sautest
 
     let test_cases = []
 
@@ -95,10 +97,15 @@
     " Non-existing user defined function
     let test_cases += [['*MyxyzFunc', 0]]
 
+    " Function that may be created by FuncUndefined event
+    let test_cases += [['*UndefFun', 0]]
+    " Function that may be created by script autoloading
+    let test_cases += [['*foo#F', 0]]
+
     redir! > test.out
 
     for [test_case, result] in test_cases
-       echo test_case . ": " . result
+        echo test_case . ": " . result
         call RunTest(test_case, result)
     endfor
 
@@ -207,6 +214,14 @@
        echo "FAILED"
     endif
 
+    " Non-existing autoload variable that may be autoloaded
+    echo 'foo#x: 0'
+    if !exists('foo#x')
+       echo "OK"
+    else
+       echo "FAILED"
+    endif
+
     " Valid local list
     let local_list = ["blue", "orange"]
     echo 'local_list: 1'
@@ -566,6 +581,10 @@
 
     call TestFuncArg("arg1", "arg2")
 
+    echo ' g:foo#x =' g:foo#x
+    echo '   foo#F()' foo#F()
+    echo 'UndefFun()' UndefFun()
+
     redir END
 endfunction
 :call TestExists()
@@ -576,5 +595,6 @@
 :set ff=unix
 :w
 :qa!
+:while getchar(1) | call getchar() | endwhile
 ENDTEST
 
diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test60.ok
--- a/src/testdir/test60.ok     Mon Jan 06 15:51:55 2014 +0100
+++ b/src/testdir/test60.ok     Tue Jan 07 07:40:29 2014 +0400
@@ -71,6 +71,10 @@
 OK
 *MyxyzFunc: 0
 OK
+*UndefFun: 0
+OK
+*foo#F: 0
+OK
 :edit: 2
 OK
 :edit/a: 0
@@ -95,6 +99,8 @@
 OK
 local_var: 0
 OK
+foo#x: 0
+OK
 local_list: 1
 OK
 local_list[1]: 1
@@ -195,3 +201,6 @@
 OK
 a:2: 0
 OK
+ g:foo#x = 1
+   foo#F() 0
+UndefFun() 0

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
diff -crN vim-small-patches.bc19475ed196/src/eval.c vim-small-patches.7b182c0bfaf5/src/eval.c
*** vim-small-patches.bc19475ed196/src/eval.c	2014-01-07 07:44:20.407838396 +0400
--- vim-small-patches.7b182c0bfaf5/src/eval.c	2014-01-07 07:44:20.427838398 +0400
***************
*** 125,133 ****
   */
  static hashtab_T	compat_hashtab;
  
- /* When using exists() don't auto-load a script. */
- static int		no_autoload = FALSE;
- 
  /*
   * When recursively copying lists and dicts we need to remember which ones we
   * have done to avoid endless recursiveness.  This unique ID is used for that.
--- 125,130 ----
***************
*** 156,161 ****
--- 153,166 ----
  /* Values for trans_function_name() argument: */
  #define TFN_INT		1	/* internal function name OK */
  #define TFN_QUIET	2	/* no error messages */
+ #define TFN_NO_AUTOLOAD	4	/* do not use script autoloading */
+ 
+ /* #define TFN_TO_GLVAL(flags)	(flags&(TFN_QUIET|TFN_NO_AUTOLOAD)) */
+ #define TFN_TO_GLV(flags)	(flags)
+ 
+ /* Values for get_lval() flags argument: */
+ #define GLV_QUIET	TFN_QUIET	/* no error messages */
+ #define GLV_NO_AUTOLOAD	TFN_NO_AUTOLOAD	/* do not use script autoloading */
  
  /*
   * Structure to hold info for a user function.
***************
*** 390,396 ****
  static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
  static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
  static int check_changedtick __ARGS((char_u *arg));
! static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
  static void clear_lval __ARGS((lval_T *lp));
  static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op));
  static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u  *op));
--- 395,401 ----
  static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
  static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
  static int check_changedtick __ARGS((char_u *arg));
! static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags));
  static void clear_lval __ARGS((lval_T *lp));
  static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op));
  static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u  *op));
***************
*** 770,776 ****
  static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end));
  static int eval_isnamec __ARGS((int c));
  static int eval_isnamec1 __ARGS((int c));
! static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose));
  static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose));
  static typval_T *alloc_tv __ARGS((void));
  static typval_T *alloc_string_tv __ARGS((char_u *string));
--- 775,781 ----
  static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end));
  static int eval_isnamec __ARGS((int c));
  static int eval_isnamec1 __ARGS((int c));
! static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose, int no_autoload));
  static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose));
  static typval_T *alloc_tv __ARGS((void));
  static typval_T *alloc_string_tv __ARGS((char_u *string));
***************
*** 781,788 ****
  static char_u *get_tv_string __ARGS((typval_T *varp));
  static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
  static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
! static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp));
! static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int writing));
  static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
  static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
  static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
--- 786,793 ----
  static char_u *get_tv_string __ARGS((typval_T *varp));
  static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
  static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
! static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp, int no_autoload));
! static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int no_autoload));
  static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
  static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
  static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
***************
*** 1059,1065 ****
      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, FALSE,
  							     FNE_CHECK_START);
      if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
      {
--- 1064,1070 ----
      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)
      {
***************
*** 1150,1156 ****
  	    /* 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, FALSE, FNE_CHECK_START);
  	    if (redir_endp != NULL && redir_lval->ll_name != NULL)
  		set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
  	    clear_lval(redir_lval);
--- 1155,1161 ----
  	    /* 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, (char_u *)".");
  	    clear_lval(redir_lval);
***************
*** 2239,2245 ****
  	    {
  		if (tofree != NULL)
  		    name = tofree;
! 		if (get_var_tv(name, len, &tv, TRUE) == FAIL)
  		    error = TRUE;
  		else
  		{
--- 2244,2250 ----
  	    {
  		if (tofree != NULL)
  		    name = tofree;
! 		if (get_var_tv(name, len, &tv, TRUE, FALSE) == FAIL)
  		    error = TRUE;
  		else
  		{
***************
*** 2474,2480 ****
      {
  	lval_T	lv;
  
! 	p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START);
  	if (p != NULL && lv.ll_name != NULL)
  	{
  	    if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
--- 2479,2485 ----
      {
  	lval_T	lv;
  
! 	p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
  	if (p != NULL && lv.ll_name != NULL)
  	{
  	    if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
***************
*** 2519,2536 ****
   * "unlet" is TRUE for ":unlet": slightly different behavior when something is
   * wrong; must end in space or cmd separator.
   *
   * Returns a pointer to just after the name, including indexes.
   * When an evaluation error occurs "lp->ll_name" is NULL;
   * Returns NULL for a parsing error.  Still need to free items in "lp"!
   */
      static char_u *
! get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
      char_u	*name;
      typval_T	*rettv;
      lval_T	*lp;
      int		unlet;
      int		skip;
!     int		quiet;	    /* don't give error messages */
      int		fne_flags;  /* flags for find_name_end() */
  {
      char_u	*p;
--- 2524,2545 ----
   * "unlet" is TRUE for ":unlet": slightly different behavior when something is
   * wrong; must end in space or cmd separator.
   *
+  * flags:
+  *  GLV_QUIET:       do not give error messages
+  *  GLV_NO_AUTOLOAD: do not use script autoloading
+  *
   * Returns a pointer to just after the name, including indexes.
   * When an evaluation error occurs "lp->ll_name" is NULL;
   * Returns NULL for a parsing error.  Still need to free items in "lp"!
   */
      static char_u *
! get_lval(name, rettv, lp, unlet, skip, flags, fne_flags)
      char_u	*name;
      typval_T	*rettv;
      lval_T	*lp;
      int		unlet;
      int		skip;
!     int		flags;	    /* don't give error messages */
      int		fne_flags;  /* flags for find_name_end() */
  {
      char_u	*p;
***************
*** 2573,2579 ****
  	    /* Report an invalid expression in braces, unless the
  	     * expression evaluation has been cancelled due to an
  	     * aborting error, an interrupt, or an exception. */
! 	    if (!aborting() && !quiet)
  	    {
  		emsg_severe = TRUE;
  		EMSG2(_(e_invarg2), name);
--- 2582,2588 ----
  	    /* Report an invalid expression in braces, unless the
  	     * expression evaluation has been cancelled due to an
  	     * aborting error, an interrupt, or an exception. */
! 	    if (!aborting() && !(flags & GLV_QUIET))
  	    {
  		emsg_severe = TRUE;
  		EMSG2(_(e_invarg2), name);
***************
*** 2591,2598 ****
  
      cc = *p;
      *p = NUL;
!     v = find_var(lp->ll_name, &ht);
!     if (v == NULL && !quiet)
  	EMSG2(_(e_undefvar), lp->ll_name);
      *p = cc;
      if (v == NULL)
--- 2600,2607 ----
  
      cc = *p;
      *p = NUL;
!     v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
!     if (v == NULL && !(flags & GLV_QUIET))
  	EMSG2(_(e_undefvar), lp->ll_name);
      *p = cc;
      if (v == NULL)
***************
*** 2608,2620 ****
  		&& !(lp->ll_tv->v_type == VAR_DICT
  					   && lp->ll_tv->vval.v_dict != NULL))
  	{
! 	    if (!quiet)
  		EMSG(_("E689: Can only index a List or Dictionary"));
  	    return NULL;
  	}
  	if (lp->ll_range)
  	{
! 	    if (!quiet)
  		EMSG(_("E708: [:] must come last"));
  	    return NULL;
  	}
--- 2617,2629 ----
  		&& !(lp->ll_tv->v_type == VAR_DICT
  					   && lp->ll_tv->vval.v_dict != NULL))
  	{
! 	    if (!(flags & GLV_QUIET))
  		EMSG(_("E689: Can only index a List or Dictionary"));
  	    return NULL;
  	}
  	if (lp->ll_range)
  	{
! 	    if (!(flags & GLV_QUIET))
  		EMSG(_("E708: [:] must come last"));
  	    return NULL;
  	}
***************
*** 2627,2633 ****
  		;
  	    if (len == 0)
  	    {
! 		if (!quiet)
  		    EMSG(_(e_emptykey));
  		return NULL;
  	    }
--- 2636,2642 ----
  		;
  	    if (len == 0)
  	    {
! 		if (!(flags & GLV_QUIET))
  		    EMSG(_(e_emptykey));
  		return NULL;
  	    }
***************
*** 2657,2663 ****
  	    {
  		if (lp->ll_tv->v_type == VAR_DICT)
  		{
! 		    if (!quiet)
  			EMSG(_(e_dictrange));
  		    if (!empty1)
  			clear_tv(&var1);
--- 2666,2672 ----
  	    {
  		if (lp->ll_tv->v_type == VAR_DICT)
  		{
! 		    if (!(flags & GLV_QUIET))
  			EMSG(_(e_dictrange));
  		    if (!empty1)
  			clear_tv(&var1);
***************
*** 2666,2672 ****
  		if (rettv != NULL && (rettv->v_type != VAR_LIST
  					       || rettv->vval.v_list == NULL))
  		{
! 		    if (!quiet)
  			EMSG(_("E709: [:] requires a List value"));
  		    if (!empty1)
  			clear_tv(&var1);
--- 2675,2681 ----
  		if (rettv != NULL && (rettv->v_type != VAR_LIST
  					       || rettv->vval.v_list == NULL))
  		{
! 		    if (!(flags & GLV_QUIET))
  			EMSG(_("E709: [:] requires a List value"));
  		    if (!empty1)
  			clear_tv(&var1);
***************
*** 2700,2706 ****
  
  	    if (*p != ']')
  	    {
! 		if (!quiet)
  		    EMSG(_(e_missbrac));
  		if (!empty1)
  		    clear_tv(&var1);
--- 2709,2715 ----
  
  	    if (*p != ']')
  	    {
! 		if (!(flags & GLV_QUIET))
  		    EMSG(_(e_missbrac));
  		if (!empty1)
  		    clear_tv(&var1);
***************
*** 2721,2727 ****
  		key = get_tv_string(&var1);	/* is number or string */
  		if (*key == NUL)
  		{
! 		    if (!quiet)
  			EMSG(_(e_emptykey));
  		    clear_tv(&var1);
  		    return NULL;
--- 2730,2736 ----
  		key = get_tv_string(&var1);	/* is number or string */
  		if (*key == NUL)
  		{
! 		    if (!(flags & GLV_QUIET))
  			EMSG(_(e_emptykey));
  		    clear_tv(&var1);
  		    return NULL;
***************
*** 2768,2774 ****
  		/* Key does not exist in dict: may need to add it. */
  		if (*p == '[' || *p == '.' || unlet)
  		{
! 		    if (!quiet)
  			EMSG2(_(e_dictkey), key);
  		    if (len == -1)
  			clear_tv(&var1);
--- 2777,2783 ----
  		/* Key does not exist in dict: may need to add it. */
  		if (*p == '[' || *p == '.' || unlet)
  		{
! 		    if (!(flags & GLV_QUIET))
  			EMSG2(_(e_dictkey), key);
  		    if (len == -1)
  			clear_tv(&var1);
***************
*** 2819,2825 ****
  	    {
  		if (lp->ll_range && !lp->ll_empty2)
  		    clear_tv(&var2);
! 		if (!quiet)
  		    EMSGN(_(e_listidx), lp->ll_n1);
  		return NULL;
  	    }
--- 2828,2834 ----
  	    {
  		if (lp->ll_range && !lp->ll_empty2)
  		    clear_tv(&var2);
! 		if (!(flags & GLV_QUIET))
  		    EMSGN(_(e_listidx), lp->ll_n1);
  		return NULL;
  	    }
***************
*** 2839,2845 ****
  		    ni = list_find(lp->ll_list, lp->ll_n2);
  		    if (ni == NULL)
  		    {
! 			if (!quiet)
  			    EMSGN(_(e_listidx), lp->ll_n2);
  			return NULL;
  		    }
--- 2848,2854 ----
  		    ni = list_find(lp->ll_list, lp->ll_n2);
  		    if (ni == NULL)
  		    {
! 			if (!(flags & GLV_QUIET))
  			    EMSGN(_(e_listidx), lp->ll_n2);
  			return NULL;
  		    }
***************
*** 2851,2857 ****
  		    lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
  		if (lp->ll_n2 < lp->ll_n1)
  		{
! 		    if (!quiet)
  			EMSGN(_(e_listidx), lp->ll_n2);
  		    return NULL;
  		}
--- 2860,2866 ----
  		    lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
  		if (lp->ll_n2 < lp->ll_n1)
  		{
! 		    if (!(flags & GLV_QUIET))
  			EMSGN(_(e_listidx), lp->ll_n2);
  		    return NULL;
  		}
***************
*** 2904,2910 ****
  
  		/* handle +=, -= and .= */
  		if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
! 							     &tv, TRUE) == OK)
  		{
  		    if (tv_op(&tv, rettv, op) == OK)
  			set_var(lp->ll_name, &tv, FALSE);
--- 2913,2919 ----
  
  		/* handle +=, -= and .= */
  		if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
! 							&tv, TRUE, FALSE) == OK)
  		{
  		    if (tv_op(&tv, rettv, op) == OK)
  			set_var(lp->ll_name, &tv, FALSE);
***************
*** 3556,3562 ****
      do
      {
  	/* Parse the name and find the end. */
! 	name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE,
  							     FNE_CHECK_START);
  	if (lv.ll_name == NULL)
  	    error = TRUE;	    /* error but continue parsing */
--- 3565,3571 ----
      do
      {
  	/* Parse the name and find the end. */
! 	name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
  							     FNE_CHECK_START);
  	if (lv.ll_name == NULL)
  	    error = TRUE;	    /* error but continue parsing */
***************
*** 3709,3715 ****
  	    ret = FAIL;
  	else
  	{
! 	    di = find_var(lp->ll_name, NULL);
  	    if (di == NULL)
  		ret = FAIL;
  	    else
--- 3718,3724 ----
  	    ret = FAIL;
  	else
  	{
! 	    di = find_var(lp->ll_name, NULL, TRUE);
  	    if (di == NULL)
  		ret = FAIL;
  	    else
***************
*** 5179,5185 ****
  		}
  	    }
  	    else if (evaluate)
! 		ret = get_var_tv(s, len, rettv, TRUE);
  	    else
  		ret = OK;
  	}
--- 5188,5194 ----
  		}
  	    }
  	    else if (evaluate)
! 		ret = get_var_tv(s, len, rettv, TRUE, FALSE);
  	    else
  		ret = OK;
  	}
***************
*** 8284,8290 ****
  
      cc = name[*lenp];
      name[*lenp] = NUL;
!     v = find_var(name, NULL);
      name[*lenp] = cc;
      if (v != NULL && v->di_tv.v_type == VAR_FUNC)
      {
--- 8293,8299 ----
  
      cc = name[*lenp];
      name[*lenp] = NUL;
!     v = find_var(name, NULL, FALSE);
      name[*lenp] = cc;
      if (v != NULL && v->di_tv.v_type == VAR_FUNC)
      {
***************
*** 10039,10046 ****
      int		n = FALSE;
      int		len = 0;
  
-     no_autoload = TRUE;
- 
      p = get_tv_string(&argvars[0]);
      if (*p == '$')			/* environment variable */
      {
--- 10048,10053 ----
***************
*** 10091,10097 ****
  	{
  	    if (tofree != NULL)
  		name = tofree;
! 	    n = (get_var_tv(name, len, &tv, FALSE) == OK);
  	    if (n)
  	    {
  		/* handle d.key, l[idx], f(expr) */
--- 10098,10104 ----
  	{
  	    if (tofree != NULL)
  		name = tofree;
! 	    n = (get_var_tv(name, len, &tv, FALSE, TRUE) == OK);
  	    if (n)
  	    {
  		/* handle d.key, l[idx], f(expr) */
***************
*** 10107,10114 ****
      }
  
      rettv->vval.v_number = n;
- 
-     no_autoload = FALSE;
  }
  
  #ifdef FEAT_FLOAT
--- 10114,10119 ----
***************
*** 13344,13351 ****
      dictitem_T	*di;
  
      rettv->vval.v_number = -1;
!     end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE,
! 							     FNE_CHECK_START);
      if (end != NULL && lv.ll_name != NULL)
      {
  	if (*end != NUL)
--- 13349,13356 ----
      dictitem_T	*di;
  
      rettv->vval.v_number = -1;
!     end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
! 					GLV_NO_AUTOLOAD, FNE_CHECK_START);
      if (end != NULL && lv.ll_name != NULL)
      {
  	if (*end != NUL)
***************
*** 13358,13364 ****
  		    rettv->vval.v_number = 1;	    /* always locked */
  		else
  		{
! 		    di = find_var(lv.ll_name, NULL);
  		    if (di != NULL)
  		    {
  			/* Consider a variable locked when:
--- 13363,13369 ----
  		    rettv->vval.v_number = 1;	    /* always locked */
  		else
  		{
! 		    di = find_var(lv.ll_name, NULL, TRUE);
  		    if (di != NULL)
  		    {
  			/* Consider a variable locked when:
***************
*** 19774,19784 ****
   * Return OK or FAIL.
   */
      static int
! get_var_tv(name, len, rettv, verbose)
      char_u	*name;
      int		len;		/* length of "name" */
      typval_T	*rettv;		/* NULL when only checking existence */
      int		verbose;	/* may give error message */
  {
      int		ret = OK;
      typval_T	*tv = NULL;
--- 19779,19790 ----
   * Return OK or FAIL.
   */
      static int
! get_var_tv(name, len, rettv, verbose, no_autoload)
      char_u	*name;
      int		len;		/* length of "name" */
      typval_T	*rettv;		/* NULL when only checking existence */
      int		verbose;	/* may give error message */
+     int		no_autoload;	/* do not use script autoloading */
  {
      int		ret = OK;
      typval_T	*tv = NULL;
***************
*** 19805,19811 ****
       */
      else
      {
! 	v = find_var(name, NULL);
  	if (v != NULL)
  	    tv = &v->di_tv;
      }
--- 19811,19817 ----
       */
      else
      {
! 	v = find_var(name, NULL, no_autoload);
  	if (v != NULL)
  	    tv = &v->di_tv;
      }
***************
*** 20207,20215 ****
   * hashtab_T used.
   */
      static dictitem_T *
! find_var(name, htp)
      char_u	*name;
      hashtab_T	**htp;
  {
      char_u	*varname;
      hashtab_T	*ht;
--- 20213,20222 ----
   * hashtab_T used.
   */
      static dictitem_T *
! find_var(name, htp, no_autoload)
      char_u	*name;
      hashtab_T	**htp;
+     int		no_autoload;
  {
      char_u	*varname;
      hashtab_T	*ht;
***************
*** 20219,20225 ****
  	*htp = ht;
      if (ht == NULL)
  	return NULL;
!     return find_var_in_ht(ht, *name, varname, htp != NULL);
  }
  
  /*
--- 20226,20232 ----
  	*htp = ht;
      if (ht == NULL)
  	return NULL;
!     return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
  }
  
  /*
***************
*** 20227,20237 ****
   * Returns NULL if not found.
   */
      static dictitem_T *
! find_var_in_ht(ht, htname, varname, writing)
      hashtab_T	*ht;
      int		htname;
      char_u	*varname;
!     int		writing;
  {
      hashitem_T	*hi;
  
--- 20234,20244 ----
   * Returns NULL if not found.
   */
      static dictitem_T *
! find_var_in_ht(ht, htname, varname, no_autoload)
      hashtab_T	*ht;
      int		htname;
      char_u	*varname;
!     int		no_autoload;
  {
      hashitem_T	*hi;
  
***************
*** 20263,20269 ****
  	 * worked find the variable again.  Don't auto-load a script if it was
  	 * loaded already, otherwise it would be loaded every time when
  	 * checking if a function name is a Funcref variable. */
! 	if (ht == &globvarht && !writing)
  	{
  	    /* Note: script_autoload() may make "hi" invalid. It must either
  	     * be obtained again or not used. */
--- 20270,20276 ----
  	 * worked find the variable again.  Don't auto-load a script if it was
  	 * loaded already, otherwise it would be loaded every time when
  	 * checking if a function name is a Funcref variable. */
! 	if (ht == &globvarht && !no_autoload)
  	{
  	    /* Note: script_autoload() may make "hi" invalid. It must either
  	     * be obtained again or not used. */
***************
*** 20343,20349 ****
  {
      dictitem_T	*v;
  
!     v = find_var(name, NULL);
      if (v == NULL)
  	return NULL;
      return get_tv_string(&v->di_tv);
--- 20350,20356 ----
  {
      dictitem_T	*v;
  
!     v = find_var(name, NULL, FALSE);
      if (v == NULL)
  	return NULL;
      return get_tv_string(&v->di_tv);
***************
*** 21672,21678 ****
       */
      if (fudi.fd_dict == NULL)
      {
! 	v = find_var(name, &ht);
  	if (v != NULL && v->di_tv.v_type == VAR_FUNC)
  	{
  	    emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
--- 21679,21685 ----
       */
      if (fudi.fd_dict == NULL)
      {
! 	v = find_var(name, &ht, FALSE);
  	if (v != NULL && v->di_tv.v_type == VAR_FUNC)
  	{
  	    emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
***************
*** 21830,21837 ****
   * Also handles a Funcref in a List or Dictionary.
   * Returns the function name in allocated memory, or NULL for failure.
   * flags:
!  * TFN_INT:   internal function name OK
!  * TFN_QUIET: be quiet
   * Advances "pp" to just after the function name (if no error).
   */
      static char_u *
--- 21837,21845 ----
   * Also handles a Funcref in a List or Dictionary.
   * Returns the function name in allocated memory, or NULL for failure.
   * flags:
!  * TFN_INT:         internal function name OK
!  * TFN_QUIET:       be quiet
!  * TFN_NO_AUTOLOAD: do not use script autoloading
   * Advances "pp" to just after the function name (if no error).
   */
      static char_u *
***************
*** 21869,21875 ****
      if (lead > 2)
  	start += lead;
  
!     end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET,
  					      lead > 2 ? 0 : FNE_CHECK_START);
      if (end == start)
      {
--- 21877,21883 ----
      if (lead > 2)
  	start += lead;
  
!     end = get_lval(start, NULL, &lv, FALSE, skip, TFN_TO_GLV(flags),
  					      lead > 2 ? 0 : FNE_CHECK_START);
      if (end == start)
      {
***************
*** 22146,22152 ****
      char_u  *p;
      int	    n = FALSE;
  
!     p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
      nm = skipwhite(nm);
  
      /* Only accept "funcname", "funcname ", "funcname (..." and
--- 22154,22161 ----
      char_u  *p;
      int	    n = FALSE;
  
!     p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
! 			    NULL);
      nm = skipwhite(nm);
  
      /* Only accept "funcname", "funcname ", "funcname (..." and
***************
*** 22393,22402 ****
      int		ret = FALSE;
      int		i;
  
-     /* Return quickly when autoload disabled. */
-     if (no_autoload)
- 	return FALSE;
- 
      /* If there is no '#' after name[0] there is no package name. */
      p = vim_strchr(name, AUTOLOAD_CHAR);
      if (p == NULL || p == name)
--- 22402,22407 ----
diff -crN vim-small-patches.bc19475ed196/src/testdir/test55.in vim-small-patches.7b182c0bfaf5/src/testdir/test55.in
*** vim-small-patches.bc19475ed196/src/testdir/test55.in	2014-01-07 07:44:20.407838396 +0400
--- vim-small-patches.7b182c0bfaf5/src/testdir/test55.in	2014-01-07 07:44:20.409838397 +0400
***************
*** 282,287 ****
--- 282,294 ----
  :    $put =ps
  :  endfor
  :endfor
+ :" :lockvar/islocked() triggering script autoloading
+ :set rtp+=./sautest
+ :lockvar g:foo#x
+ :unlockvar g:foo#x
+ :$put ='locked g:foo#x:'.islocked('g:foo#x')
+ :$put ='exists g:foo#x:'.exists('g:foo#x')
+ :$put ='g:foo#x: '.g:foo#x
  :"
  :" a:000 function argument
  :" first the tests that should fail
diff -crN vim-small-patches.bc19475ed196/src/testdir/test55.ok vim-small-patches.7b182c0bfaf5/src/testdir/test55.ok
*** vim-small-patches.bc19475ed196/src/testdir/test55.ok	2014-01-07 07:44:20.387838394 +0400
--- vim-small-patches.7b182c0bfaf5/src/testdir/test55.ok	2014-01-07 07:44:20.408838396 +0400
***************
*** 86,91 ****
--- 86,94 ----
  FFpFFpp
  0000-000
  ppppppp
+ locked g:foo#x:-1
+ exists g:foo#x:0
+ g:foo#x: 1
  caught a:000
  caught a:000[0]
  caught a:000[2]
diff -crN vim-small-patches.bc19475ed196/src/testdir/test60.in vim-small-patches.7b182c0bfaf5/src/testdir/test60.in
*** vim-small-patches.bc19475ed196/src/testdir/test60.in	2014-01-07 07:44:20.388838394 +0400
--- vim-small-patches.7b182c0bfaf5/src/testdir/test60.in	2014-01-07 07:44:20.427838398 +0400
***************
*** 1,4 ****
! Tests for the exists() function.  vim: set ft=vim :
  
  STARTTEST
  :so small.vim
--- 1,4 ----
! Tests for the exists() function.  vim: set ft=vim ts=8 :
  
  STARTTEST
  :so small.vim
***************
*** 11,18 ****
  endfunction
  :function! TestExists()
      augroup myagroup
! 	autocmd! BufEnter *.my echo 'myfile edited'
      augroup END
  
      let test_cases = []
  
--- 11,20 ----
  endfunction
  :function! TestExists()
      augroup myagroup
! 	autocmd! BufEnter       *.my     echo "myfile edited"
! 	autocmd! FuncUndefined  UndefFun exec "fu UndefFun()\nendfu"
      augroup END
+     set rtp+=./sautest
  
      let test_cases = []
  
***************
*** 95,104 ****
      " Non-existing user defined function
      let test_cases += [['*MyxyzFunc', 0]]
  
      redir! > test.out
  
      for [test_case, result] in test_cases
!       	echo test_case . ": " . result
          call RunTest(test_case, result)
      endfor
  
--- 97,111 ----
      " Non-existing user defined function
      let test_cases += [['*MyxyzFunc', 0]]
  
+     " Function that may be created by FuncUndefined event
+     let test_cases += [['*UndefFun', 0]]
+     " Function that may be created by script autoloading
+     let test_cases += [['*foo#F', 0]]
+ 
      redir! > test.out
  
      for [test_case, result] in test_cases
!         echo test_case . ": " . result
          call RunTest(test_case, result)
      endfor
  
***************
*** 207,212 ****
--- 214,227 ----
  	echo "FAILED"
      endif
  
+     " Non-existing autoload variable that may be autoloaded
+     echo 'foo#x: 0'
+     if !exists('foo#x')
+ 	echo "OK"
+     else
+ 	echo "FAILED"
+     endif
+ 
      " Valid local list
      let local_list = ["blue", "orange"]
      echo 'local_list: 1'
***************
*** 566,571 ****
--- 581,590 ----
  
      call TestFuncArg("arg1", "arg2")
  
+     echo ' g:foo#x =' g:foo#x
+     echo '   foo#F()' foo#F()
+     echo 'UndefFun()' UndefFun()
+ 
      redir END
  endfunction
  :call TestExists()
***************
*** 576,580 ****
--- 595,600 ----
  :set ff=unix
  :w
  :qa!
+ :while getchar(1) | call getchar() | endwhile
  ENDTEST
  
diff -crN vim-small-patches.bc19475ed196/src/testdir/test60.ok vim-small-patches.7b182c0bfaf5/src/testdir/test60.ok
*** vim-small-patches.bc19475ed196/src/testdir/test60.ok	2014-01-07 07:44:20.387838394 +0400
--- vim-small-patches.7b182c0bfaf5/src/testdir/test60.ok	2014-01-07 07:44:20.408838396 +0400
***************
*** 71,76 ****
--- 71,80 ----
  OK
  *MyxyzFunc: 0
  OK
+ *UndefFun: 0
+ OK
+ *foo#F: 0
+ OK
  :edit: 2
  OK
  :edit/a: 0
***************
*** 95,100 ****
--- 99,106 ----
  OK
  local_var: 0
  OK
+ foo#x: 0
+ OK
  local_list: 1
  OK
  local_list[1]: 1
***************
*** 195,197 ****
--- 201,206 ----
  OK
  a:2: 0
  OK
+  g:foo#x = 1
+    foo#F() 0
+ UndefFun() 0

Raspunde prin e-mail lui