0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.1.1407: popup_create() does not support text properties

Problem:    Popup_create() does not support text properties.
Solution:   Support the third form of the text argument.
This commit is contained in:
Bram Moolenaar
2019-05-26 23:32:06 +02:00
parent 2cd0dce898
commit 7a8d0278bd
10 changed files with 162 additions and 49 deletions

View File

@@ -279,7 +279,6 @@ optionally text properties. It is in one of three forms:
- a string - a string
- a list of strings - a list of strings
- a list of dictionaries, where each dictionary has these entries: - a list of dictionaries, where each dictionary has these entries:
{not implemented yet}
text String with the text to display. text String with the text to display.
props A list of text properties. Optional. props A list of text properties. Optional.
Each entry is a dictionary, like the third argument of Each entry is a dictionary, like the third argument of
@@ -369,12 +368,16 @@ outside of the Vim window will not be displayed, thus truncated.
POPUP TEXT PROPERTIES *popup-props* POPUP TEXT PROPERTIES *popup-props*
{not implemented yet} These are similar to the third argument of |prop_add()| except:
These are similar to the third argument of |prop_add()|, but not exactly the - "lnum" is always the current line in the list
same, since they only apply to one line. - "bufnr" is always the buffer of the popup
- "col" is in the Dict instead of a separate argument
- "transparent" is extra
So we get:
col starting column, counted in bytes, use one for the col starting column, counted in bytes, use one for the
first column. first column.
length length of text in bytes; can be zero length length of text in bytes; can be zero
end_lnum line number for the end of the text
end_col column just after the text; not used when "length" is end_col column just after the text; not used when "length" is
present; when {col} and "end_col" are equal, this is a present; when {col} and "end_col" are equal, this is a
zero-width text property zero-width text property
@@ -385,6 +388,7 @@ same, since they only apply to one line.
transparent do not show these characters, show the text under it; transparent do not show these characters, show the text under it;
if there is an border character to the right or below if there is an border character to the right or below
it will be made transparent as well it will be made transparent as well
{not implemented yet}
POPUP FILTER *popup-filter* POPUP FILTER *popup-filter*

View File

@@ -59,6 +59,91 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
str, OPT_FREE|OPT_LOCAL, 0); str, OPT_FREE|OPT_LOCAL, 0);
} }
/*
* Add lines to the popup from a list of strings.
*/
static void
add_popup_strings(buf_T *buf, list_T *l)
{
listitem_T *li;
linenr_T lnum = 0;
char_u *p;
for (li = l->lv_first; li != NULL; li = li->li_next)
if (li->li_tv.v_type == VAR_STRING)
{
p = li->li_tv.vval.v_string;
ml_append_buf(buf, lnum++,
p == NULL ? (char_u *)"" : p, (colnr_T)0, TRUE);
}
}
/*
* Add lines to the popup from a list of dictionaries.
*/
static void
add_popup_dicts(buf_T *buf, list_T *l)
{
listitem_T *li;
listitem_T *pli;
linenr_T lnum = 0;
char_u *p;
dict_T *dict;
// first add the text lines
for (li = l->lv_first; li != NULL; li = li->li_next)
{
if (li->li_tv.v_type != VAR_DICT)
{
emsg(_(e_dictreq));
return;
}
dict = li->li_tv.vval.v_dict;
p = dict == NULL ? NULL
: dict_get_string(dict, (char_u *)"text", FALSE);
ml_append_buf(buf, lnum++,
p == NULL ? (char_u *)"" : p, (colnr_T)0, TRUE);
}
// add the text properties
lnum = 1;
for (li = l->lv_first; li != NULL; li = li->li_next, ++lnum)
{
dictitem_T *di;
list_T *plist;
dict = li->li_tv.vval.v_dict;
di = dict_find(dict, (char_u *)"props", -1);
if (di != NULL)
{
if (di->di_tv.v_type != VAR_LIST)
{
emsg(_(e_listreq));
return;
}
plist = di->di_tv.vval.v_list;
if (plist != NULL)
{
for (pli = plist->lv_first; pli != NULL; pli = pli->li_next)
{
if (pli->li_tv.v_type != VAR_DICT)
{
emsg(_(e_dictreq));
return;
}
dict = pli->li_tv.vval.v_dict;
if (dict != NULL)
{
int col = dict_get_number(dict, (char_u *)"col");
prop_add_common( lnum, col, dict, buf, NULL);
}
}
}
}
}
}
/* /*
* popup_create({text}, {options}) * popup_create({text}, {options})
*/ */
@@ -128,27 +213,21 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
// Add text to the buffer. // Add text to the buffer.
if (argvars[0].v_type == VAR_STRING) if (argvars[0].v_type == VAR_STRING)
{
// just a string // just a string
ml_append_buf(buf, 0, argvars[0].vval.v_string, (colnr_T)0, TRUE); ml_append_buf(buf, 0, argvars[0].vval.v_string, (colnr_T)0, TRUE);
else if (argvars[0].vval.v_list->lv_first->li_tv.v_type == VAR_STRING)
{
listitem_T *li;
linenr_T lnum = 0;
char_u *p;
// list of strings
for (li = argvars[0].vval.v_list->lv_first; li != NULL;
li = li->li_next)
if (li->li_tv.v_type == VAR_STRING)
{
p = li->li_tv.vval.v_string;
ml_append_buf(buf, lnum++,
p == NULL ? (char_u *)"" : p, (colnr_T)0, TRUE);
}
} }
else else
// TODO: handle a list of dictionaries {
emsg("Not implemented yet"); list_T *l = argvars[0].vval.v_list;
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. // Delete the line of the empty buffer.
curbuf = buf; curbuf = buf;

