diff src/popupwin.c @ 16853:e6bcccccbf7b v8.1.1428

patch 8.1.1428: popup_atcursor() not implemented yet commit https://github.com/vim/vim/commit/cc31ad9f9b601d53926b96586bd6b40602d57951 Author: Bram Moolenaar <Bram@vim.org> Date: Thu May 30 19:25:06 2019 +0200 patch 8.1.1428: popup_atcursor() not implemented yet Problem: Popup_atcursor() not implemented yet. Solution: Implement it. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/4456)
author Bram Moolenaar <Bram@vim.org>
date Thu, 30 May 2019 19:30:03 +0200
parents 48c06fcb8be7
children 19162ff4eacd
line wrap: on
line diff
--- 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 UNUS
     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
     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
 }
 
 /*
+ * 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.