Skip to content

Commit

Permalink
Problem: cannot change buffer in a popup
Browse files Browse the repository at this point in the history
related: vim#15006

Problem:  cannot change buffer in a popup
Solution: add popup_setbuf() function
  • Loading branch information
chrisbra committed Jun 16, 2024
1 parent 0ddab58 commit fb5d02d
Show file tree
Hide file tree
Showing 15 changed files with 194 additions and 3 deletions.
19 changes: 16 additions & 3 deletions runtime/doc/popup.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*popup.txt* For Vim version 9.1. Last change: 2024 Jun 08
*popup.txt* For Vim version 9.1. Last change: 2024 Jun 16


VIM REFERENCE MANUAL by Bram Moolenaar
Expand Down Expand Up @@ -186,6 +186,7 @@ Manipulating a popup window:
|popup_move()| change the position and size of a popup
|popup_setoptions()| override options of a popup
|popup_settext()| replace the popup buffer contents
|popup_setbuf()| replace the popup buffer contents

Closing popup windows:
|popup_close()| close one popup
Expand Down Expand Up @@ -574,6 +575,18 @@ popup_notification({what}, {options}) *popup_notification()*
Return type: |Number|


popup_setbuf({id}, {buf}) *popup_setbuf()*
Set buffer {buf} to be displayed in popup win {id}. For the
use of {buf}, see |bufname()| function.
Does not change the window size or position, other than caused
by the different text.

Can also be used as a |method|: >
GetPopup()->popup_setbuf(bufnr('foobar'))
<
Return type: |Number|


popup_setoptions({id}, {options}) *popup_setoptions()*
Override options in popup {id} with entries in {options}.
These options can be set:
Expand Down Expand Up @@ -616,8 +629,8 @@ popup_settext({id}, {text}) *popup_settext()*
Set the text of the buffer in popup win {id}. {text} is the
same as supplied to |popup_create()|, except that a buffer
number is not allowed.
Does not change the window size or position, other than caused
by the different text.
May change window size or position to adjust for the size
of the buffer text.

Can also be used as a |method|: >
GetPopup()->popup_settext('hello')
Expand Down
1 change: 1 addition & 0 deletions runtime/doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -9431,6 +9431,7 @@ popup_menu() popup.txt /*popup_menu()*
popup_menu-shortcut-example popup.txt /*popup_menu-shortcut-example*
popup_move() popup.txt /*popup_move()*
popup_notification() popup.txt /*popup_notification()*
popup_setbuf() popup.txt /*popup_setbuf()*
popup_setoptions() popup.txt /*popup_setoptions()*
popup_settext() popup.txt /*popup_settext()*
popup_show() popup.txt /*popup_show()*
Expand Down
1 change: 1 addition & 0 deletions runtime/doc/usr_41.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,7 @@ Popup window: *popup-window-functions*
popup_move() change the position and size of a popup
popup_setoptions() override options of a popup
popup_settext() replace the popup buffer contents
popup_setbuf() set the popup buffer
popup_close() close one popup
popup_clear() close all popups
popup_filter_menu() select from a list of items
Expand Down
3 changes: 3 additions & 0 deletions src/evalfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,7 @@ static argcheck_T arg2_number_bool[] = {arg_number, arg_bool};
static argcheck_T arg2_number_dict_any[] = {arg_number, arg_dict_any};
static argcheck_T arg2_number_list[] = {arg_number, arg_list_any};
static argcheck_T arg2_number_string[] = {arg_number, arg_string};
static argcheck_T arg2_number_buffer[] = {arg_number, arg_buffer};
static argcheck_T arg2_number_string_or_list[] = {arg_number, arg_string_or_list_any};
static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any};
static argcheck_T arg2_string[] = {arg_string, arg_string};
Expand Down Expand Up @@ -2421,6 +2422,8 @@ static funcentry_T global_functions[] =
ret_void, PROP_FUNC(f_popup_move)},
{"popup_notification", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict,
ret_number, PROP_FUNC(f_popup_notification)},
{"popup_setbuf", 2, 2, FEARG_1, arg2_number_buffer,
ret_void, PROP_FUNC(f_popup_setbuf)},
{"popup_setoptions", 2, 2, FEARG_1, arg2_number_dict_any,
ret_void, PROP_FUNC(f_popup_setoptions)},
{"popup_settext", 2, 2, FEARG_1, arg2_number_string_or_list,
Expand Down
45 changes: 45 additions & 0 deletions src/popupwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -2844,6 +2844,51 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED)
popup_adjust_position(wp);
}

/*
* popup_setbuf({id}, {bufnr})
*/
void
f_popup_setbuf(typval_T *argvars, typval_T *rettv UNUSED)
{
int id;
win_T *wp;
buf_T *buf;

if (in_vim9script()
&& (check_for_number_arg(argvars, 0) == FAIL
|| check_for_buffer_arg(argvars, 1) == FAIL))
return;

if (check_for_buffer_arg(argvars, 1) == FAIL)
return;

id = (int)tv_get_number(&argvars[0]);
wp = find_popup_win(id);
if (wp == NULL)
return;

buf = tv_get_buf_from_arg(&argvars[1]);

if (buf == NULL)
return;
#ifdef FEAT_TERMINAL
else if (buf->b_term != NULL && popup_terminal_exists())
{
emsg(_(e_cannot_open_second_popup_with_terminal));
return NULL;
}
#endif

wp->w_buffer->b_nwindows--;
win_init_popup_win(wp, buf);
set_local_options_default(wp, FALSE);
swap_exists_action = SEA_READONLY;
buffer_ensure_loaded(buf);
swap_exists_action = SEA_NONE;
redraw_win_later(wp, UPD_NOT_VALID);
popup_adjust_position(wp);
}

