0
0
mirror of https://github.com/vim/vim.git synced 2025-09-30 04:44:14 -04:00

updated for version 7.4.191

Problem:    Escaping a file name for shell commands can't be done without a
            function.
Solution:   Add the :S file name modifier.
This commit is contained in:
Bram Moolenaar
2014-02-23 23:39:13 +01:00
parent 581966e832
commit 26df092843
20 changed files with 126 additions and 26 deletions

View File

@@ -5428,6 +5428,7 @@ shellescape({string} [, {special}]) *shellescape()*
< This results in a directory listing for the file under the < This results in a directory listing for the file under the
cursor. Example of use with |system()|: > cursor. Example of use with |system()|: >
:call system("chmod +w -- " . shellescape(expand("%"))) :call system("chmod +w -- " . shellescape(expand("%")))
< See also |::S|.
shiftwidth() *shiftwidth()* shiftwidth() *shiftwidth()*
@@ -5910,14 +5911,16 @@ system({expr} [, {input}]) *system()* *E677*
passed as stdin to the command. The string is written as-is, passed as stdin to the command. The string is written as-is,
you need to take care of using the correct line separators you need to take care of using the correct line separators
yourself. Pipes are not used. yourself. Pipes are not used.
Note: Use |shellescape()| to escape special characters in a Note: Use |shellescape()| or |::S| with |expand()| or
command argument. Newlines in {expr} may cause the command to |fnamemodify()| to escape special characters in a command
fail. The characters in 'shellquote' and 'shellxquote' may argument. Newlines in {expr} may cause the command to fail.
also cause trouble. The characters in 'shellquote' and 'shellxquote' may also
cause trouble.
This is not to be used for interactive commands. This is not to be used for interactive commands.
The result is a String. Example: > The result is a String. Example: >
:let files = system("ls " . shellescape(expand('%:h'))) :let files = system("ls " . shellescape(expand('%:h')))
:let files = system('ls ' . expand('%:h:S'))
< To make the result more system-independent, the shell output < To make the result more system-independent, the shell output
is filtered to replace <CR> with <NL> for Macintosh, and is filtered to replace <CR> with <NL> for Macintosh, and

View File

