# HG changeset patch # User Christian Brabandt # Date 1483878604 -3600 # Node ID 7232cd9f8a7cd17462809e8d5cbfd0ee768a6337 # Parent 3dd44fd29319168a3a9a63f7c8fae9bbd623895e commit https://github.com/vim/vim/commit/12c4492dd35e0cd83c8816be2ec849b836109882 Author: Bram Moolenaar Date: Sun Jan 8 13:26:03 2017 +0100 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) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -7561,7 +7561,11 @@ system({expr} [, {input}]) *system()* If {input} is given and is a |List| it is written to the file in a way |writefile()| does with {binary} set to "b" (i.e. with a newline between each list item with newlines inside - list items converted to NULs). + list items converted to NULs). + When {input} is given and is a number that is a valid id for + an existing buffer then the content of the buffer is written + to the file line by line, each line terminated by a NL and + NULs characters where the text has a NL. Pipes are not used, the 'shelltemp' option is not used. diff --git a/src/Makefile b/src/Makefile --- a/src/Makefile +++ b/src/Makefile @@ -2164,6 +2164,7 @@ test_arglist \ test_substitute \ test_syn_attr \ test_syntax \ + test_system \ test_tabline \ test_tabpage \ test_tagcase \ diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -11817,7 +11817,6 @@ get_cmd_output_as_rettv( char_u *res = NULL; char_u *p; char_u *infile = NULL; - char_u buf[NUMBUFLEN]; int err = FALSE; FILE *fd; list_T *list = NULL; @@ -11831,7 +11830,7 @@ get_cmd_output_as_rettv( if (argvars[1].v_type != VAR_UNKNOWN) { /* - * Write the string to a temp file, to be used for input of the shell + * Write the text to a temp file, to be used for input of the shell * command. */ if ((infile = vim_tempname('i', TRUE)) == NULL) @@ -11846,14 +11845,42 @@ get_cmd_output_as_rettv( EMSG2(_(e_notopen), infile); goto errret; } - if (argvars[1].v_type == VAR_LIST) + if (argvars[1].v_type == VAR_NUMBER) + { + linenr_T lnum; + buf_T *buf; + + buf = buflist_findnr(argvars[1].vval.v_number); + if (buf == NULL) + { + EMSGN(_(e_nobufnr), argvars[1].vval.v_number); + goto errret; + } + + for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) + { + for (p = ml_get_buf(buf, lnum, FALSE); *p != NUL; ++p) + if (putc(*p == '\n' ? NUL : *p, fd) == EOF) + { + err = TRUE; + break; + } + if (putc(NL, fd) == EOF) + { + err = TRUE; + break; + } + } + } + else if (argvars[1].v_type == VAR_LIST) { if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL) err = TRUE; } else { - size_t len; + size_t len; + char_u buf[NUMBUFLEN]; p = get_tv_string_buf_chk(&argvars[1], buf); if (p == NULL) diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -184,6 +184,7 @@ NEW_TESTS = test_arglist.res \ test_stat.res \ test_substitute.res \ test_syntax.res \ + test_system.res \ test_textobjects.res \ test_undo.res \ test_usercommands.res \ diff --git a/src/testdir/test_system.vim b/src/testdir/test_system.vim new file mode 100644 --- /dev/null +++ b/src/testdir/test_system.vim @@ -0,0 +1,20 @@ +" Tests for system() and systemlist() + +function! Test_System() + if !executable('echo') || !executable('cat') || !executable('wc') + return + endif + call assert_equal("123\n", system('echo 123')) + call assert_equal(['123'], systemlist('echo 123')) + call assert_equal('123', system('cat', '123')) + call assert_equal(['123'], systemlist('cat', '123')) + call assert_equal(["as\df"], systemlist('cat', ["as\df"])) + new Xdummy + call setline(1, ['asdf', "pw\er", 'xxxx']) + call assert_equal("3\n", system('wc -l', bufnr('%'))) + call assert_equal(['3'], systemlist('wc -l', bufnr('%'))) + call assert_equal(['asdf', "pw\er", 'xxxx'], systemlist('cat', bufnr('%'))) + bwipe! + + call assert_fails('call system("wc -l", 99999)', 'E86:') +endfunction diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 151, +/**/ 150, /**/ 149,