]> granicus.if.org Git - vim/commitdiff
updated for version 7.2a-013 v7.2a.013
authorBram Moolenaar <Bram@vim.org>
Fri, 4 Jul 2008 09:44:11 +0000 (09:44 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 4 Jul 2008 09:44:11 +0000 (09:44 +0000)
runtime/doc/eval.txt
src/eval.c
src/ex_docmd.c
src/misc2.c
src/proto/ex_docmd.pro
src/proto/misc2.pro
src/version.c

index 349df2f251637c67d707d9082e32967b77990163..6fd0ae1715e0e8342e4f658f4594720ffcb8d278 100644 (file)
@@ -1856,7 +1856,8 @@ setreg( {n}, {v}[, {opt}])        Number  set register to value and type
 settabwinvar( {tabnr}, {winnr}, {varname}, {val})    set {varname} in window
                                        {winnr} in tab page {tabnr} to {val}
 setwinvar( {nr}, {varname}, {val})     set {varname} in window {nr} to {val}
-shellescape( {string})         String  escape {string} for use as shell
+shellescape( {string} [, {special}])
+                               String  escape {string} for use as shell
                                        command argument
 simplify( {filename})          String  simplify filename as much as possible
 sin( {expr})                   Float   sine of {expr}
@@ -4018,10 +4019,10 @@ mkdir({name} [, {path} [, {prot}]])
 <
                                                        *mode()*
 mode([expr])   Return a string that indicates the current mode.
-               If [expr] is supplied and it evaluates to a non-zero number or
-               a non-empty string, then the full mode is returned, otherwise
-               only the first letter is returned.  Note that " " and "0" are
-               also non-empty strings.
+               If [expr] is supplied and it evaluates to a non-zero Number or
+               a non-empty String (|non-zero-arg|), then the full mode is
+               returned, otherwise only the first letter is returned.  Note
+               that " " and "0" are also non-empty strings.
 
                        n       Normal
                        no      Operator-pending
@@ -4941,19 +4942,23 @@ setwinvar({nr}, {varname}, {val})                       *setwinvar()*
                        :call setwinvar(1, "&list", 0)
                        :call setwinvar(2, "myvar", "foobar")
 
-shellescape({string})                                  *shellescape()*
+shellescape({string} [, {special}])                    *shellescape()*
                Escape {string} for use as shell command argument.
                On MS-Windows and MS-DOS, when 'shellslash' is not set, it
-               will enclose {string} double quotes and double all double
+               will enclose {string} in double quotes and double all double
                quotes within {string}.
                For other systems, it will enclose {string} in single quotes
                and replace all "'" with "'\''".
-               Example: >
-                       :echo shellescape('c:\program files\vim')
-<              results in:
-                       "c:\program files\vim" ~
-               Example usage: >
-                       :call system("chmod +x -- " . shellescape(expand("%")))
+               When the {special} argument is present and it's a non-zero
+               Number or a non-empty String (|non-zero-arg|), then special
+               items such as "%", "#" and "<cword>" will be preceded by a
+               backslash.  This backslash will be removed again by the |:!|
+               command.
+               Example of use with a |:!| command: >
+                   :exe '!dir ' . shellescape(expand('<cfile>'), 1)
+<              This results in a directory listing for the file under the
+               cursor.  Example of use with |system()|: >
+                   :call system("chmod +w -- " . shellescape(expand("%")))
 
 
 simplify({filename})                                   *simplify()*
@@ -5333,13 +5338,14 @@ system({expr} [, {input}])                              *system()* *E677*
                passed as stdin to the command.  The string is written as-is,
                you need to take care of using the correct line separators
                yourself.  Pipes are not used.
-               Note: newlines in {expr} may cause the command to fail.  The
-               characters in 'shellquote' and 'shellxquote' may also cause
-               trouble.
+               Note: Use |shellescape()| to escape special characters in a
+               command argument.  Newlines in {expr} may cause the command to
+               fail.  The characters in 'shellquote' and 'shellxquote' may
+               also cause trouble.
                This is not to be used for interactive commands.
-               The result is a String.  Example: >
 
-                       :let files = system("ls")
+               The result is a String.  Example: >
+                   :let files = system("ls " .  shellescape(expand('%:h')))
 
 <              To make the result more system-independent, the shell output
                is filtered to replace <CR> with <NL> for Macintosh, and
@@ -5559,11 +5565,13 @@ visualmode([expr])                                              *visualmode()*
                Visual mode that was used.
                If Visual mode is active, use |mode()| to get the Visual mode
                (e.g., in a |:vmap|).
-
-               If [expr] is supplied and it evaluates to a non-zero number or
-               a non-empty string, then the Visual mode will be cleared and
+                                                       *non-zero-arg*
+               If [expr] is supplied and it evaluates to a non-zero Number or
+               a non-empty String, then the Visual mode will be cleared and
                the old value is returned.  Note that " " and "0" are also
-               non-empty strings, thus cause the mode to be cleared.
+               non-empty strings, thus cause the mode to be cleared.  A List,
+               Dictionary or Float is not a Number or String, thus does not
+               cause the mode to be cleared.
 
                                                        *winbufnr()*
 winbufnr({nr}) The result is a Number, which is the number of the buffer
@@ -6738,8 +6746,10 @@ This would call the function "my_func_whizz(parameter)".
 
                        Be careful to correctly escape special characters in
                        file names.  The |fnameescape()| function can be used
-                       for this.  Example: >
+                       for Vim commands, |shellescape()| for |:!| commands.
+                       Examples: >
                :execute "e " . fnameescape(filename)
+               :execute "!ls " . shellescape(expand('%:h'), 1)
 <
                        Note: The executed string may be any command-line, but
                        you cannot start or end a "while", "for" or "if"
index e4024986e27bf364524b8c8d3742fb3f7c74d8a9..a41411a259de35092a97893d18b7c1436ef4c27f 100644 (file)
@@ -462,6 +462,7 @@ static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
 static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
 static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
 static void emsg_funcname __ARGS((char *ermsg, char_u *name));
+static int non_zero_arg __ARGS((typval_T *argvars));
 
 #ifdef FEAT_FLOAT
 static void f_abs __ARGS((typval_T *argvars, typval_T *rettv));
@@ -7611,7 +7612,7 @@ static struct fst
     {"setreg",         2, 3, f_setreg},
     {"settabwinvar",   4, 4, f_settabwinvar},
     {"setwinvar",      3, 3, f_setwinvar},
-    {"shellescape",    1, 1, f_shellescape},
+    {"shellescape",    1, 2, f_shellescape},
     {"simplify",       1, 1, f_simplify},
 #ifdef FEAT_FLOAT
     {"sin",            1, 1, f_sin},
@@ -8094,6 +8095,20 @@ emsg_funcname(ermsg, name)
        vim_free(p);
 }
 