@@ -4757,8 +4757,9 @@ A jump table for the options with a short description can be found at |Q_op|.
global or local to buffer |global-local| global or local to buffer |global-local|
{not in Vi} {not in Vi}
Program to use for the ":make" command. See |:make_makeprg|. Program to use for the ":make" command. See |:make_makeprg|.
This option may contain '%' and '#' characters, which are expanded to This option may contain '%' and '#' characters (see |:_%| and |:_#|),
the current and alternate file name. |:_%| |:_#| which are expanded to the current and alternate file name. Use |::S|
to escape file names in case they contain special characters.
Environment variables are expanded |:set_env|. See |option-backslash| Environment variables are expanded |:set_env|. See |option-backslash|
about including spaces and backslashes. about including spaces and backslashes.
Note that a '|' must be escaped twice: once for ":set" and once for Note that a '|' must be escaped twice: once for ":set" and once for

View File

@@ -838,7 +838,7 @@ Unfortunately, there is no standard way to run the tests.
The alltests.py script seems to be used quite often, that's all. The alltests.py script seems to be used quite often, that's all.
Useful values for the 'makeprg' options therefore are: Useful values for the 'makeprg' options therefore are:
setlocal makeprg=./alltests.py " Run a testsuite setlocal makeprg=./alltests.py " Run a testsuite
setlocal makeprg=python % " Run a single testcase setlocal makeprg=python\ %:S " Run a single testcase
Also see http://vim.sourceforge.net/tip_view.php?tip_id=280. Also see http://vim.sourceforge.net/tip_view.php?tip_id=280.
@@ -1332,7 +1332,7 @@ or: >
Here is an alternative from Michael F. Lamb for Unix that filters the errors Here is an alternative from Michael F. Lamb for Unix that filters the errors
first: > first: >
:setl errorformat=%Z%f:%l:\ %m,%A%p^,%-G%*[^sl]%.%# :setl errorformat=%Z%f:%l:\ %m,%A%p^,%-G%*[^sl]%.%#
:setl makeprg=javac\ %\ 2>&1\ \\\|\ vim-javac-filter :setl makeprg=javac\ %:S\ 2>&1\ \\\|\ vim-javac-filter
You need to put the following in "vim-javac-filter" somewhere in your path You need to put the following in "vim-javac-filter" somewhere in your path
(e.g., in ~/bin) and make it executable: > (e.g., in ~/bin) and make it executable: >

View File

@@ -128,7 +128,7 @@ be escaped with a backslash. Example: >
You can include special Vim keywords in the command specification. The % You can include special Vim keywords in the command specification. The %
character expands to the name of the current file. So if you execute the character expands to the name of the current file. So if you execute the
command: > command: >
:set makeprg=make\ % :set makeprg=make\ %:S
When you are editing main.c, then ":make" executes the following command: > When you are editing main.c, then ":make" executes the following command: >
@@ -137,7 +137,7 @@ When you are editing main.c, then ":make" executes the following command: >
This is not too useful, so you will refine the command a little and use the :r This is not too useful, so you will refine the command a little and use the :r
(root) modifier: > (root) modifier: >
:set makeprg=make\ %:r.o :set makeprg=make\ %:r:S.o
Now the command executed is as follows: > Now the command executed is as follows: >

View File

@@ -209,7 +209,7 @@ The ":map" command can be followed by another command. A | character
separates the two commands. This also means that a | character can't be used separates the two commands. This also means that a | character can't be used
inside a map command. To include one, use <Bar> (five characters). Example: inside a map command. To include one, use <Bar> (five characters). Example:
> >
:map <F8> :write <Bar> !checkin %<CR> :map <F8> :write <Bar> !checkin %:S<CR>
The same problem applies to the ":unmap" command, with the addition that you The same problem applies to the ":unmap" command, with the addition that you
have to watch out for trailing white space. These two commands are different: have to watch out for trailing white space. These two commands are different:

View File

@@ -311,7 +311,7 @@ redefine what these items do (after the default menus are setup).
item with a bitmap. For example, define a new toolbar item with: > item with a bitmap. For example, define a new toolbar item with: >
:tmenu ToolBar.Compile Compile the current file :tmenu ToolBar.Compile Compile the current file
:amenu ToolBar.Compile :!cc % -o %:r<CR> :amenu ToolBar.Compile :!cc %:S -o %:r:S<CR>
Now you need to create the icon. For MS-Windows it must be in bitmap format, Now you need to create the icon. For MS-Windows it must be in bitmap format,
with the name "Compile.bmp". For Unix XPM format is used, the file name is with the name "Compile.bmp". For Unix XPM format is used, the file name is

View File

@@ -540,7 +540,7 @@ character (and shows it immediately).
Added :wnext command. Same as ":write" followed by ":next". Added :wnext command. Same as ":write" followed by ":next".
The ":w!" command always writes, also when the file is write protected. In Vi The ":w!" command always writes, also when the file is write protected. In Vi
you would have to do ":!chmod +w %" and ":set noro". you would have to do ":!chmod +w %:S" and ":set noro".
When 'tildeop' has been set, "~" is an operator (must be followed by a When 'tildeop' has been set, "~" is an operator (must be followed by a
movement command). movement command).

View File

@@ -16950,7 +16950,7 @@ f_shellescape(argvars, rettv)
typval_T *rettv; typval_T *rettv;
{ {
rettv->vval.v_string = vim_strsave_shellescape( rettv->vval.v_string = vim_strsave_shellescape(
get_tv_string(&argvars[0]), non_zero_arg(&argvars[1])); get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), TRUE);
rettv->v_type = VAR_STRING; rettv->v_type = VAR_STRING;
} }
@@ -24355,6 +24355,17 @@ repeat:
} }
} }
if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S')
{
p = vim_strsave_shellescape(*fnamep, FALSE, FALSE);
if (p == NULL)
return -1;
vim_free(*bufp);
*bufp = *fnamep = p;
*fnamelen = (int)STRLEN(p);
*usedlen += 2;
}
return valid; return valid;
} }

