To: vim_dev@googlegroups.com Subject: Patch 7.4.1996 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1996 Problem: Capturing the output of a command takes a few commands. Solution: Add evalcmd(). Files: src/eval.c, runtime/doc/eval.txt, src/testdir/test_alot.vim, src/Makefile, src/testdir/test_evalcmd.vim *** ../vim-7.4.1995/src/eval.c 2016-07-07 14:50:05.083210272 +0200 --- src/eval.c 2016-07-07 17:16:35.744730850 +0200 *************** *** 555,560 **** --- 555,561 ---- static void f_empty(typval_T *argvars, typval_T *rettv); static void f_escape(typval_T *argvars, typval_T *rettv); static void f_eval(typval_T *argvars, typval_T *rettv); + static void f_evalcmd(typval_T *argvars, typval_T *rettv); static void f_eventhandler(typval_T *argvars, typval_T *rettv); static void f_executable(typval_T *argvars, typval_T *rettv); static void f_exepath(typval_T *argvars, typval_T *rettv); *************** *** 1133,1138 **** --- 1134,1140 ---- } static lval_T *redir_lval = NULL; + #define EVALCMD_BUSY (redir_lval == (lval_T *)&redir_lval) static garray_T redir_ga; /* only valid when redir_lval is not NULL */ static char_u *redir_endp = NULL; static char_u *redir_varname = NULL; *************** *** 1250,1255 **** --- 1252,1263 ---- { typval_T tv; + if (EVALCMD_BUSY) + { + redir_lval = NULL; + return; + } + if (redir_lval != NULL) { /* If there was no error: assign the text to the variable. */ *************** *** 8556,8561 **** --- 8564,8570 ---- {"empty", 1, 1, f_empty}, {"escape", 2, 2, f_escape}, {"eval", 1, 1, f_eval}, + {"evalcmd", 1, 1, f_evalcmd}, {"eventhandler", 0, 0, f_eventhandler}, {"executable", 1, 1, f_executable}, {"exepath", 1, 1, f_exepath}, *************** *** 11337,11342 **** --- 11346,11381 ---- } /* + * "evalcmd()" function + */ + static void + f_evalcmd(typval_T *argvars, typval_T *rettv) + { + char_u *s; + + rettv->vval.v_string = NULL; + rettv->v_type = VAR_STRING; + + s = get_tv_string_chk(&argvars[0]); + if (s != NULL) + { + redir_vname = TRUE; + redir_lval = (lval_T *)&redir_lval; + ga_init2(&redir_ga, (int)sizeof(char), 500); + + if (do_cmdline_cmd(s) == OK) + rettv->vval.v_string = redir_ga.ga_data; + else + vim_free(redir_ga.ga_data); + + redir_ga.ga_data = NULL; + redir_vname = FALSE; + redir_lval = NULL; + } + + } + + /* * "eventhandler()" function */ static void *** ../vim-7.4.1995/runtime/doc/eval.txt 2016-07-07 14:50:05.075210391 +0200 --- runtime/doc/eval.txt 2016-07-07 16:57:32.161784835 +0200 *************** *** 1942,1947 **** --- 1961,1967 ---- empty({expr}) Number |TRUE| if {expr} is empty escape({string}, {chars}) String escape {chars} in {string} with '\' eval({string}) any evaluate {string} into its value + evalcmd({command}) String execute {command} and get the output eventhandler() Number |TRUE| if inside an event handler executable({expr}) Number 1 if executable {expr} exists exepath({expr}) String full path of the command {expr} *************** *** 3218,3223 **** --- 3232,3246 ---- them. Also works for |Funcref|s that refer to existing functions. + evalcmd({command}) *evalcmd()* + Execute Ex {command} and return the output as a string. This + is equivalent to: > + redir => var + {command} + redir END + < To get a list of lines use: > + split(evalcmd(cmd), "\n") + eventhandler() *eventhandler()* Returns 1 when inside an event handler. That is that Vim got interrupted while waiting for the user to type a character, *** ../vim-7.4.1995/src/testdir/test_alot.vim 2016-07-07 14:50:05.083210272 +0200 --- src/testdir/test_alot.vim 2016-07-07 17:22:00.619885016 +0200 *************** *** 5,13 **** source test_autocmd.vim source test_cursor_func.vim source test_delete.vim source test_ex_undo.vim - source test_expr.vim source test_expand.vim source test_expand_dllpath.vim source test_feedkeys.vim source test_fnamemodify.vim --- 5,14 ---- source test_autocmd.vim source test_cursor_func.vim source test_delete.vim + source test_evalcmd.vim source test_ex_undo.vim source test_expand.vim + source test_expr.vim source test_expand_dllpath.vim source test_feedkeys.vim source test_fnamemodify.vim *** ../vim-7.4.1995/src/Makefile 2016-07-07 14:50:05.083210272 +0200 --- src/Makefile 2016-07-07 17:23:39.514410212 +0200 *************** *** 2023,2028 **** --- 2023,2029 ---- test_cmdline \ test_cursor_func \ test_delete \ + test_evalcmd \ test_ex_undo \ test_expand \ test_expand_dllpath \ *** ../vim-7.4.1995/src/testdir/test_evalcmd.vim 2016-07-07 17:30:56.287903210 +0200 --- src/testdir/test_evalcmd.vim 2016-07-07 17:26:11.300146914 +0200 *************** *** 0 **** --- 1,8 ---- + " test evalcmd() + + func Test_evalcmd() + call assert_equal("\nnocompatible", evalcmd('set compatible?')) + call assert_equal("\nsomething\nnice", evalcmd('echo "something\nnice"')) + call assert_fails('call evalcmd("doesnotexist")', 'E492:') + endfunc + *** ../vim-7.4.1995/src/version.c 2016-07-07 16:42:57.322788302 +0200 --- src/version.c 2016-07-07 17:22:25.971506938 +0200 *************** *** 760,761 **** --- 760,763 ---- { /* Add new patch number below this line */ + /**/ + 1996, /**/ -- hundred-and-one symptoms of being an internet addict: 219. Your spouse has his or her lawyer deliver the divorce papers... via e-mail. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///