static void
popup_free(win_T *wp)
{
Expand Down
1 change: 1 addition & 0 deletions src/proto/popupwin.pro
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void f_popup_hide(typval_T *argvars, typval_T *rettv);
void popup_show(win_T *wp);
void f_popup_show(typval_T *argvars, typval_T *rettv);
void f_popup_settext(typval_T *argvars, typval_T *rettv);
void f_popup_setbuf(typval_T *argvars, typval_T *rettv);
int error_if_popup_window(int also_with_term);
int popup_close(int id, int force);
int popup_close_tabpage(tabpage_T *tp, int id, int force);
Expand Down
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popup_beval_3.dump.failed
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
|1+0&#ffffff0| @73
>2| @73
|3| @73
|4| @10|t+0#0000001#ffd7ff255|e|x|t| +0#0000000#ffffff0@58
|h|e|r|e| |i|s| |s|o|m|e| |t|e|x|t| |t|o| |h|o|v|e|r| |o|v|e|r| @43
|6| @73
|7| @73
|8| @73
|9| @73
|:|c|a|l@1| |M|o|v|e|A|w|a|y|(|)| @40|2|,|1| @10|T|o|p|
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popup_setbuf_01.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
> +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35
|~| @73
|~| @73
|~| @73
|~| @73
| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popup_setbuf_02.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
> +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35
|~| @73
|~| @73
|~| @73
|~| @73
|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t|b|u|f|(|p|,| |'|f|o@1|b|a|r|.|t|x|t|'|)| @21|0|,|0|-|1| @8|A|l@1|
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popup_setbuf_03.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
|~+0#4040ff13#ffffff0| @73
|~| @73
|~| @73
|~| @33|t+0#0000001#ffd7ff255|e|s|t| +0#4040ff13#ffffff0@35
|~| @73
|~| @73
|~| @73
|~| @73
|E+0#ffffff16#e000002|1|2@1|0|:| |S|t|r|i|n|g| |o|r| |N|u|m|b|e|r| |r|e|q|u|i|r|e|d| |f|o|r| |a|r|g|u|m|e|n|t| |2| +0#0000000#ffffff0@27
|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popup_setbuf_04.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001
| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255
|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popup_setbuf_05.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
>h+0#e000002#ffffff0|e|l|p|.|t|x|t| +0#0000000&@7|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000000&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @12
@75
@24|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @30
@73|k|
@6|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e| +0#0000001#ffd7ff255|s+0#0000000#ffffff0|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @2
|l| @73
|h+3&&|e|l|p|.|t|x|t| |[|H|e|l|p|]|[|R|O|]| @37|1|,|1| @11|T|o|p
| +0&&@74
|[+1&&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1
| +0&&@74
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popup_setbuf_06.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
>*+0#ffffff16#ffd7ff255|h+0#e000002&|e|l|p|.|t|x|t|*+0#ffffff16&| +0#0000001&@5|F|o|r| |V+0#00e0e07&|i|m| |v|e|r|s|i|o|n| |9|.|1|.| +0#0000001&@1|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7| @11| +0#0000000#0000001
| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@23|V|I|M| |-| |m|a|i|n| |h|e|l|p| |f|i|l|e| @29| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@72|k| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@5|M|o|v|e| |a|r|o|u|n|d|:| @1|U|s|e| |t|h|e| |c|u|r|s|o|r| |k|e|y|s|,| |o|r| |"|h|"| |t|o| |g|o| |l|e|f|t|,| @11|h| @1| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255|l| @71| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@19|"|j|"| |t|o| |g|o| |d|o|w|n|,| |"|k|"| |t|o| |g|o| |u|p|,| |"|l|"| |t|o| |g|o| |r|i|g|h|t|.| @6|j| +0#0000000#a8a8a8255
|C+0#0000001#ffd7ff255|l|o|s|e| |t|h|i|s| |w|i|n|d|o|w|:| @1|U|s|e| |"|:|q|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&|.| @37| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@2|G|e|t| |o|u|t| |o|f| |V|i|m|:| @1|U|s|e| |"|:|q|a|!|<+0#e000e06&|E|n|t|e|r|>|"+0#0000001&| |(|c|a|r|e|f|u|l|,| |a|l@1| |c|h|a|n|g|e|s| |a|r|e| |l|o|s|t|!|)|.| @2| +0#0000000#a8a8a8255
| +0#0000001#ffd7ff255@73| +0#0000000#a8a8a8255
52 changes: 52 additions & 0 deletions src/testdir/test_popupwin.vim
Original file line number Diff line number Diff line change
Expand Up @@ -2499,6 +2499,58 @@ func Test_popup_settext_null()
call popup_close(id)
endfunc

func Test_popup_setbuf()
CheckScreendump

let lines =<< trim END
let opts = #{wrap: 0}
let p = popup_create('test', opts)
let buf = bufnr('%')
END

call writefile(lines, 'XtestPopupSetBuf')
"call writefile(lines, 'XtestPopupSetBuf', 'D')
let buf = RunVimInTerminal('-S XtestPopupSetBuf', #{rows: 10})
call VerifyScreenDump(buf, 'Test_popup_setbuf_01', {})

" Setting to an non-existing buffer doesn't do anything
call term_sendkeys(buf, ":call popup_setbuf(p, 'foobar.txt')\<CR>")
call VerifyScreenDump(buf, 'Test_popup_setbuf_02', {})

" Error
call term_sendkeys(buf, ":call popup_setbuf(p, ['a','b','c'])\<CR>")
call VerifyScreenDump(buf, 'Test_popup_setbuf_03', {})

" Set to help window
call term_sendkeys(buf, ":help\<CR>")
call term_sendkeys(buf, ":call popup_setbuf(p, 'help.txt')\<CR>")
call VerifyScreenDump(buf, 'Test_popup_setbuf_04', {})

" Setting back to original buffer
call term_sendkeys(buf, ":call popup_setbuf(p, buf)\<CR>")
call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {})

" use method
call term_sendkeys(buf, ":echo p->popup_setbuf('help.txt')\<CR>")
call VerifyScreenDump(buf, 'Test_popup_setbuf_06', {})

call term_sendkeys(buf, ":echo p->popup_setbuf(buf)\<CR>")
call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {})

" clean up
call StopVimInTerminal(buf)
endfunc

func Test_popup_setbuf_null()
let id = popup_create('', {})
call popup_setbuf(id, -1)
call popup_close(id)

let id = popup_create('', {})
call popup_settext(id, test_null_string())
call popup_close(id)
endfunc

func Test_popup_hidden()
new

Expand Down
5 changes: 5 additions & 0 deletions src/testdir/test_vim9_builtin.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3152,6 +3152,11 @@ def Test_popup_settext()
v9.CheckSourceDefAndScriptFailure(['popup_settext(1, 2)'], ['E1013: Argument 2: type mismatch, expected string but got number', 'E1222: String or List required for argument 2'])
enddef

def Test_popup_setbuf()
v9.CheckSourceDefAndScriptFailure(['popup_setbuf([], "abc")'], ['E1013: Argument 1: type mismatch, expected number but got list<any>', 'E1210: Number required for argument 1'])
v9.CheckSourceDefAndScriptFailure(['popup_setbuf(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list<any>', 'E1220: String or Number required for argument 2'])
enddef

def Test_popup_show()
v9.CheckSourceDefAndScriptFailure(['popup_show("a")'], ['E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1'])
v9.CheckSourceDefAndScriptFailure(['popup_show(true)'], ['E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1'])
Expand Down

0 comments on commit fb5d02d

Please sign in to comment.