aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/move.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r--src/nvim/move.c75
1 files changed, 74 insertions, 1 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 4a87f82eb7..e6fee9999f 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -95,6 +95,8 @@ static void comp_botline(win_T *wp)
wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
set_empty_rows(wp, done);
+
+ win_check_anchored_floats(wp);
}
void reset_cursorline(void)
@@ -310,6 +312,7 @@ void update_topline(void)
}
}
curwin->w_valid |= VALID_TOPLINE;
+ win_check_anchored_floats(curwin);
/*
* Need to redraw when topline changed.
@@ -827,7 +830,8 @@ void curs_columns(
new_leftcol = 0;
if (new_leftcol != (int)curwin->w_leftcol) {
curwin->w_leftcol = new_leftcol;
- /* screen has to be redrawn with new curwin->w_leftcol */
+ win_check_anchored_floats(curwin);
+ // screen has to be redrawn with new curwin->w_leftcol
redraw_later(NOT_VALID);
}
}
@@ -943,6 +947,74 @@ void curs_columns(
curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL;
}
+/// Compute the screen position of text character at "pos" in window "wp"
+/// The resulting values are one-based, zero when character is not visible.
+///
+/// @param[out] rowp screen row
+/// @param[out] scolp start screen column
+/// @param[out] ccolp cursor screen column
+/// @param[out] ecolp end screen column
+void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp,
+ int *ccolp, int *ecolp, bool local)
+{
+ colnr_T scol = 0, ccol = 0, ecol = 0;
+ int row = 0;
+ int rowoff = 0;
+ colnr_T coloff = 0;
+ bool visible_row = false;
+
+ if (pos->lnum >= wp->w_topline && pos->lnum < wp->w_botline) {
+ row = plines_m_win(wp, wp->w_topline, pos->lnum - 1) + 1;
+ visible_row = true;
+ } else if (pos->lnum < wp->w_topline) {
+ row = 0;
+ } else {
+ row = wp->w_height_inner;
+ }
+
+ bool existing_row = (pos->lnum > 0
+ && pos->lnum <= wp->w_buffer->b_ml.ml_line_count);
+
+ if ((local && existing_row) || visible_row) {
+ colnr_T off;
+ colnr_T col;
+ int width;
+
+ 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 = visible_row ? ((col - wp->w_width) / width + 1) : 0;
+ col -= rowoff * width;
+ }
+
+ col -= wp->w_leftcol;
+
+ if (col >= 0 && col < width) {
+ coloff = col - scol + (local ? 0 : wp->w_wincol) + 1;
+ } else {
+ scol = ccol = ecol = 0;
+ // character is left or right of the window
+ if (local) {
+ coloff = col < 0 ? -1 : wp->w_width_inner + 1;
+ } else {
+ row = 0;
+ }
+ }
+ }
+ *rowp = (local ? 0 : wp->w_winrow) + row + rowoff;
+ *scolp = scol + coloff;
+ *ccolp = ccol + coloff;
+ *ecolp = ecol + coloff;
+}
+
/*
* Scroll the current window down by "line_count" logical lines. "CTRL-Y"
*/
@@ -1099,6 +1171,7 @@ check_topfill (
}
}
}
+ win_check_anchored_floats(curwin);
}
/*