+/*
+ * Return TRUE for a non-zero Number and a non-empty String.
+ */
+    static int
+non_zero_arg(argvars)
+    typval_T   *argvars;
+{
+    return ((argvars[0].v_type == VAR_NUMBER
+               && argvars[0].vval.v_number != 0)
+           || (argvars[0].v_type == VAR_STRING
+               && argvars[0].vval.v_string != NULL
+               && *argvars[0].vval.v_string != NUL));
+}
+
 /*********************************************
  * Implementation of the built-in functions
  */
@@ -13480,10 +13495,9 @@ f_mode(argvars, rettv)
            buf[1] = 'o';
     }
 
-    /* A zero number or empty string argument: return only major mode. */
-    if (!(argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number != 0)
-           && !(argvars[0].v_type == VAR_STRING
-                                      && *get_tv_string(&argvars[0]) != NUL))
+    /* Clear out the minor mode when the argument is not a non-zero number or
+     * non-empty string.  */
+    if (!non_zero_arg(&argvars[0]))
        buf[1] = NUL;
 
     rettv->vval.v_string = vim_strsave(buf);
@@ -15684,7 +15698,8 @@ f_shellescape(argvars, rettv)
     typval_T   *argvars;
     typval_T   *rettv;
 {
-    rettv->vval.v_string = vim_strsave_shellescape(get_tv_string(&argvars[0]));
+    rettv->vval.v_string = vim_strsave_shellescape(
+                      get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]));
     rettv->v_type = VAR_STRING;
 }
 
@@ -17273,9 +17288,7 @@ f_visualmode(argvars, rettv)
     rettv->vval.v_string = vim_strsave(str);
 
     /* A non-zero number or non-empty string argument: reset mode. */
-    if ((argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number != 0)
-           || (argvars[0].v_type == VAR_STRING
-                                      && *get_tv_string(&argvars[0]) != NUL))
+    if (non_zero_arg(&argvars[0]))
        curbuf->b_visual_mode_eval = NUL;
 #else
     rettv->vval.v_number = 0; /* return anything, it won't work anyway */
