# HG changeset patch # User Bram Moolenaar # Date 1559159105 -7200 # Node ID 6699c03347d283a5c5bd30a52e7c9b412f1c8e96 # Parent 74537e143a88f2d9640b265a810698ab63b0b8f4 patch 8.1.1418: win_execute() is not implemented yet commit https://github.com/vim/vim/commit/868b7b6712ea4f2232eeeae18c5cbbbddf2ee84d Author: Bram Moolenaar Date: Wed May 29 21:44:40 2019 +0200 patch 8.1.1418: win_execute() is not implemented yet Problem: Win_execute() is not implemented yet. Solution: Implement it. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2739,6 +2739,8 @@ values({dict}) List values in {dict} virtcol({expr}) Number screen column of cursor or mark visualmode([expr]) String last visual mode used wildmenumode() Number whether 'wildmenu' mode is active +win_execute({id}, {command} [, {silent}]) + String execute {command} in window {id} win_findbuf({bufnr}) List find windows containing {bufnr} win_getid([{win} [, {tab}]]) Number get window ID for {win} in {tab} win_gotoid({expr}) Number go to window with ID {expr} @@ -4012,7 +4014,10 @@ execute({command} [, {silent}]) *exe To get a list of lines use |split()| on the result: > split(execute('args'), "\n") -< When used recursively the output of the recursive call is not +< To execute a command in another window than the current one + use `win_execute()`. + + When used recursively the output of the recursive call is not included in the output of the higher level call. exepath({expr}) *exepath()* @@ -10310,6 +10315,12 @@ wildmenumode() *wildmenumode()* < (Note, this needs the 'wildcharm' option set appropriately). +win_execute({id}, {command} [, {silent}]) *win_execute()* + Like `execute()` but in the context of window {id}. + The window will temporarily be made the current window, + without triggering autocommands. + Example: > + call win_execute(winid, 'syntax enable') win_findbuf({bufnr}) *win_findbuf()* Returns a list with |window-ID|s for windows that contain diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt --- a/runtime/doc/popup.txt +++ b/runtime/doc/popup.txt @@ -70,6 +70,7 @@ By default the 'wrap' option is set, so there is not enough space, some text may be invisible. + TODO: Example how to use syntax highlighting of a code snippet. @@ -242,14 +243,6 @@ popup_getposition({id}) *popup_getpo positioning mechanism applied. If popup window {id} is not found an empty Dict is returned. -win_execute({id}, {command}) - {not implemented yet} - Like `execute()` but in the context of window {id}. - The window will temporarily be made the current window, - without triggering autocommands. - Example: > - call win_execute(winid, 'syntax enable') -< *:popupclear* *:popupc* :popupc[lear] Emergency solution to a misbehaving plugin: close all popup @@ -274,6 +267,10 @@ better leave them alone. The window does have a cursor position, but the cursor is not displayed. +To execute a command in the context of the popup window and buffer use +`win_execute()`. Example: > + call win_execute(winid, 'syntax enable') + Options can be set on the window with `setwinvar()`, e.g.: > call setwinvar(winid, '&wrap', 0) And options can be set on the buffer with `setbufvar()`, e.g.: > diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -492,6 +492,7 @@ static void f_values(typval_T *argvars, static void f_virtcol(typval_T *argvars, typval_T *rettv); static void f_visualmode(typval_T *argvars, typval_T *rettv); static void f_wildmenumode(typval_T *argvars, typval_T *rettv); +static void f_win_execute(typval_T *argvars, typval_T *rettv); static void f_win_findbuf(typval_T *argvars, typval_T *rettv); static void f_win_getid(typval_T *argvars, typval_T *rettv); static void f_win_gotoid(typval_T *argvars, typval_T *rettv); @@ -1045,6 +1046,7 @@ static struct fst {"virtcol", 1, 1, f_virtcol}, {"visualmode", 0, 1, f_visualmode}, {"wildmenumode", 0, 0, f_wildmenumode}, + {"win_execute", 2, 3, f_win_execute}, {"win_findbuf", 1, 1, f_win_findbuf}, {"win_getid", 0, 2, f_win_getid}, {"win_gotoid", 1, 1, f_win_gotoid}, @@ -3519,7 +3521,7 @@ get_list_line( * "execute()" function */ static void -f_execute(typval_T *argvars, typval_T *rettv) +execute_common(typval_T *argvars, typval_T *rettv, int arg_off) { char_u *cmd = NULL; list_T *list = NULL; @@ -3535,9 +3537,9 @@ f_execute(typval_T *argvars, typval_T *r rettv->vval.v_string = NULL; rettv->v_type = VAR_STRING; - if (argvars[0].v_type == VAR_LIST) - { - list = argvars[0].vval.v_list; + if (argvars[arg_off].v_type == VAR_LIST) + { + list = argvars[arg_off].vval.v_list; if (list == NULL || list->lv_first == NULL) /* empty list, no commands, empty output */ return; @@ -3545,15 +3547,15 @@ f_execute(typval_T *argvars, typval_T *r } else { - cmd = tv_get_string_chk(&argvars[0]); + cmd = tv_get_string_chk(&argvars[arg_off]); if (cmd == NULL) return; } - if (argvars[1].v_type != VAR_UNKNOWN) + if (argvars[arg_off + 1].v_type != VAR_UNKNOWN) { char_u buf[NUMBUFLEN]; - char_u *s = tv_get_string_buf_chk(&argvars[1], buf); + char_u *s = tv_get_string_buf_chk(&argvars[arg_off + 1], buf); if (s == NULL) return; @@ -3621,6 +3623,15 @@ f_execute(typval_T *argvars, typval_T *r } /* + * "execute()" function + */ + static void +f_execute(typval_T *argvars, typval_T *rettv) +{ + execute_common(argvars, rettv, 0); +} + +/* * "exepath()" function */ static void @@ -6097,6 +6108,30 @@ f_getwininfo(typval_T *argvars, typval_T } /* + * "win_execute()" function + */ + static void +f_win_execute(typval_T *argvars, typval_T *rettv) +{ + int id = (int)tv_get_number(argvars); + win_T *wp = win_id2wp(id); + win_T *save_curwin = curwin; + + if (wp != NULL) + { + curwin = wp; + curbuf = curwin->w_buffer; + check_cursor(); + execute_common(argvars, rettv, 1); + if (win_valid(save_curwin)) + { + curwin = save_curwin; + curbuf = curwin->w_buffer; + } + } +} + +/* * "win_findbuf()" function */ static void diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -238,6 +238,7 @@ f_popup_create(typval_T *argvars, typval buf->b_p_ul = -1; // no undo buf->b_p_swf = FALSE; // no swap file buf->b_p_bl = FALSE; // unlisted buffer + buf->b_locked = TRUE; win_init_popup_win(wp, buf); @@ -376,6 +377,7 @@ f_popup_show(typval_T *argvars, typval_T static void popup_free(win_T *wp) { + wp->w_buffer->b_locked = FALSE; if (wp->w_winrow + wp->w_height >= cmdline_row) clear_cmdline = TRUE; win_free_popup(wp); diff --git a/src/testdir/test_execute_func.vim b/src/testdir/test_execute_func.vim --- a/src/testdir/test_execute_func.vim +++ b/src/testdir/test_execute_func.vim @@ -78,3 +78,27 @@ func Test_execute_not_silent() endfor call assert_equal('xyz ', text2) endfunc + +func Test_win_execute() + let thiswin = win_getid() + new + let otherwin = win_getid() + call setline(1, 'the new window') + call win_gotoid(thiswin) + let line = win_execute(otherwin, 'echo getline(1)') + call assert_match('the new window', line) + + if has('textprop') + let popupwin = popup_create('the popup win', {'line': 2, 'col': 3}) + redraw + let line = win_execute(popupwin, 'echo getline(1)') + call assert_match('the popup win', line) + + call assert_fails('call win_execute(popupwin, "bwipe!")', 'E937:') + + call popup_close(popupwin) + endif + + call win_gotoid(otherwin) + bwipe! +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1418, +/**/ 1417, /**/ 1416,