Skip to content

Commit 12c4492

Browse files
committed
patch 8.0.0151: passing buffer content to system() is clumsy
Problem: To pass buffer content to system() and systemlist() one has to first create a string or list. Solution: Allow passing a buffer number. (LemonBoy, closes #1240)
1 parent 7069bf1 commit 12c4492

6 files changed

Lines changed: 60 additions & 5 deletions

File tree

runtime/doc/eval.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7561,7 +7561,11 @@ system({expr} [, {input}]) *system()* *E677*
75617561
If {input} is given and is a |List| it is written to the file
75627562
in a way |writefile()| does with {binary} set to "b" (i.e.
75637563
with a newline between each list item with newlines inside
7564-
list items converted to NULs).
7564+
list items converted to NULs).
7565+
When {input} is given and is a number that is a valid id for
7566+
an existing buffer then the content of the buffer is written
7567+
to the file line by line, each line terminated by a NL and
7568+
NULs characters where the text has a NL.
75657569

75667570
Pipes are not used, the 'shelltemp' option is not used.
75677571

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,7 @@ test_arglist \
21642164
test_substitute \
21652165
test_syn_attr \
21662166
test_syntax \
2167+
test_system \
21672168
test_tabline \
21682169
test_tabpage \
21692170
test_tagcase \

src/evalfunc.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11817,7 +11817,6 @@ get_cmd_output_as_rettv(
1181711817
char_u *res = NULL;
1181811818
char_u *p;
1181911819
char_u *infile = NULL;
11820-
char_u buf[NUMBUFLEN];
1182111820
int err = FALSE;
1182211821
FILE *fd;
1182311822
list_T *list = NULL;
@@ -11831,7 +11830,7 @@ get_cmd_output_as_rettv(
1183111830
if (argvars[1].v_type != VAR_UNKNOWN)
1183211831
{
1183311832
/*
11834-
* Write the string to a temp file, to be used for input of the shell
11833+
* Write the text to a temp file, to be used for input of the shell
1183511834
* command.
1183611835
*/
1183711836
if ((infile = vim_tempname('i', TRUE)) == NULL)
@@ -11846,14 +11845,42 @@ get_cmd_output_as_rettv(
1184611845
EMSG2(_(e_notopen), infile);
1184711846
goto errret;
1184811847
}
11849-
if (argvars[1].v_type == VAR_LIST)
11848+
if (argvars[1].v_type == VAR_NUMBER)
11849+
{
11850+
linenr_T lnum;
11851+
buf_T *buf;
11852+
11853+
buf = buflist_findnr(argvars[1].vval.v_number);
11854+
if (buf == NULL)
11855+
{
11856+
EMSGN(_(e_nobufnr), argvars[1].vval.v_number);
11857+
goto errret;
11858+
}
11859+
11860+
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++)
11861+
{
11862+
for (p = ml_get_buf(buf, lnum, FALSE); *p != NUL; ++p)
11863+
if (putc(*p == '\n' ? NUL : *p, fd) == EOF)
11864+
{
11865+
err = TRUE;
11866+
break;
11867+
}
11868+
if (putc(NL, fd) == EOF)
11869+
{
11870+
err = TRUE;
11871+
break;
11872+
}
11873+
}
11874+
}
11875+
else if (argvars[1].v_type == VAR_LIST)
1185011876
{
1185111877
if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL)
1185211878
err = TRUE;
1185311879
}
1185411880
else
1185511881
{
11856-
size_t len;
11882+
size_t len;
11883+
char_u buf[NUMBUFLEN];
1185711884

1185811885
p = get_tv_string_buf_chk(&argvars[1], buf);
1185911886
if (p == NULL)

src/testdir/Make_all.mak

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ NEW_TESTS = test_arglist.res \
184184
test_stat.res \
185185
test_substitute.res \
186186
test_syntax.res \
187+
test_system.res \
187188
test_textobjects.res \
188189
test_undo.res \
189190
test_usercommands.res \

src/testdir/test_system.vim

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
" Tests for system() and systemlist()
2+
3+
function! Test_System()
4+
if !executable('echo') || !executable('cat') || !executable('wc')
5+
return
6+
endif
7+
call assert_equal("123\n", system('echo 123'))
8+
call assert_equal(['123'], systemlist('echo 123'))
9+
call assert_equal('123', system('cat', '123'))
10+
call assert_equal(['123'], systemlist('cat', '123'))
11+
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
12+
new Xdummy
13+
call setline(1, ['asdf', "pw\<NL>er", 'xxxx'])
14+
call assert_equal("3\n", system('wc -l', bufnr('%')))
15+
call assert_equal(['3'], systemlist('wc -l', bufnr('%')))
16+
call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], systemlist('cat', bufnr('%')))
17+
bwipe!
18+
19+
call assert_fails('call system("wc -l", 99999)', 'E86:')
20+
endfunction

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
151,
767769
/**/
768770
150,
769771
/**/

0 commit comments

Comments
 (0)