aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/cursor.c')
-rw-r--r--src/nvim/cursor.c72
1 files changed, 55 insertions, 17 deletions
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 3ba9da34f2..0e97e2203f 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdbool.h>
#include <inttypes.h>
@@ -12,6 +15,7 @@
#include "nvim/state.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/mark.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor.c.generated.h"
@@ -227,9 +231,10 @@ static int coladvance2(
}
}
- /* prevent from moving onto a trail byte */
- if (has_mbyte)
- mb_adjustpos(curbuf, pos);
+ // Prevent from moving onto a trail byte.
+ if (has_mbyte) {
+ mark_mb_adjustpos(curbuf, pos);
+ }
if (col < wcol)
return FAIL;
@@ -294,6 +299,26 @@ linenr_T get_cursor_rel_lnum(win_T *wp, linenr_T lnum)
return (lnum < cursor) ? -retval : retval;
}
+// Make sure "pos.lnum" and "pos.col" are valid in "buf".
+// This allows for the col to be on the NUL byte.
+void check_pos(buf_T *buf, pos_T *pos)
+{
+ char_u *line;
+ colnr_T len;
+
+ if (pos->lnum > buf->b_ml.ml_line_count) {
+ pos->lnum = buf->b_ml.ml_line_count;
+ }
+
+ if (pos->col > 0) {
+ line = ml_get_buf(buf, pos->lnum, false);
+ len = (colnr_T)STRLEN(line);
+ if (pos->col > len) {
+ pos->col = len;
+ }
+ }
+}
+
/*
* Make sure curwin->w_cursor.lnum is valid.
*/
@@ -318,9 +343,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;
@@ -342,25 +366,39 @@ void check_cursor_col_win(win_T *win)
win->w_cursor.col = len;
} else {
win->w_cursor.col = len - 1;
- /* Move the cursor to the head byte. */
- if (has_mbyte)
- mb_adjustpos(win->w_buffer, &win->w_cursor);
+ // Move the cursor to the head byte.
+ if (has_mbyte) {
+ mark_mb_adjustpos(win->w_buffer, &win->w_cursor);
+ }
}
} else if (win->w_cursor.col < 0) {
win->w_cursor.col = 0;
}
- /* If virtual editing is on, we can leave the cursor on the old position,
- * only we must set it to virtual. But don't do it when at the end of the
- * line. */
- if (oldcol == MAXCOL)
+ // If virtual editing is on, we can leave the cursor on the old position,
+ // only we must set it to virtual. But don't do it when at the end of the
+ // line.
+ if (oldcol == MAXCOL) {
win->w_cursor.coladd = 0;
- else if (ve_flags == VE_ALL) {
- if (oldcoladd > win->w_cursor.col)
+ } else if (ve_flags == VE_ALL) {
+ if (oldcoladd > win->w_cursor.col) {
win->w_cursor.coladd = oldcoladd - win->w_cursor.col;
- else
- /* avoid weird number when there is a miscalculation or overflow */
+
+ // Make sure that coladd is not more than the char width.
+ // Not for the last character, coladd is then used when the cursor
+ // is actually after the last character.
+ if (win->w_cursor.col + 1 < len && win->w_cursor.coladd > 0) {
+ int cs, ce;
+
+ getvcol(win, &win->w_cursor, &cs, NULL, &ce);
+ if (win->w_cursor.coladd > ce - cs) {
+ win->w_cursor.coladd = ce - cs;
+ }
+ }
+ } else {
+ // avoid weird number when there is a miscalculation or overflow
win->w_cursor.coladd = 0;
+ }
}
}