patch 8.1.1553: not easy to change the text in a popup window
Problem: Not easy to change the text in a popup window.
Solution: Add popup_settext(). (Ben Jackson, closes #4549)
Also display a space for an empty popup.
diff --git a/src/evalfunc.c b/src/evalfunc.c
index d371c28..8c8bb4d 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -822,6 +822,7 @@
{"popup_hide", 1, 1, f_popup_hide},
{"popup_move", 2, 2, f_popup_move},
{"popup_notification", 2, 2, f_popup_notification},
+ {"popup_settext", 2, 2, f_popup_settext},
{"popup_show", 1, 1, f_popup_show},
#endif
#ifdef FEAT_FLOAT
diff --git a/src/popupwin.c b/src/popupwin.c
index c0b5e13..99ef290 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -601,8 +601,10 @@
wp->w_topline = wp->w_buffer->b_ml.ml_line_count;
// Compute width based on longest text line and the 'wrap' option.
+ // Use a minimum width of one, so that something shows when there is no
+ // text.
// TODO: more accurate wrapping
- wp->w_width = 0;
+ wp->w_width = 1;
for (lnum = wp->w_topline; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum)
{
int len = vim_strsize(ml_get_buf(wp->w_buffer, lnum, FALSE));
@@ -704,6 +706,48 @@
} create_type_T;
/*
+ * Make "buf" empty and set the contents to "text".
+ * Used by popup_create() and popup_settext().
+ */
+ static void
+popup_set_buffer_text(buf_T *buf, typval_T text)
+{
+ int lnum;
+
+ // Clear the buffer, then replace the lines.
+ curbuf = buf;
+ for (lnum = buf->b_ml.ml_line_count; lnum > 0; --lnum)
+ ml_delete(lnum, FALSE);
+ curbuf = curwin->w_buffer;
+
+ // Add text to the buffer.
+ if (text.v_type == VAR_STRING)
+ {
+ // just a string
+ ml_append_buf(buf, 0, text.vval.v_string, (colnr_T)0, TRUE);
+ }
+ else
+ {
+ list_T *l = text.vval.v_list;
+
+ if (l->lv_len > 0)
+ {
+ if (l->lv_first->li_tv.v_type == VAR_STRING)
+ // list of strings
+ add_popup_strings(buf, l);
+ else
+ // list of dictionaries
+ add_popup_dicts(buf, l);
+ }
+ }
+
+ // delete the line that was in the empty buffer
+ curbuf = buf;
+ ml_delete(buf->b_ml.ml_line_count, FALSE);
+ curbuf = curwin->w_buffer;
+}
+
+/*
* popup_create({text}, {options})
* popup_atcursor({text}, {options})
*/
@@ -789,31 +833,7 @@
// TODO: find tab page "nr"
emsg("Not implemented yet");
- // Add text to the buffer.
- if (argvars[0].v_type == VAR_STRING)
- {
- // just a string
- ml_append_buf(buf, 0, argvars[0].vval.v_string, (colnr_T)0, TRUE);
- }
- else
- {
- list_T *l = argvars[0].vval.v_list;
-
- if (l->lv_len > 0)
- {
- if (l->lv_first->li_tv.v_type == VAR_STRING)
- // list of strings
- add_popup_strings(buf, l);
- else
- // list of dictionaries
- add_popup_dicts(buf, l);
- }
- }
-
- // Delete the line of the empty buffer.
- curbuf = buf;
- ml_delete(buf->b_ml.ml_line_count, FALSE);
- curbuf = curwin->w_buffer;
+ popup_set_buffer_text(buf, argvars[0]);
if (type == TYPE_ATCURSOR)
{
@@ -1112,6 +1132,22 @@
}
}
+/*
+ * popup_settext({id}, {text})
+ */
+ void
+f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED)
+{
+ int id = (int)tv_get_number(&argvars[0]);
+ win_T *wp = find_popup_win(id);
+
+ if (wp != NULL)
+ {
+ popup_set_buffer_text(wp->w_buffer, argvars[1]);
+ popup_adjust_position(wp);
+ }
+}
+
static void
popup_free(win_T *wp)
{
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index 6e93791..e026506 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -14,6 +14,7 @@
void f_popup_close(typval_T *argvars, typval_T *rettv);
void f_popup_hide(typval_T *argvars, typval_T *rettv);
void f_popup_show(typval_T *argvars, typval_T *rettv);
+void f_popup_settext(typval_T *argvars, typval_T *rettv);
void popup_close(int id);
void popup_close_tabpage(tabpage_T *tp, int id);
void close_all_popups(void);
diff --git a/src/testdir/dumps/Test_popup_settext_01.dump b/src/testdir/dumps/Test_popup_settext_01.dump
new file mode 100644
index 0000000..768c1bd
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_settext_01.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @28|t+0#0000001#ffd7ff255|h|i|s| |i|s| |a| |t|e|x|t| +0#4040ff13#ffffff0@30
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_settext_02.dump b/src/testdir/dumps/Test_popup_settext_02.dump
new file mode 100644
index 0000000..565e97f
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_settext_02.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @35| +0#0000001#ffd7ff255| +0#4040ff13#ffffff0@36
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t@1|e|x|t|(|p|,| |'@1|)| @30|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_settext_03.dump b/src/testdir/dumps/Test_popup_settext_03.dump
new file mode 100644
index 0000000..b2c0504
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_settext_03.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @35|a+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@36
+|~| @35|b+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@36
+|~| @35|c+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@36
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t@1|e|x|t|(|p|,| |[|'|a|'|,|'|b|'|,|'|c|'|]|)| @19|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_settext_04.dump b/src/testdir/dumps/Test_popup_settext_04.dump
new file mode 100644
index 0000000..8e20916
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_settext_04.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @35|a+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@36
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t@1|e|x|t|(|p|,| |[|'|a|'|]|)| @27|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_settext_05.dump b/src/testdir/dumps/Test_popup_settext_05.dump
new file mode 100644
index 0000000..1ae670e
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_settext_05.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @35| +0#0000001#ffd7ff255| +0#4040ff13#ffffff0@36
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t@1|e|x|t|(|p|,| |[|]|)| @30|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_popup_settext_06.dump b/src/testdir/dumps/Test_popup_settext_06.dump
new file mode 100644
index 0000000..99c32c8
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_settext_06.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @33|a+0#0000001#ffd7ff255@3| +0#4040ff13#ffffff0@35
+|~| @33|b+0#0000001#ffd7ff255@3| +0#4040ff13#ffffff0@35
+|~| @33|c+0#0000001#ffd7ff255@3| +0#4040ff13#ffffff0@35
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index ae41512..ebe2400 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -916,13 +916,13 @@
let winid = popup_create('', {'padding': [2,2,2,2]})
redraw
let pos = popup_getpos(winid)
- call assert_equal(4, pos.width)
+ call assert_equal(5, pos.width)
call assert_equal(5, pos.height)
let winid = popup_create([], {'border': []})
redraw
let pos = popup_getpos(winid)
- call assert_equal(2, pos.width)
+ call assert_equal(3, pos.width)
call assert_equal(3, pos.height)
endfunc
@@ -1231,3 +1231,47 @@
call StopVimInTerminal(buf)
call delete('XtestNotifications')
endfunc
+
+function Test_popup_settext()
+ if !CanRunVimInTerminal()
+ throw 'Skipped: cannot make screendumps'
+ endif
+
+ let lines =<< trim END
+ let opts = {'wrap': 0}
+ let p = popup_create('test', opts)
+ call popup_settext(p, 'this is a text')
+ END
+
+ call writefile( lines, 'XtestPopupSetText' )
+ let buf = RunVimInTerminal('-S XtestPopupSetText', {'rows': 10})
+ call VerifyScreenDump(buf, 'Test_popup_settext_01', {})
+
+ " Setting to empty string clears it
+ call term_sendkeys(buf, ":call popup_settext(p, '')\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_settext_02', {})
+
+ " Setting a list
+ call term_sendkeys(buf, ":call popup_settext(p, ['a','b','c'])\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_settext_03', {})
+
+ " Shrinking with a list
+ call term_sendkeys(buf, ":call popup_settext(p, ['a'])\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_settext_04', {})
+
+ " Growing with a list
+ call term_sendkeys(buf, ":call popup_settext(p, ['a','b','c'])\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_settext_03', {})
+
+ " Empty list clears
+ call term_sendkeys(buf, ":call popup_settext(p, [])\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_settext_05', {})
+
+ " Dicts
+ call term_sendkeys(buf, ":call popup_settext(p, [{'text': 'aaaa'}, {'text': 'bbbb'}, {'text': 'cccc'}])\<CR>")
+ call VerifyScreenDump(buf, 'Test_popup_settext_06', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('XtestPopupSetText')
+endfunction
diff --git a/src/version.c b/src/version.c
index f960d52..aa11b7e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -778,6 +778,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1553,
+/**/
1552,
/**/
1551,