diff src/move.c @ 17292:8a095d343c59 v8.1.1645

patch 8.1.1645: cannot use a popup window for a balloon commit https://github.com/vim/vim/commit/b3d17a20d243f65bcfe23de08b7afd948c5132c2 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 7 18:28:14 2019 +0200 patch 8.1.1645: cannot use a popup window for a balloon Problem: Cannot use a popup window for a balloon. Solution: Add popup_beval(). Add the "mousemoved" property. Add the screenpos() function.
author Bram Moolenaar <Bram@vim.org>
date Sun, 07 Jul 2019 18:30:05 +0200
parents cd5c83115ec6
children 59f8948b7590
line wrap: on
line diff
--- a/src/move.c
+++ b/src/move.c
@@ -1189,6 +1189,96 @@ curs_columns(
     curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL;
 }
 
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Compute the screen position of text character at "pos" in window "wp"
+ * The resulting values are one-based, zero when character is not visible.
+ */
+    static void
+textpos2screenpos(
+	win_T	*wp,
+	pos_T	*pos,
+	int	*rowp,	// screen row
+	int	*scolp,	// start screen column
+	int	*ccolp,	// cursor screen column
+	int	*ecolp)	// end screen column
+{
+    colnr_T	scol = 0, ccol = 0, ecol = 0;
+    int		row = 0;
+    int		rowoff = 0;
+    colnr_T	coloff = 0;
+
+    if (pos->lnum >= wp->w_topline && pos->lnum < wp->w_botline)
+    {
+	colnr_T off;
+	colnr_T col;
+	int     width;
+
+	row = plines_m_win(wp, wp->w_topline, pos->lnum - 1) + 1;
+	getvcol(wp, pos, &scol, &ccol, &ecol);
+
+	// similar to what is done in validate_cursor_col()
+	col = scol;
+	off = win_col_off(wp);
+	col += off;
+	width = wp->w_width - off + win_col_off2(wp);
+
+	/* long line wrapping, adjust row */
+	if (wp->w_p_wrap
+		&& col >= (colnr_T)wp->w_width
+		&& width > 0)
+	{
+	    /* use same formula as what is used in curs_columns() */
+	    rowoff = ((col - wp->w_width) / width + 1);
+	    col -= rowoff * width;
+	}
+	col -= wp->w_leftcol;
+	if (col >= width)
+	    col = -1;
+	if (col >= 0)
+	    coloff = col - scol + wp->w_wincol + 1;
+	else
+	    // character is left or right of the window
+	    row = scol = ccol = ecol = 0;
+    }
+    *rowp = wp->w_winrow + row + rowoff;
+    *scolp = scol + coloff;
+    *ccolp = ccol + coloff;
+    *ecolp = ecol + coloff;
+}
+
+/*
+ * "screenpos({winid}, {lnum}, {col})" function
+ */
+    void
+f_screenpos(typval_T *argvars UNUSED, typval_T *rettv)
+{
+    dict_T	*dict;
+    win_T	*wp;
+    pos_T	pos;
+    int		row = 0;
+    int		scol = 0, ccol = 0, ecol = 0;
+
+    if (rettv_dict_alloc(rettv) != OK)
+	return;
+    dict = rettv->vval.v_dict;
+
+    wp = find_win_by_nr_or_id(&argvars[0]);
+    if (wp == NULL)
+	return;
+
+    pos.lnum = tv_get_number(&argvars[1]);
+    pos.col = tv_get_number(&argvars[2]) - 1;
+    pos.coladd = 0;
+    textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol);
+
+    dict_add_number(dict, "row", row);
+    dict_add_number(dict, "col", scol);
+    dict_add_number(dict, "curscol", ccol);
+    dict_add_number(dict, "endcol", ecol);
+}
+#endif
+
 /*
  * Scroll the current window down by "line_count" logical lines.  "CTRL-Y"
  */