index 460fc2a39a9c7b61cfd436055cf308fdf97b4bf9..83cffc1fc438cf648145abdcbd4bf29da7b6863c 100644 (file)
@@ -7059,8 +7059,8 @@ ex_splitview(eap)
 
 # ifdef FEAT_QUICKFIX
     /* A ":split" in the quickfix window works like ":new".  Don't want two
-     * quickfix windows. */
-    if (bt_quickfix(curbuf))
+     * quickfix windows.  But it's OK when doing ":tab split". */
+    if (bt_quickfix(curbuf) && cmdmod.tab == 0)
     {
        if (eap->cmdidx == CMD_split)
            eap->cmdidx = CMD_new;
@@ -9320,6 +9320,58 @@ ex_tag_cmd(eap, name)
                                                          eap->forceit, TRUE);
 }
 
+/*
+ * Check "str" for starting with a special cmdline variable.
+ * If found return one of the SPEC_ values and set "*usedlen" to the length of
+ * the variable.  Otherwise return -1 and "*usedlen" is unchanged.
+ */
+    int
+find_cmdline_var(src, usedlen)
+    char_u     *src;
+    int                *usedlen;
+{
+    int                len;
+    int                i;
+    static char *(spec_str[]) = {
+                   "%",
+#define SPEC_PERC   0
+                   "#",
+#define SPEC_HASH   1
+                   "<cword>",          /* cursor word */
+#define SPEC_CWORD  2
+                   "<cWORD>",          /* cursor WORD */
+#define SPEC_CCWORD 3
+                   "<cfile>",          /* cursor path name */
+#define SPEC_CFILE  4
+                   "<sfile>",          /* ":so" file name */
+#define SPEC_SFILE  5
+#ifdef FEAT_AUTOCMD
+                   "<afile>",          /* autocommand file name */
+# define SPEC_AFILE 6
+                   "<abuf>",           /* autocommand buffer number */
+# define SPEC_ABUF  7
+                   "<amatch>",         /* autocommand match name */
+# define SPEC_AMATCH 8
+#endif
+#ifdef FEAT_CLIENTSERVER
+                   "<client>"
+# define SPEC_CLIENT 9
+#endif
+    };
+#define SPEC_COUNT  (sizeof(spec_str) / sizeof(char *))
+
+    for (i = 0; i < SPEC_COUNT; ++i)
+    {
+       len = (int)STRLEN(spec_str[i]);
+       if (STRNCMP(src, spec_str[i], len) == 0)
+       {
+           *usedlen = len;
+           return i;
+       }
+    }
+    return -1;
+}
+
 /*
  * Evaluate cmdline variables.
  *
@@ -9360,34 +9412,6 @@ eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
 #ifdef FEAT_MODIFY_FNAME
     int                skip_mod = FALSE;
 #endif
-    static char *(spec_str[]) =
-       {
-                   "%",
-#define SPEC_PERC   0
-                   "#",
-#define SPEC_HASH   1
-                   "<cword>",          /* cursor word */
-#define SPEC_CWORD  2
-                   "<cWORD>",          /* cursor WORD */
-#define SPEC_CCWORD 3
-                   "<cfile>",          /* cursor path name */
-#define SPEC_CFILE  4
-                   "<sfile>",          /* ":so" file name */
-#define SPEC_SFILE  5
-#ifdef FEAT_AUTOCMD
-                   "<afile>",          /* autocommand file name */
-# define SPEC_AFILE 6
-                   "<abuf>",           /* autocommand buffer number */
-# define SPEC_ABUF  7
-                   "<amatch>",         /* autocommand match name */
-# define SPEC_AMATCH 8
-#endif
-#ifdef FEAT_CLIENTSERVER
-                   "<client>"
-# define SPEC_CLIENT 9
-#endif
-               };
-#define SPEC_COUNT  (sizeof(spec_str) / sizeof(char *))
 
 #if defined(FEAT_AUTOCMD) || defined(FEAT_CLIENTSERVER)
     char_u     strbuf[30];
@@ -9400,13 +9424,8 @@ eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
     /*
      * Check if there is something to do.
      */