View File

@@ -1369,12 +1369,14 @@ csh_like_shell()
* Escape a newline, depending on the 'shell' option. * Escape a newline, depending on the 'shell' option.
* When "do_special" is TRUE also replace "!", "%", "#" and things starting * When "do_special" is TRUE also replace "!", "%", "#" and things starting
* with "<" like "<cfile>". * with "<" like "<cfile>".
* When "do_newline" is FALSE do not escape newline unless it is csh shell.
* Returns the result in allocated memory, NULL if we have run out. * Returns the result in allocated memory, NULL if we have run out.
*/ */
char_u * char_u *
vim_strsave_shellescape(string, do_special) vim_strsave_shellescape(string, do_special, do_newline)
char_u *string; char_u *string;
int do_special; int do_special;
int do_newline;
{ {
unsigned length; unsigned length;
char_u *p; char_u *p;
@@ -1403,7 +1405,8 @@ vim_strsave_shellescape(string, do_special)
# endif # endif
if (*p == '\'') if (*p == '\'')
length += 3; /* ' => '\'' */ length += 3; /* ' => '\'' */
if (*p == '\n' || (*p == '!' && (csh_like || do_special))) if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special)))
{ {
++length; /* insert backslash */ ++length; /* insert backslash */
if (csh_like && do_special) if (csh_like && do_special)
@@ -1454,7 +1457,8 @@ vim_strsave_shellescape(string, do_special)
++p; ++p;
continue; continue;
} }
if (*p == '\n' || (*p == '!' && (csh_like || do_special))) if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special)))
{ {
*d++ = '\\'; *d++ = '\\';
if (csh_like && do_special) if (csh_like && do_special)

View File

@@ -5790,7 +5790,7 @@ nv_ident(cap)
{ {
/* Escape the argument properly for a shell command */ /* Escape the argument properly for a shell command */
ptr = vim_strnsave(ptr, n); ptr = vim_strnsave(ptr, n);
p = vim_strsave_shellescape(ptr, TRUE); p = vim_strsave_shellescape(ptr, TRUE, TRUE);
vim_free(ptr); vim_free(ptr);
if (p == NULL) if (p == NULL)
{ {

View File

@@ -32,7 +32,7 @@ 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 __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_escaped_ext __ARGS((char_u *string, char_u *esc_chars, int cc, int bsl));
int csh_like_shell __ARGS((void)); int csh_like_shell __ARGS((void));
char_u *vim_strsave_shellescape __ARGS((char_u *string, int do_special)); char_u *vim_strsave_shellescape __ARGS((char_u *string, int do_special, int do_newline));
char_u *vim_strsave_up __ARGS((char_u *string)); char_u *vim_strsave_up __ARGS((char_u *string));
char_u *vim_strnsave_up __ARGS((char_u *string, int len)); char_u *vim_strnsave_up __ARGS((char_u *string, int len));
void vim_strup __ARGS((char_u *p)); void vim_strup __ARGS((char_u *p));

View File

@@ -35,7 +35,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test89.out test90.out test91.out test92.out test93.out \ test89.out test90.out test91.out test92.out test93.out \
test94.out test95.out test96.out test97.out test98.out \ test94.out test95.out test96.out test97.out test98.out \
test99.out test100.out test101.out test102.out test103.out \ test99.out test100.out test101.out test102.out test103.out \
test104.out test104.out test105.out
.SUFFIXES: .in .out .SUFFIXES: .in .out
@@ -156,3 +156,4 @@ test101.out: test101.in
test102.out: test102.in test102.out: test102.in
test103.out: test103.in test103.out: test103.in
test104.out: test104.in test104.out: test104.in
test105.out: test105.in

View File

@@ -33,7 +33,8 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test84.out test85.out test86.out test87.out test88.out \ test84.out test85.out test86.out test87.out test88.out \
test89.out test90.out test91.out test92.out test93.out \ test89.out test90.out test91.out test92.out test93.out \
test94.out test95.out test96.out test98.out test99.out \ test94.out test95.out test96.out test98.out test99.out \
test100.out test101.out test102.out test103.out test104.out test100.out test101.out test102.out test103.out test104.out \
test105.out
SCRIPTS32 = test50.out test70.out SCRIPTS32 = test50.out test70.out

View File

@@ -53,7 +53,8 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test84.out test85.out test86.out test87.out test88.out \ test84.out test85.out test86.out test87.out test88.out \
test89.out test90.out test91.out test92.out test93.out \ test89.out test90.out test91.out test92.out test93.out \
test94.out test95.out test96.out test98.out test99.out \ test94.out test95.out test96.out test98.out test99.out \
test100.out test101.out test102.out test103.out test104.out test100.out test101.out test102.out test103.out test104.out \
test105.out
SCRIPTS32 = test50.out test70.out SCRIPTS32 = test50.out test70.out

View File

@@ -35,7 +35,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
test81.out test82.out test83.out test84.out test88.out \ test81.out test82.out test83.out test84.out test88.out \
test89.out test90.out test91.out test92.out test93.out \ test89.out test90.out test91.out test92.out test93.out \
test94.out test95.out test96.out test98.out test99.out \ test94.out test95.out test96.out test98.out test99.out \
test100.out test101.out test102.out test103.out test104.out test100.out test101.out test102.out test103.out test104.out \
test105.out
.SUFFIXES: .in .out .SUFFIXES: .in .out

View File

@@ -4,7 +4,7 @@
# Authors: Zoltan Arpadffy, <arpadffy@polarhome.com> # Authors: Zoltan Arpadffy, <arpadffy@polarhome.com>
# Sandor Kopanyi, <sandor.kopanyi@mailbox.hu> # Sandor Kopanyi, <sandor.kopanyi@mailbox.hu>
# #
# Last change: 2013 Nov 21 # Last change: 2014 Feb 23
# #
# This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64.
# Edit the lines in the Configuration section below to select. # Edit the lines in the Configuration section below to select.
@@ -79,7 +79,8 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \
test82.out test83.out test84.out test88.out test89.out \ test82.out test83.out test84.out test88.out test89.out \
test90.out test91.out test92.out test93.out test94.out \ test90.out test91.out test92.out test93.out test94.out \
test95.out test96.out test97.out test98.out test99.out \ test95.out test96.out test97.out test98.out test99.out \
test100.out test101.out test102.out test103.out test104.out test100.out test101.out test102.out test103.out test104.out \
test105.out
# Known problems: # Known problems:
# Test 30: a problem around mac format - unknown reason # Test 30: a problem around mac format - unknown reason

View File

@@ -31,7 +31,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
test89.out test90.out test91.out test92.out test93.out \ test89.out test90.out test91.out test92.out test93.out \
test94.out test95.out test96.out test97.out test98.out \ test94.out test95.out test96.out test97.out test98.out \
test99.out test100.out test101.out test102.out test103.out \ test99.out test100.out test101.out test102.out test103.out \
test104.out test104.out test105.out
SCRIPTS_GUI = test16.out SCRIPTS_GUI = test16.out

45
src/testdir/test105.in Normal file
View File

@@ -0,0 +1,45 @@
Test filename modifiers vim: set ft=vim :
STARTTEST
:source small.vim
:%delete _
:set shell=sh
:set shellslash
:let tab="\t"
:command -nargs=1 Put :let expr=<q-args> | $put =expr.tab.strtrans(string(eval(expr)))
:let $HOME=fnamemodify('.', ':p:h:h:h')
:Put fnamemodify('.', ':p' )[-1:]
:Put fnamemodify('.', ':p:h' )[-1:]
:Put fnamemodify('test.out', ':p' )[-1:]
:Put fnamemodify('test.out', ':.' )
:Put fnamemodify('../testdir/a', ':.' )
:Put fnamemodify('test.out', ':~' )
:Put fnamemodify('../testdir/a', ':~' )
:Put fnamemodify('../testdir/a', ':t' )
:Put fnamemodify('.', ':p:t' )
:Put fnamemodify('test.out', ':p:t' )
:Put fnamemodify('test.out', ':p:e' )
:Put fnamemodify('test.out', ':p:t:e' )
:Put fnamemodify('abc.fb2.tar.gz', ':r' )
:Put fnamemodify('abc.fb2.tar.gz', ':r:r' )
:Put fnamemodify('abc.fb2.tar.gz', ':r:r:r' )
:Put substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(src/testdir/.*\)', '\1', '')
:Put fnamemodify('abc.fb2.tar.gz', ':e' )
:Put fnamemodify('abc.fb2.tar.gz', ':e:e' )
:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e' )
:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e:e')
:Put fnamemodify('abc.fb2.tar.gz', ':e:e:r' )
:Put fnamemodify('abc def', ':S' )
:Put fnamemodify('abc" "def', ':S' )
:Put fnamemodify('abc"%"def', ':S' )
:Put fnamemodify('abc'' ''def', ':S' )
:Put fnamemodify('abc''%''def', ':S' )
:Put fnamemodify("abc\ndef", ':S' )
:set shell=tcsh
:Put fnamemodify("abc\ndef", ':S' )
:$put ='vim: ts=8'
:1 delete _
:w! test.out
:qa!
ENDTEST

29
src/testdir/test105.ok Normal file
View File

@@ -0,0 +1,29 @@
fnamemodify('.', ':p' )[-1:] '/'
fnamemodify('.', ':p:h' )[-1:] 'r'
fnamemodify('test.out', ':p' )[-1:] 't'
fnamemodify('test.out', ':.' ) 'test.out'
fnamemodify('../testdir/a', ':.' ) 'a'
fnamemodify('test.out', ':~' ) '~/src/testdir/test.out'
fnamemodify('../testdir/a', ':~' ) '~/src/testdir/a'
fnamemodify('../testdir/a', ':t' ) 'a'
fnamemodify('.', ':p:t' ) ''
fnamemodify('test.out', ':p:t' ) 'test.out'
fnamemodify('test.out', ':p:e' ) 'out'
fnamemodify('test.out', ':p:t:e' ) 'out'
fnamemodify('abc.fb2.tar.gz', ':r' ) 'abc.fb2.tar'
fnamemodify('abc.fb2.tar.gz', ':r:r' ) 'abc.fb2'
fnamemodify('abc.fb2.tar.gz', ':r:r:r' ) 'abc'
substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(src/testdir/.*\)', '\1', '') 'src/testdir/abc.fb2'
fnamemodify('abc.fb2.tar.gz', ':e' ) 'gz'
fnamemodify('abc.fb2.tar.gz', ':e:e' ) 'tar.gz'
fnamemodify('abc.fb2.tar.gz', ':e:e:e' ) 'fb2.tar.gz'
fnamemodify('abc.fb2.tar.gz', ':e:e:e:e') 'fb2.tar.gz'
fnamemodify('abc.fb2.tar.gz', ':e:e:r' ) 'tar'
fnamemodify('abc def', ':S' ) '''abc def'''
fnamemodify('abc" "def', ':S' ) '''abc" "def'''
fnamemodify('abc"%"def', ':S' ) '''abc"%"def'''
fnamemodify('abc'' ''def', ':S' ) '''abc''\'''' ''\''''def'''
fnamemodify('abc''%''def', ':S' ) '''abc''\''''%''\''''def'''
fnamemodify("abc\ndef", ':S' ) '''abc^@def'''
fnamemodify("abc\ndef", ':S' ) '''abc\^@def'''
vim: ts=8

View File

@@ -738,6 +738,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
191,
/**/ /**/
190, 190,
/**/ /**/