summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-05-30 19:25:06 +0200
committerBram Moolenaar <Bram@vim.org>2019-05-30 19:25:06 +0200
commitcc31ad9f9b601d53926b96586bd6b40602d57951 (patch)
tree2cc83563ea3db6176c37a922068c262777d8217f
parent54fabd4b5e373c7f1d794d24d27a30a8bac84da1 (diff)
downloadvim-git-cc31ad9f9b601d53926b96586bd6b40602d57951.tar.gz
patch 8.1.1428: popup_atcursor() not implemented yetv8.1.1428
Problem: Popup_atcursor() not implemented yet. Solution: Implement it. (Yasuhiro Matsumoto, closes #4456)
-rw-r--r--runtime/doc/popup.txt29
-rw-r--r--src/evalfunc.c1
-rw-r--r--src/popupwin.c87
-rw-r--r--src/proto/popupwin.pro15
-rw-r--r--src/testdir/test_popupwin.vim49
-rw-r--r--src/version.c2
6 files changed, 159 insertions, 24 deletions
diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt
index 174ea094a..58728c8c4 100644
--- a/runtime/doc/popup.txt
+++ b/runtime/doc/popup.txt
@@ -85,11 +85,11 @@ Probably 2. is the best choice.
IMPLEMENTATION:
- Code is in popupwin.c
-- when creating the window set options to Vim default? (verify with 'number')
+- Implement the "pos" option.
- Implement filter.
Check that popup_close() works in the filter.
-- Implement the "pos" option.
- Handle screen resize in screenalloc().
+- show [Popup] instead of [Scratch] in ":ls!"
- Make redrawing more efficient and avoid flicker.
Store popup info in a mask, use the mask in screen_line()
Fix redrawing problem with completion.
@@ -97,7 +97,7 @@ IMPLEMENTATION:
Fix redrawing the statusline on top of a popup
- Figure out the size and position better.
if wrapping splits a double-wide character
- if wrapping has an indent
+ if wrapping inserts indent
- Can the buffer be re-used, to avoid using up lots of buffer numbers?
- Implement all the unimplemented options and features.
@@ -160,10 +160,10 @@ popup_notification({text}, {options}) *popup_notification()*
popup_atcursor({text}, {options}) *popup_atcursor()*
- {not implemented yet}
Show the {text} above the cursor, and close it when the cursor
moves. This works like: >
call popup_create({text}, {
+ \ 'pos': 'botleft',
\ 'line': 'cursor-1',
\ 'col': 'cursor',
\ 'moved': 'WORD',
@@ -270,10 +270,11 @@ manipulation is restricted:
- 'bufhidden' is "hide"
- 'buflisted' is off
- 'undolevels' is -1: no undo at all
-TODO: more
+- all other buffer-local and window_local options are set to their Vim default
+ value.
-It is possible to change these options, but anything might break then, so
-better leave them alone.
+It is possible to change the specifically mentioned options, but anything
+might break then, so better leave them alone.
The window does have a cursor position, but the cursor is not displayed.
@@ -306,12 +307,10 @@ The second argument of |popup_create()| is a dictionary with options:
"cursor", "cursor+1" or "cursor-1" to use the line of
the cursor and add or subtract a number of lines;
default is "cursor-1".
- {only number is implemented}
col screen column where to position the popup; can use
"cursor" to use the column of the cursor, "cursor+99"
and "cursor-99" to add or subtract a number of
columns; default is "cursor"
- {only number is implemented}
pos "topleft", "topright", "botleft" or "botright":
defines what corner of the popup "line" and "col" are
used for. When not set "topleft" is used.
@@ -342,9 +341,17 @@ The second argument of |popup_create()| is a dictionary with options:
{not implemented yet}
highlight highlight group name to use for the text, stored in
the 'wincolor' option
+ padding list with numbers, defining the padding
+ above/right/below/left of the popup (similar to CSS);
+ an empty list uses a padding of 1 all around; the
+ padding goes around the text, inside any border;
+ padding uses the 'wincolor' highlight; Example: [1, 2,
+ 1, 3] has 1 line of padding above, 2 columns on the
+ right, 1 line below and 3 columns on the left
+ {not implemented yet}
border list with numbers, defining the border thickness
- above/right/below/left of the popup; an empty list
- uses a border of 1 all around
+ above/right/below/left of the popup (similar to CSS);
+ an empty list uses a border of 1 all around
{not implemented yet}
borderhighlight highlight group name to use for the border
{not implemented yet}
diff --git a/src/evalfunc.c b/src/evalfunc.c
index d1e89eb99..a6703d18b 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -809,6 +809,7 @@ static struct fst
{"perleval", 1, 1, f_perleval},
#endif
#ifdef FEAT_TEXT_PROP
+ {"popup_atcursor", 2, 2, f_popup_atcursor},
{"popup_close", 1, 1, f_popup_close},
{"popup_create", 2, 2, f_popup_create},
{"popup_getoptions", 1, 1, f_popup_getoptions},
diff --git a/src/popupwin.c b/src/popupwin.c
index ee59af2ea..9e9bf27e7 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -16,11 +16,55 @@
#ifdef FEAT_TEXT_PROP
/*
+ * Get option value for"key", which is "line" or "col".
+ * Handles "cursor+N" and "cursor-N".
+ */
+ static int
+popup_options_pos(dict_T *dict, char_u *key)
+{
+ dictitem_T *di;
+ char_u *val;
+ char_u *s;
+ char_u *endp;
+ int n = 0;
+
+ di = dict_find(dict, key, -1);
+ if (di == NULL)
+ return 0;
+
+ val = tv_get_string(&di->di_tv);
+ if (STRNCMP(val, "cursor", 6) != 0)
+ return dict_get_number(dict, key);
+
+ setcursor_mayforce(TRUE);
+ s = val + 6;
+ if (*s != NUL)
+ {
+ n = strtol((char *)s, (char **)&endp, 10);
+ if (endp != NULL && *skipwhite(endp) != NUL)
+ {
+ semsg(_(e_invexpr2), val);
+ return 0;
+ }
+ }
+
+ if (STRCMP(key, "line") == 0)
+ n = screen_screenrow() + 1 + n;
+ else // "col"
+ n = screen_screencol() + 1 + n;
+
+ if (n < 1)
+ n = 1;
+ return n;
+}
+
+/*
* Go through the options in "dict" and apply them to buffer "buf" displayed in
* popup window "wp".
+ * When called from f_popup_atcursor() "atcursor" is TRUE.
*/
static void
-apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
+apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
{
int nr;
char_u *str;
@@ -30,8 +74,19 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth");
wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight");
- wp->w_wantline = dict_get_number(dict, (char_u *)"line");
- wp->w_wantcol = dict_get_number(dict, (char_u *)"col");
+ if (atcursor)
+ {
+ setcursor_mayforce(TRUE);
+ wp->w_wantline = screen_screenrow();
+ wp->w_wantcol = screen_screencol() + 1;
+ }
+
+ nr = popup_options_pos(dict, (char_u *)"line");
+ if (nr > 0)
+ wp->w_wantline = nr;
+ nr = popup_options_pos(dict, (char_u *)"col");
+ if (nr > 0)
+ wp->w_wantcol = nr;
wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
@@ -215,9 +270,11 @@ popup_adjust_position(win_T *wp)
/*
* popup_create({text}, {options})
+ * popup_atcursor({text}, {options})
+ * When called from f_popup_atcursor() "atcursor" is TRUE.
*/
- void
-f_popup_create(typval_T *argvars, typval_T *rettv)
+ static void
+popup_create(typval_T *argvars, typval_T *rettv, int atcursor)
{
win_T *wp;
buf_T *buf;
@@ -309,7 +366,7 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
curbuf = curwin->w_buffer;
// Deal with options.
- apply_options(wp, buf, argvars[1].vval.v_dict);
+ apply_options(wp, buf, argvars[1].vval.v_dict, atcursor);
// set default values
if (wp->w_zindex == 0)
@@ -323,6 +380,24 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
}
/*
+ * popup_create({text}, {options})
+ */
+ void
+f_popup_create(typval_T *argvars, typval_T *rettv)
+{
+ popup_create(argvars, rettv, FALSE);
+}
+
+/*
+ * popup_atcursor({text}, {options})
+ */
+ void
+f_popup_atcursor(typval_T *argvars, typval_T *rettv)
+{
+ popup_create(argvars, rettv, TRUE);
+}
+
+/*
* Find the popup window with window-ID "id".
* If the popup window does not exist NULL is returned.
* If the window is not a popup window, and error message is given.
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index 733745712..404b6cfe8 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -1,15 +1,16 @@
/* popupwin.c */
-void popup_adjust_position(win_T *wp);
-void f_popup_create(typval_T *argvars, typval_T *rettv);
int popup_any_visible(void);
+void close_all_popups(void);
+void ex_popupclear(exarg_T *eap);
+void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
void f_popup_close(typval_T *argvars, typval_T *rettv);
+void f_popup_create(typval_T *argvars, typval_T *rettv);
+void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
+void f_popup_getposition(typval_T *argvars, typval_T *rettv);
void f_popup_hide(typval_T *argvars, typval_T *rettv);
+void f_popup_move(typval_T *argvars, typval_T *rettv);
void f_popup_show(typval_T *argvars, typval_T *rettv);
+void popup_adjust_position(win_T *wp);
void popup_close(int id);
void popup_close_tabpage(tabpage_T *tp, int id);
-void close_all_popups(void);
-void ex_popupclear(exarg_T *eap);
-void f_popup_move(typval_T *argvars, typval_T *rettv);
-void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
-void f_popup_getposition(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index d92d8b12a..ee188e39c 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -335,3 +335,52 @@ func Test_popup_option_values()
call popup_close(winid)
bwipe
endfunc
+
+func Test_popup_atcursor()
+ topleft vnew
+ call setline(1, [
+ \ 'xxxxxxxxxxxxxxxxx',
+ \ 'xxxxxxxxxxxxxxxxx',
+ \ 'xxxxxxxxxxxxxxxxx',
+ \])
+
+ call cursor(2, 2)
+ redraw
+ let winid = popup_atcursor('vim', {})
+ redraw
+ let line = join(map(range(1, 17), 'screenstring(1, v:val)'), '')
+ call assert_equal('xvimxxxxxxxxxxxxx', line)
+ call popup_close(winid)
+
+ call cursor(3, 4)
+ redraw
+ let winid = popup_atcursor('vim', {})
+ redraw
+ let line = join(map(range(1, 17), 'screenstring(2, v:val)'), '')
+ call assert_equal('xxxvimxxxxxxxxxxx', line)
+ call popup_close(winid)
+
+ call cursor(1, 1)
+ redraw
+ let winid = popup_create('vim', {
+ \ 'line': 'cursor+2',
+ \ 'col': 'cursor+1',
+ \})
+ redraw
+ let line = join(map(range(1, 17), 'screenstring(3, v:val)'), '')
+ call assert_equal('xvimxxxxxxxxxxxxx', line)
+ call popup_close(winid)
+
+ call cursor(3, 3)
+ redraw
+ let winid = popup_create('vim', {
+ \ 'line': 'cursor-2',
+ \ 'col': 'cursor-1',
+ \})
+ redraw
+ let line = join(map(range(1, 17), 'screenstring(1, v:val)'), '')
+ call assert_equal('xvimxxxxxxxxxxxxx', line)
+ call popup_close(winid)
+
+ bwipe!
+endfunc
diff --git a/src/version.c b/src/version.c
index 282d045e6..6d04157ab 100644
--- a/src/version.c
+++ b/src/version.c
@@ -768,6 +768,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1428,
+/**/
1427,
/**/
1426,