-    for (spec_idx = 0; spec_idx < SPEC_COUNT; ++spec_idx)
-    {
-       *usedlen = (int)STRLEN(spec_str[spec_idx]);
-       if (STRNCMP(src, spec_str[spec_idx], *usedlen) == 0)
-           break;
-    }
-    if (spec_idx == SPEC_COUNT)            /* no match */
+    spec_idx = find_cmdline_var(src, usedlen);
+    if (spec_idx < 0)  /* no match */
     {
        *usedlen = 1;
        return NULL;
index 62a8cda14601a3cf449e0fb22ead5024d0dfd922..04f038b9a265f4d5168394e8090c21fb614e37f8 100644 (file)
@@ -1262,16 +1262,19 @@ vim_strsave_escaped_ext(string, esc_chars, cc, bsl)
  * Escape "string" for use as a shell argument with system().
  * This uses single quotes, except when we know we need to use double qoutes
  * (MS-DOS and MS-Windows without 'shellslash' set).
+ * Also replace "%", "#" and things like "<cfile>" when "do_special" is TRUE.
  * Returns the result in allocated memory, NULL if we have run out.
  */
     char_u *
-vim_strsave_shellescape(string)
+vim_strsave_shellescape(string, do_special)
     char_u     *string;
+    int                do_special;
 {
     unsigned   length;
     char_u     *p;
     char_u     *d;
     char_u     *escaped_string;
+    int                l;
 
     /* First count the number of extra bytes required. */
     length = (unsigned)STRLEN(string) + 3;  /* two quotes and a trailing NUL */
@@ -1287,6 +1290,11 @@ vim_strsave_shellescape(string)
 # endif
        if (*p == '\'')
            length += 3;                /* ' => '\'' */
+       if (do_special && find_cmdline_var(p, &l) >= 0)
+       {
+           ++length;                   /* insert backslash */
+           p += l - 1;
+       }
     }
 
     /* Allocate memory for the result and fill it. */
@@ -1320,13 +1328,19 @@ vim_strsave_shellescape(string)
 # endif
            if (*p == '\'')
            {
-               *d++='\'';
-               *d++='\\';
-               *d++='\'';
-               *d++='\'';
+               *d++ = '\'';
+               *d++ = '\\';
+               *d++ = '\'';
+               *d++ = '\'';
                ++p;
                continue;
            }
+           if (do_special && find_cmdline_var(p, &l) >= 0)
+           {
+               *d++ = '\\';            /* insert backslash */
+               while (--l >= 0)        /* copy the var */
+                   *d++ = *p++;
+           }
 
            MB_COPY_CHAR(p, d);
        }
@@ -2776,7 +2790,7 @@ get_special_key_code(name)
     return 0;
 }
 
-#ifdef FEAT_CMDL_COMPL
+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
     char_u *
 get_key_name(i)
     int            i;
@@ -2787,7 +2801,7 @@ get_key_name(i)
 }
 #endif
 
-#ifdef FEAT_MOUSE
+#if defined(FEAT_MOUSE) || defined(PROTO)
 /*
  * Look up the given mouse code to return the relevant information in the other
  * arguments.  Return which button is down or was released.
index 5835db096d8744b7273d368e8fdfcaff176f1daf..e267acfd87220efb6204553102d330b6f9407887 100644 (file)
@@ -46,6 +46,7 @@ int vim_mkdir_emsg __ARGS((char_u *name, int prot));
 FILE *open_exfile __ARGS((char_u *fname, int forceit, char *mode));
 void update_topline_cursor __ARGS((void));
 void exec_normal_cmd __ARGS((char_u *cmd, int remap, int silent));
+int find_cmdline_var __ARGS((char_u *src, int *usedlen));
 char_u *eval_vars __ARGS((char_u *src, char_u *srcstart, int *usedlen, linenr_T *lnump, char_u **errormsg, int *escaped));
 char_u *expand_sfile __ARGS((char_u *arg));
 int put_eol __ARGS((FILE *fd));
index ce5632ee0560a3fe8b27ca0e219873ba01fb308d..397a09a2573e69a9d60c96798d4e0d18a95ea214 100644 (file)
@@ -29,7 +29,7 @@ char_u *vim_strsave __ARGS((char_u *string));
 char_u *vim_strnsave __ARGS((char_u *string, int len));
 char_u *vim_strsave_escaped __ARGS((char_u *string, char_u *esc_chars));
 char_u *vim_strsave_escaped_ext __ARGS((char_u *string, char_u *esc_chars, int cc, int bsl));
-char_u *vim_strsave_shellescape __ARGS((char_u *string));
+char_u *vim_strsave_shellescape __ARGS((char_u *string, int do_special));
 char_u *vim_strsave_up __ARGS((char_u *string));
 char_u *vim_strnsave_up __ARGS((char_u *string, int len));
 void vim_strup __ARGS((char_u *p));
index f46ebda2c56762368a5f06309baed0dc26a5bf0c..49f41f50eb862b707a93dc2574636f947c35ace2 100644 (file)
@@ -676,6 +676,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    13,
 /**/
     12,
 /**/