View File

@@ -1,5 +1,6 @@
/* textprop.c */ /* textprop.c */
void f_prop_add(typval_T *argvars, typval_T *rettv); void f_prop_add(typval_T *argvars, typval_T *rettv);
void prop_add_common(linenr_T start_lnum, colnr_T start_col, dict_T *dict, buf_T *default_buf, typval_T *dict_arg);
int get_text_props(buf_T *buf, linenr_T lnum, char_u **props, int will_change); int get_text_props(buf_T *buf, linenr_T lnum, char_u **props, int will_change);
proptype_T *text_prop_type_by_id(buf_T *buf, int id); proptype_T *text_prop_type_by_id(buf_T *buf, int id);
void f_prop_clear(typval_T *argvars, typval_T *rettv); void f_prop_clear(typval_T *argvars, typval_T *rettv);

View File

@@ -4405,7 +4405,10 @@ win_line(
char_attr = hl_combine_attr(line_attr, search_attr); char_attr = hl_combine_attr(line_attr, search_attr);
# ifdef FEAT_TEXT_PROP # ifdef FEAT_TEXT_PROP
else if (text_prop_type != NULL) else if (text_prop_type != NULL)
char_attr = hl_combine_attr(line_attr, text_prop_attr); {
char_attr = hl_combine_attr(
line_attr != 0 ? line_attr : win_attr, text_prop_attr);
}
# endif # endif
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL) else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|| vcol < fromcol || vcol_prev < fromcol_prev || vcol < fromcol || vcol_prev < fromcol_prev
@@ -4429,7 +4432,8 @@ win_line(
char_attr = hl_combine_attr( char_attr = hl_combine_attr(
syntax_attr, text_prop_attr); syntax_attr, text_prop_attr);
else else
char_attr = text_prop_attr; char_attr = hl_combine_attr(
win_attr, text_prop_attr);
} }
else else
#endif #endif

View File

