diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/cursor.c | 5 | ||||
-rw-r--r-- | src/nvim/mbyte.c | 35 | ||||
-rw-r--r-- | src/nvim/normal.c | 4 | ||||
-rw-r--r-- | src/nvim/terminal.c | 1 |
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); } } } |