mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -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:
@@ -279,7 +279,6 @@ optionally text properties. It is in one of three forms:
|
||||
- a string
|
||||
- a list of strings
|
||||
- a list of dictionaries, where each dictionary has these entries:
|
||||
{not implemented yet}
|
||||
text String with the text to display.
|
||||
props A list of text properties. Optional.
|
||||
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*
|
||||
|
||||
{not implemented yet}
|
||||
These are similar to the third argument of |prop_add()|, but not exactly the
|
||||
same, since they only apply to one line.
|
||||
These are similar to the third argument of |prop_add()| except:
|
||||
- "lnum" is always the current line in the list
|
||||
- "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
|
||||
first column.
|
||||
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
|
||||
present; when {col} and "end_col" are equal, this is a
|
||||
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;
|
||||
if there is an border character to the right or below
|
||||
it will be made transparent as well
|
||||
{not implemented yet}
|
||||
|
||||
|
||||
POPUP FILTER *popup-filter*
|
||||
|
113
src/popupwin.c
113
src/popupwin.c
@@ -59,6 +59,91 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
|
||||
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})
|
||||
*/
|
||||
@@ -128,27 +213,21 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
|
||||
|
||||
// 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 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
|
||||
// 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.
|
||||
curbuf = buf;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* textprop.c */
|
||||
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);
|
||||
proptype_T *text_prop_type_by_id(buf_T *buf, int id);
|
||||
void f_prop_clear(typval_T *argvars, typval_T *rettv);
|
||||
|
@@ -4405,7 +4405,10 @@ win_line(
|
||||
char_attr = hl_combine_attr(line_attr, search_attr);
|
||||
# ifdef FEAT_TEXT_PROP
|
||||
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
|
||||
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|
||||
|| vcol < fromcol || vcol_prev < fromcol_prev
|
||||
@@ -4429,7 +4432,8 @@ win_line(
|
||||
char_attr = hl_combine_attr(
|
||||
syntax_attr, text_prop_attr);
|
||||
else
|
||||
char_attr = text_prop_attr;
|
||||
char_attr = hl_combine_attr(
|
||||
win_attr, text_prop_attr);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@@ -2,9 +2,9 @@
|
||||
> +0#0000000#ffffff0@74
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @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
|
||||
|:+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|
|
||||
| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
|
||||
|
@@ -7,4 +7,4 @@
|
||||
|6| @73
|
||||
|7| @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|
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @73
|
||||
|~| @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
|
||||
|
@@ -14,6 +14,8 @@ func Test_simple_popup()
|
||||
\ "call setline(1, range(1, 100))",
|
||||
\ "hi PopupColor1 ctermbg=lightblue",
|
||||
\ "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 winid2 = popup_create(['another one', 'another two', 'another three'], {'line': 3, 'col': 25})",
|
||||
\ "call setwinvar(winid2, '&wincolor', 'PopupColor2')",
|
||||
@@ -23,7 +25,12 @@ func Test_simple_popup()
|
||||
|
||||
" Add a tabpage
|
||||
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', {})
|
||||
|
||||
" switch back to first tabpage
|
||||
|
@@ -142,23 +142,8 @@ get_bufnr_from_arg(typval_T *arg, buf_T **buf)
|
||||
void
|
||||
f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
linenr_T lnum;
|
||||
linenr_T start_lnum;
|
||||
linenr_T end_lnum;
|
||||
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_col = tv_get_number(&argvars[1]);
|
||||
@@ -172,7 +157,38 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
emsg(_(e_dictreq));
|
||||
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)
|
||||
{
|
||||
@@ -221,7 +237,7 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
if (dict_find(dict, (char_u *)"id", -1) != NULL)
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
// Find the index where to insert the new property.
|
||||
// Since the text properties are not aligned properly when stored with the
|
||||
// text, we need to copy them as bytes before using it as a struct.
|
||||
// Since the text properties are not aligned properly when stored with
|
||||
// the text, we need to copy them as bytes before using it as a struct.
|
||||
for (i = 0; i < proplen; ++i)
|
||||
{
|
||||
mch_memmove(&tmp_prop, props + i * sizeof(textprop_T),
|
||||
sizeof(textprop_T));
|
||||
sizeof(textprop_T));
|
||||
if (tmp_prop.tp_col >= col)
|
||||
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)
|
||||
| (lnum < end_lnum ? TP_FLAG_CONT_NEXT : 0);
|
||||
mch_memmove(newprops + i * sizeof(textprop_T), &tmp_prop,
|
||||
sizeof(textprop_T));
|
||||
sizeof(textprop_T));
|
||||
|
||||
if (i < proplen)
|
||||
mch_memmove(newprops + (i + 1) * sizeof(textprop_T),
|
||||
|
@@ -767,6 +767,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1407,
|
||||
/**/
|
||||
1406,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user