@@ -2,9 +2,9 @@
> +0#0000000#ffffff0@74 > +0#0000000#ffffff0@74
|~+0#4040ff13&| @73 |~+0#4040ff13&| @73
|~| @6|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @10| +0#4040ff13#ffffff0@46 |~| @6|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @10| +0#4040ff13#ffffff0@46
|~| @6|a+0#0000001#ffd7ff255| |c+0#ff404010&|o|m@1|e|n|t| +0#0000001&|l|i|n|e| @5| +0#4040ff13#ffffff0@46
|~| @73 |~| @73
|~| @73 |~| @73
|~| @73 |~| @73
|~| @73 |~| @73
|~| @73 | +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|c|r|e|a|t|e|(|'|o|t|h|e|r| |t|a|b|'|,| |{|'|l|i|n|e|'|:| |4|,| |'|c|o|l|'|:| |9|}|)| @2|0|,|0|-|1| @8|A|l@1|

View File

@@ -7,4 +7,4 @@
|6| @73 |6| @73
|7| @73 |7| @73
|8| @73 |8| @73
|:|c|a|l@1| |p|o|p|u|p|_|c|r|e|a|t|e|(|'|o|t|h|e|r| |t|a|b|'|,| |{|'|l|i|n|e|'|:| |4|,| |'|c|o| @9|1|,|1| @10|T|o|p| @57|1|,|1| @10|T|o|p|

View File

@@ -2,7 +2,7 @@
|~+0#4040ff13&| @73 |~+0#4040ff13&| @73
|~| @73 |~| @73
|~| @6|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @10| +0#4040ff13#ffffff0@46 |~| @6|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @10| +0#4040ff13#ffffff0@46
|~| @73 |~| @6|a+0#0000001#ffd7ff255| |c+0#ff404010&|o|m@1|e|n|t| +0#0000001&|l|i|n|e| @5| +0#4040ff13#ffffff0@46
|~| @73 |~| @73
|~| @73 |~| @73
|~| @73 |~| @73

View File

@@ -14,6 +14,8 @@ func Test_simple_popup()
\ "call setline(1, range(1, 100))", \ "call setline(1, range(1, 100))",
\ "hi PopupColor1 ctermbg=lightblue", \ "hi PopupColor1 ctermbg=lightblue",
\ "hi PopupColor2 ctermbg=lightcyan", \ "hi PopupColor2 ctermbg=lightcyan",
\ "hi Comment ctermfg=red",
\ "call prop_type_add('comment', {'highlight': 'Comment'})",
\ "let winid = popup_create('hello there', {'line': 3, 'col': 11, 'highlight': 'PopupColor1'})", \ "let winid = popup_create('hello there', {'line': 3, 'col': 11, 'highlight': 'PopupColor1'})",
\ "let winid2 = popup_create(['another one', 'another two', 'another three'], {'line': 3, 'col': 25})", \ "let winid2 = popup_create(['another one', 'another two', 'another three'], {'line': 3, 'col': 25})",
\ "call setwinvar(winid2, '&wincolor', 'PopupColor2')", \ "call setwinvar(winid2, '&wincolor', 'PopupColor2')",
@@ -23,7 +25,12 @@ func Test_simple_popup()
" Add a tabpage " Add a tabpage
call term_sendkeys(buf, ":tabnew\<CR>") call term_sendkeys(buf, ":tabnew\<CR>")
call term_sendkeys(buf, ":call popup_create('other tab', {'line': 4, 'col': 9})\<CR>") call term_sendkeys(buf, ":call popup_create(["
\ .. "{'text': 'other tab'},"
\ .. "{'text': 'a comment line', 'props': [{"
\ .. "'col': 3, 'length': 7, 'type': 'comment'"
\ .. "}]},"
\ .. "], {'line': 4, 'col': 9})\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_02', {}) call VerifyScreenDump(buf, 'Test_popupwin_02', {})
" switch back to first tabpage " switch back to first tabpage

View File

@@ -142,23 +142,8 @@ get_bufnr_from_arg(typval_T *arg, buf_T **buf)
void void
f_prop_add(typval_T *argvars, typval_T *rettv UNUSED) f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
{ {
linenr_T lnum;
linenr_T start_lnum; linenr_T start_lnum;
linenr_T end_lnum;
colnr_T start_col; colnr_T start_col;
colnr_T end_col;
dict_T *dict;
char_u *type_name;
proptype_T *type;
buf_T *buf = curbuf;
int id = 0;
char_u *newtext;
int proplen;
size_t textlen;
char_u *props = NULL;
char_u *newprops;
textprop_T tmp_prop;
int i;
start_lnum = tv_get_number(&argvars[0]); start_lnum = tv_get_number(&argvars[0]);
start_col = tv_get_number(&argvars[1]); start_col = tv_get_number(&argvars[1]);
@@ -172,7 +157,38 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
emsg(_(e_dictreq)); emsg(_(e_dictreq));
return; return;
} }
dict = argvars[2].vval.v_dict;
prop_add_common(start_lnum, start_col, argvars[2].vval.v_dict,
curbuf, &argvars[2]);
}
/*
* Shared between prop_add() and popup_create().
* "dict_arg" is the function argument of a dict containing "bufnr".
* it is NULL for popup_create().
*/
void
prop_add_common(
linenr_T start_lnum,
colnr_T start_col,
dict_T *dict,
buf_T *default_buf,
typval_T *dict_arg)
{
linenr_T lnum;
linenr_T end_lnum;
colnr_T end_col;
char_u *type_name;
proptype_T *type;
buf_T *buf = default_buf;
int id = 0;
char_u *newtext;
int proplen;
size_t textlen;
char_u *props = NULL;
char_u *newprops;
textprop_T tmp_prop;
int i;
if (dict == NULL || dict_find(dict, (char_u *)"type", -1) == NULL) if (dict == NULL || dict_find(dict, (char_u *)"type", -1) == NULL)
{ {
@@ -221,7 +237,7 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
if (dict_find(dict, (char_u *)"id", -1) != NULL) if (dict_find(dict, (char_u *)"id", -1) != NULL)
id = dict_get_number(dict, (char_u *)"id"); id = dict_get_number(dict, (char_u *)"id");
if (get_bufnr_from_arg(&argvars[2], &buf) == FAIL) if (dict_arg != NULL && get_bufnr_from_arg(dict_arg, &buf) == FAIL)
return; return;
type = lookup_prop_type(type_name, buf); type = lookup_prop_type(type_name, buf);
@@ -278,12 +294,12 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
mch_memmove(newtext, buf->b_ml.ml_line_ptr, textlen); mch_memmove(newtext, buf->b_ml.ml_line_ptr, textlen);
// Find the index where to insert the new property. // Find the index where to insert the new property.
// Since the text properties are not aligned properly when stored with the // Since the text properties are not aligned properly when stored with
// text, we need to copy them as bytes before using it as a struct. // the text, we need to copy them as bytes before using it as a struct.
for (i = 0; i < proplen; ++i) for (i = 0; i < proplen; ++i)
{ {
mch_memmove(&tmp_prop, props + i * sizeof(textprop_T), mch_memmove(&tmp_prop, props + i * sizeof(textprop_T),
sizeof(textprop_T)); sizeof(textprop_T));
if (tmp_prop.tp_col >= col) if (tmp_prop.tp_col >= col)
break; break;
} }
@@ -298,7 +314,7 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
tmp_prop.tp_flags = (lnum > start_lnum ? TP_FLAG_CONT_PREV : 0) tmp_prop.tp_flags = (lnum > start_lnum ? TP_FLAG_CONT_PREV : 0)
| (lnum < end_lnum ? TP_FLAG_CONT_NEXT : 0); | (lnum < end_lnum ? TP_FLAG_CONT_NEXT : 0);
mch_memmove(newprops + i * sizeof(textprop_T), &tmp_prop, mch_memmove(newprops + i * sizeof(textprop_T), &tmp_prop,
sizeof(textprop_T)); sizeof(textprop_T));
if (i < proplen) if (i < proplen)
mch_memmove(newprops + (i + 1) * sizeof(textprop_T), mch_memmove(newprops + (i + 1) * sizeof(textprop_T),

View File

@@ -767,6 +767,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1407,
/**/ /**/
1406, 1406,
/**/ /**/