Patch 8.1.1407

11 views
Skip to first unread message

Bram Moolenaar

unread,
May 26, 2019, 5:32:34 PM5/26/19
to vim...@googlegroups.com

Patch 8.1.1407
Problem: Popup_create() does not support text properties.
Solution: Support the third form of the text argument.
Files: src/textprop.c, src/proto/textprop.pro, src/popupwin.c,
src/testdir/test_popupwin.vim, src/screen.c,
src/testdir/dumps/Test_popupwin_02.dump,
src/testdir/dumps/Test_popupwin_03.dump,
src/testdir/dumps/Test_popupwin_04.dump,
runtime/doc/popup.txt


*** ../vim-8.1.1406/src/textprop.c 2019-05-25 20:21:24.685950973 +0200
--- src/textprop.c 2019-05-26 23:30:46.064098867 +0200
***************
*** 142,164 ****
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]);
--- 142,149 ----
***************
*** 172,178 ****
emsg(_(e_dictreq));
return;
}
! dict = argvars[2].vval.v_dict;

if (dict == NULL || dict_find(dict, (char_u *)"type", -1) == NULL)
{
--- 157,194 ----
emsg(_(e_dictreq));
return;
}
!
! 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,227 ****
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)
return;

type = lookup_prop_type(type_name, buf);
--- 237,243 ----
if (dict_find(dict, (char_u *)"id", -1) != NULL)
id = dict_get_number(dict, (char_u *)"id");

! if (dict_arg != NULL && get_bufnr_from_arg(dict_arg, &buf) == FAIL)
return;

type = lookup_prop_type(type_name, buf);
***************
*** 278,289 ****
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.
for (i = 0; i < proplen; ++i)
{
mch_memmove(&tmp_prop, props + i * sizeof(textprop_T),
! sizeof(textprop_T));
if (tmp_prop.tp_col >= col)
break;
}
--- 294,305 ----
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.
for (i = 0; i < proplen; ++i)
{
mch_memmove(&tmp_prop, props + i * sizeof(textprop_T),
! sizeof(textprop_T));
if (tmp_prop.tp_col >= col)
break;
}
***************
*** 298,304 ****
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));

if (i < proplen)
mch_memmove(newprops + (i + 1) * sizeof(textprop_T),
--- 314,320 ----
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));

if (i < proplen)
mch_memmove(newprops + (i + 1) * sizeof(textprop_T),
*** ../vim-8.1.1406/src/proto/textprop.pro 2019-05-19 22:53:36.504914607 +0200
--- src/proto/textprop.pro 2019-05-26 23:30:50.644073843 +0200
***************
*** 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);
*** ../vim-8.1.1406/src/popupwin.c 2019-05-26 22:17:31.736315033 +0200
--- src/popupwin.c 2019-05-26 23:06:35.631863187 +0200
***************
*** 60,65 ****
--- 60,150 ----
}

/*
+ * 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})
*/
void
***************
*** 128,154 ****

// 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");

// Delete the line of the empty buffer.
curbuf = buf;
--- 213,233 ----

// 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_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;
*** ../vim-8.1.1406/src/testdir/test_popupwin.vim 2019-05-26 22:17:31.740314999 +0200
--- src/testdir/test_popupwin.vim 2019-05-26 23:17:26.152504812 +0200
***************
*** 14,19 ****
--- 14,21 ----
\ "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,29 ****

" Add a tabpage
call term_sendkeys(buf, ":tabnew\<CR>")
! call term_sendkeys(buf, ":call popup_create('other tab', {'line': 4, 'col': 9})\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_02', {})

" switch back to first tabpage
--- 25,36 ----

" Add a tabpage
call term_sendkeys(buf, ":tabnew\<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
*** ../vim-8.1.1406/src/screen.c 2019-05-26 22:17:31.740314999 +0200
--- src/screen.c 2019-05-26 23:20:55.635380744 +0200
***************
*** 4405,4411 ****
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);
# endif
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|| vcol < fromcol || vcol_prev < fromcol_prev
--- 4405,4414 ----
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 != 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,4435 ****
char_attr = hl_combine_attr(
syntax_attr, text_prop_attr);
else
! char_attr = text_prop_attr;
}
else
#endif
--- 4432,4439 ----
char_attr = hl_combine_attr(
syntax_attr, text_prop_attr);
else
! char_attr = hl_combine_attr(
! win_attr, text_prop_attr);
}
else
#endif
*** ../vim-8.1.1406/src/testdir/dumps/Test_popupwin_02.dump 2019-05-26 14:10:59.909979018 +0200
--- src/testdir/dumps/Test_popupwin_02.dump 2019-05-26 23:21:17.503256302 +0200
***************
*** 2,10 ****
> +0#0000000#ffffff0@74
|~+0#4040ff13&| @73
|~| @6|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @10| +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|
--- 2,10 ----
> +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
! | +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
*** ../vim-8.1.1406/src/testdir/dumps/Test_popupwin_03.dump 2019-05-26 21:03:19.940073927 +0200
--- src/testdir/dumps/Test_popupwin_03.dump 2019-05-26 23:21:59.287019422 +0200
***************
*** 7,10 ****
|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|
--- 7,10 ----
|6| @73
|7| @73
|8| @73
! @57|1|,|1| @10|T|o|p|
*** ../vim-8.1.1406/src/testdir/dumps/Test_popupwin_04.dump 2019-05-26 14:10:59.909979018 +0200
--- src/testdir/dumps/Test_popupwin_04.dump 2019-05-26 23:23:09.142625542 +0200
***************
*** 2,8 ****
|~+0#4040ff13&| @73
|~| @73
|~| @6|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @10| +0#4040ff13#ffffff0@46
! |~| @73
|~| @73
|~| @73
|~| @73
--- 2,8 ----
|~+0#4040ff13&| @73
|~| @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
*** ../vim-8.1.1406/runtime/doc/popup.txt 2019-05-26 22:17:31.740314999 +0200
--- runtime/doc/popup.txt 2019-05-26 23:14:09.857529430 +0200
***************
*** 279,285 ****
- 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
--- 279,284 ----
***************
*** 369,380 ****

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.
col starting column, counted in bytes, use one for the
first column.
length length of text in bytes; can be zero
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
--- 368,383 ----

POPUP TEXT PROPERTIES *popup-props*

! 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,390 ****
--- 388,394 ----
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*
*** ../vim-8.1.1406/src/version.c 2019-05-26 22:17:31.740314999 +0200
--- src/version.c 2019-05-26 22:35:57.872688332 +0200
***************
*** 769,770 ****
--- 769,772 ----
{ /* Add new patch number below this line */
+ /**/
+ 1407,
/**/

--
hundred-and-one symptoms of being an internet addict:
37. You start looking for hot HTML addresses in public restrooms.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages