vim-patch:8.1.1418: win_execute() is not implemented yet

Problem:    Win_execute() is not implemented yet.
Solution:   Implement it.
868b7b6712
This commit is contained in:
jing 2021-04-24 23:09:31 +08:00
parent bb7d3790bf
commit f6518e5516
5 changed files with 85 additions and 8 deletions

View File

@ -2498,6 +2498,8 @@ visualmode([expr]) String last visual mode used
wait({timeout}, {condition}[, {interval}])
Number Wait until {condition} is satisfied
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_gettype([{nr}]) String type of window {nr}
@ -3616,6 +3618,8 @@ execute({command} [, {silent}]) *execute()*
Note: If nested, an outer execute() will not observe output of
the inner calls.
Note: Text attributes (highlights) are not captured.
To execute a command in another window than the current one
use `win_execute()`.
exepath({expr}) *exepath()*
Returns the full path of {expr} if it is an executable and
@ -9477,6 +9481,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

View File

@ -390,6 +390,7 @@ return {
visualmode={args={0, 1}},
wait={args={2,3}},
wildmenumode={},
win_execute={args={2, 3}},
win_findbuf={args=1},
win_getid={args={0,2}},
win_gettype={args={0,1}},

View File

@ -1953,8 +1953,8 @@ static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
return (char_u *)(s == NULL ? NULL : xstrdup(s));
}
// "execute(command)" function
static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void execute_common(typval_T *argvars, typval_T *rettv, FunPtr fptr,
int arg_off)
{
const int save_msg_silent = msg_silent;
const int save_emsg_silent = emsg_silent;
@ -1968,9 +1968,9 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
if (argvars[1].v_type != VAR_UNKNOWN) {
if (argvars[arg_off + 1].v_type != VAR_UNKNOWN) {
char buf[NUMBUFLEN];
const char *const s = tv_get_string_buf_chk(&argvars[1], buf);
const char *const s = tv_get_string_buf_chk(&argvars[arg_off + 1], buf);
if (s == NULL) {
return;
@ -1997,10 +1997,10 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
msg_col = 0; // prevent leading spaces
}
if (argvars[0].v_type != VAR_LIST) {
do_cmdline_cmd(tv_get_string(&argvars[0]));
} else if (argvars[0].vval.v_list != NULL) {
list_T *const list = argvars[0].vval.v_list;
if (argvars[arg_off].v_type != VAR_LIST) {
do_cmdline_cmd(tv_get_string(&argvars[arg_off]));
} else if (argvars[arg_off].vval.v_list != NULL) {
list_T *const list = argvars[arg_off].vval.v_list;
tv_list_ref(list);
GetListLineCookie cookie = {
.l = list,
@ -2032,6 +2032,30 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
capture_ga = save_capture_ga;
}
// "execute(command)" function
static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
execute_common(argvars, rettv, fptr, 0);
}
// "win_execute(win_id, command)" function
static void f_win_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp = win_id2wp(argvars);
win_T *save_curwin = curwin;
if (wp != NULL) {
curwin = wp;
curbuf = curwin->w_buffer;
check_cursor();
execute_common(argvars, rettv, fptr, 1);
if (win_valid(save_curwin)) {
curwin = save_curwin;
curbuf = curwin->w_buffer;
}
}
}
/// "exepath()" function
static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{

View File

@ -82,3 +82,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

View File

@ -62,6 +62,24 @@ describe('float window', function()
eq(1000, funcs.win_getid())
end)
it('win_execute() should work' , function()
local buf = meths.create_buf(false, false)
meths.buf_set_lines(buf, 0, -1, true, {'the floatwin'})
local win = meths.open_win(buf, false, {relative='win', width=16, height=1, row=0, col=10})
local line = funcs.win_execute(win, 'echo getline(1)')
eq('\nthe floatwin', line)
funcs.win_execute(win, 'bwipe!')
end)
it('win_execute() call commands that not allowed' , function()
local buf = meths.create_buf(false, false)
meths.buf_set_lines(buf, 0, -1, true, {'the floatwin'})
local win = meths.open_win(buf, true, {relative='win', width=16, height=1, row=0, col=10})
eq(pcall_err(funcs.win_execute, win, 'close'), 'Vim(close):E37: No write since last change (add ! to override)')
eq(pcall_err(funcs.win_execute, win, 'bdelete'), 'Vim(bdelete):E89: No write since last change for buffer 2 (add ! to override)')
funcs.win_execute(win, 'bwipe!')
end)
it('closed immediately by autocmd #11383', function()
eq('Error executing lua: [string "<nvim>"]:0: Window was closed immediately',
pcall_err(exec_lua, [[