diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt index 1ad4fb9f07e0d2..5ced5bd4e19063 100644 --- a/runtime/doc/popup.txt +++ b/runtime/doc/popup.txt @@ -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 @@ -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 @@ -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: @@ -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') diff --git a/runtime/doc/tags b/runtime/doc/tags index 3665fd3eefcd12..60c7613866b5dd 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -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()* diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 60d0d1e60e5a2c..a54a991f1364d2 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -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 diff --git a/src/evalfunc.c b/src/evalfunc.c index 9720691b448acb..7aad50bfc83dc3 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -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}; @@ -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, diff --git a/src/popupwin.c b/src/popupwin.c index 38c1c9e0d0b5c6..ead5e86da53946 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -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) { diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro index 1ff995085afcd0..11679c68ee0777 100644 --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -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); diff --git a/src/testdir/dumps/Test_popup_beval_3.dump.failed b/src/testdir/dumps/Test_popup_beval_3.dump.failed new file mode 100644 index 00000000000000..1db2d0055f41aa --- /dev/null +++ b/src/testdir/dumps/Test_popup_beval_3.dump.failed @@ -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| diff --git a/src/testdir/dumps/Test_popup_setbuf_01.dump b/src/testdir/dumps/Test_popup_setbuf_01.dump new file mode 100644 index 00000000000000..14359bacfe4a25 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_01.dump @@ -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| diff --git a/src/testdir/dumps/Test_popup_setbuf_02.dump b/src/testdir/dumps/Test_popup_setbuf_02.dump new file mode 100644 index 00000000000000..5feb98299d2e00 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_02.dump @@ -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| diff --git a/src/testdir/dumps/Test_popup_setbuf_03.dump b/src/testdir/dumps/Test_popup_setbuf_03.dump new file mode 100644 index 00000000000000..2c49576dce1ba0 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_03.dump @@ -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 diff --git a/src/testdir/dumps/Test_popup_setbuf_04.dump b/src/testdir/dumps/Test_popup_setbuf_04.dump new file mode 100644 index 00000000000000..937fa7c3c2f834 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_04.dump @@ -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 diff --git a/src/testdir/dumps/Test_popup_setbuf_05.dump b/src/testdir/dumps/Test_popup_setbuf_05.dump new file mode 100644 index 00000000000000..a13dfe35eee0be --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_05.dump @@ -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 diff --git a/src/testdir/dumps/Test_popup_setbuf_06.dump b/src/testdir/dumps/Test_popup_setbuf_06.dump new file mode 100644 index 00000000000000..937fa7c3c2f834 --- /dev/null +++ b/src/testdir/dumps/Test_popup_setbuf_06.dump @@ -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 diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim index a397f70752dd9b..9bb9b78ad058f9 100644 --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -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')\") + call VerifyScreenDump(buf, 'Test_popup_setbuf_02', {}) + + " Error + call term_sendkeys(buf, ":call popup_setbuf(p, ['a','b','c'])\") + call VerifyScreenDump(buf, 'Test_popup_setbuf_03', {}) + + " Set to help window + call term_sendkeys(buf, ":help\") + call term_sendkeys(buf, ":call popup_setbuf(p, 'help.txt')\") + call VerifyScreenDump(buf, 'Test_popup_setbuf_04', {}) + + " Setting back to original buffer + call term_sendkeys(buf, ":call popup_setbuf(p, buf)\") + call VerifyScreenDump(buf, 'Test_popup_setbuf_05', {}) + + " use method + call term_sendkeys(buf, ":echo p->popup_setbuf('help.txt')\") + call VerifyScreenDump(buf, 'Test_popup_setbuf_06', {}) + + call term_sendkeys(buf, ":echo p->popup_setbuf(buf)\") + 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 diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 6b1a50d4169ab2..9adb7a58575ed4 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -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', 'E1210: Number required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['popup_setbuf(1, [])'], ['E1013: Argument 2: type mismatch, expected string but got list', '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'])