aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/cursor.c5
-rw-r--r--src/nvim/mbyte.c35
-rw-r--r--src/nvim/normal.c4
-rw-r--r--src/nvim/terminal.c1
4 files changed, 39 insertions, 6 deletions
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 544bcf6ede..82f1bf0a16 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -338,9 +338,8 @@ void check_cursor_col(void)
check_cursor_col_win(curwin);
}
-/*
- * Make sure win->w_cursor.col is valid.
- */
+/// Make sure win->w_cursor.col is valid. Special handling of insert-mode.
+/// @see mb_check_adjust_col
void check_cursor_col_win(win_T *win)
{
colnr_T len;
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 6a87a63b8c..7a54b0c64f 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -1848,6 +1848,41 @@ void mb_adjustpos(buf_T *buf, pos_T *lp)
}
}
+/// Checks and adjusts cursor column. Not mode-dependent.
+/// @see check_cursor_col_win
+///
+/// @param win Places cursor on a valid column for this window.
+void mb_check_adjust_col(win_T *win)
+{
+ colnr_T oldcol = win->w_cursor.col;
+
+ // Column 0 is always valid.
+ if (oldcol != 0) {
+ char_u *p = ml_get_buf(win->w_buffer, win->w_cursor.lnum, false);
+ colnr_T len = (colnr_T)STRLEN(p);
+
+ // Empty line or invalid column?
+ if (len == 0 || oldcol < 0) {
+ win->w_cursor.col = 0;
+ } else {
+ // Cursor column too big for line?
+ if (oldcol > len) {
+ win->w_cursor.col = len - 1;
+ }
+ // Move the cursor to the head byte.
+ win->w_cursor.col -= (*mb_head_off)(p, p + win->w_cursor.col);
+ }
+
+ // Reset `coladd` when the cursor would be on the right half of a
+ // double-wide character.
+ if (win->w_cursor.coladd == 1 && p[win->w_cursor.col] != TAB
+ && vim_isprintc((*mb_ptr2char)(p + win->w_cursor.col))
+ && ptr2cells(p + win->w_cursor.col) > 1) {
+ win->w_cursor.coladd = 0;
+ }
+ }
+}
+
/*
* Return a pointer to the character before "*p", if there is one.
*/
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 7188e13436..85dc509ee6 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -925,9 +925,7 @@ normal_end:
checkpcmark(); // check if we moved since setting pcmark
xfree(s->ca.searchbuf);
- if (has_mbyte) {
- mb_adjust_cursor();
- }
+ mb_check_adjust_col(curwin); // #6203
if (curwin->w_p_scb && s->toplevel) {
validate_cursor(); // may need to update w_leftcol
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index bd925a8106..87ee8f410f 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1197,6 +1197,7 @@ static void adjust_topline(Terminal *term, buf_T *buf, long added)
// Ensure valid cursor for each window displaying this terminal.
wp->w_cursor.lnum = MIN(wp->w_cursor.lnum, ml_end);
}
+ mb_check_adjust_col(wp);
}
}
}