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.c210
1 files changed, 94 insertions, 116 deletions
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 6e2c6232d7..1446257f7e 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -15,6 +15,7 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/move.h"
+#include "nvim/option.h"
#include "nvim/plines.h"
#include "nvim/screen.h"
#include "nvim/state.h"
@@ -24,9 +25,7 @@
# include "cursor.c.generated.h"
#endif
-/*
- * Get the screen position of the cursor.
- */
+/// @return the screen position of the cursor.
int getviscol(void)
{
colnr_T x;
@@ -35,9 +34,7 @@ int getviscol(void)
return (int)x;
}
-/*
- * Get the screen position of character col with a coladd in the cursor line.
- */
+/// @return the screen position of character col with a coladd in the cursor line.
int getviscol2(colnr_T col, colnr_T coladd)
{
colnr_T x;
@@ -50,11 +47,9 @@ int getviscol2(colnr_T col, colnr_T coladd)
return (int)x;
}
-/*
- * Go to column "wcol", and add/insert white space as necessary to get the
- * cursor in that column.
- * The caller must have saved the cursor line for undo!
- */
+/// Go to column "wcol", and add/insert white space as necessary to get the
+/// cursor in that column.
+/// The caller must have saved the cursor line for undo!
int coladvance_force(colnr_T wcol)
{
int rc = coladvance2(&curwin->w_cursor, true, false, wcol);
@@ -69,15 +64,13 @@ int coladvance_force(colnr_T wcol)
return rc;
}
-/*
- * Try to advance the Cursor to the specified screen column.
- * If virtual editing: fine tune the cursor position.
- * Note that all virtual positions off the end of a line should share
- * a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)),
- * beginning at coladd 0.
- *
- * return OK if desired column is reached, FAIL if not
- */
+/// Try to advance the Cursor to the specified screen column.
+/// If virtual editing: fine tune the cursor position.
+/// Note that all virtual positions off the end of a line should share
+/// a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)),
+/// beginning at coladd 0.
+///
+/// @return OK if desired column is reached, FAIL if not
int coladvance(colnr_T wcol)
{
int rc = getvpos(&curwin->w_cursor, wcol);
@@ -99,19 +92,16 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
{
colnr_T wcol = wcol_arg;
int idx;
- char_u *ptr;
- char_u *line;
colnr_T col = 0;
- int csize = 0;
- int one_more;
int head = 0;
- one_more = (State & INSERT)
- || (State & TERM_FOCUS)
- || restart_edit != NUL
- || (VIsual_active && *p_sel != 'o')
- || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL);
- line = ml_get_buf(curbuf, pos->lnum, false);
+ int one_more = (State & MODE_INSERT)
+ || (State & MODE_TERMINAL)
+ || restart_edit != NUL
+ || (VIsual_active && *p_sel != 'o')
+ || ((get_ve_flags() & VE_ONEMORE) && wcol < MAXCOL);
+
+ char_u *line = ml_get_buf(curbuf, pos->lnum, false);
if (wcol >= MAXCOL) {
idx = (int)STRLEN(line) - 1 + one_more;
@@ -120,11 +110,12 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
if ((addspaces || finetune) && !VIsual_active) {
curwin->w_curswant = linetabsize(line) + one_more;
if (curwin->w_curswant > 0) {
- --curwin->w_curswant;
+ curwin->w_curswant--;
}
}
} else {
int width = curwin->w_width_inner - win_col_off(curwin);
+ int csize = 0;
if (finetune
&& curwin->w_p_wrap
@@ -137,16 +128,16 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
}
if (wcol / width > (colnr_T)csize / width
- && ((State & INSERT) == 0 || (int)wcol > csize + 1)) {
- /* In case of line wrapping don't move the cursor beyond the
- * right screen edge. In Insert mode allow going just beyond
- * the last character (like what happens when typing and
- * reaching the right window edge). */
+ && ((State & MODE_INSERT) == 0 || (int)wcol > csize + 1)) {
+ // In case of line wrapping don't move the cursor beyond the
+ // right screen edge. In Insert mode allow going just beyond
+ // the last character (like what happens when typing and
+ // reaching the right window edge).
wcol = (csize / width + 1) * width - 1;
}
}
- ptr = line;
+ char_u *ptr = line;
while (col <= wcol && *ptr != NUL) {
// Count a tab for what it's worth (if list mode not on)
csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
@@ -154,12 +145,10 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
col += csize;
}
idx = (int)(ptr - line);
- /*
- * Handle all the special cases. The virtual_active() check
- * is needed to ensure that a virtual position off the end of
- * a line has the correct indexing. The one_more comparison
- * replaces an explicit add of one_more later on.
- */
+ // Handle all the special cases. The virtual_active() check
+ // is needed to ensure that a virtual position off the end of
+ // a line has the correct indexing. The one_more comparison
+ // replaces an explicit add of one_more later on.
if (col > wcol || (!virtual_active() && one_more == 0)) {
idx -= 1;
// Don't count the chars from 'showbreak'.
@@ -171,8 +160,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
&& addspaces
&& wcol >= 0
&& ((col != wcol && col != wcol + 1) || csize > 1)) {
- /* 'virtualedit' is set: The difference between wcol and col is
- * filled with spaces. */
+ // 'virtualedit' is set: The difference between wcol and col is filled with spaces.
if (line[idx] == NUL) {
// Append spaces
@@ -183,7 +171,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
memcpy(newline, line, (size_t)idx);
memset(newline + idx, ' ', (size_t)correct);
- ml_replace(pos->lnum, newline, false);
+ ml_replace(pos->lnum, (char *)newline, false);
inserted_bytes(pos->lnum, (colnr_T)idx, 0, correct);
idx += correct;
col = wcol;
@@ -209,7 +197,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
STRICT_SUB(n, 1, &n, size_t);
memcpy(newline + idx + csize, line + idx + 1, n);
- ml_replace(pos->lnum, newline, false);
+ ml_replace(pos->lnum, (char *)newline, false);
inserted_bytes(pos->lnum, idx, 1, csize);
idx += (csize - 1 + correct);
col += correct;
@@ -255,29 +243,23 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
return OK;
}
-/*
- * Return in "pos" the position of the cursor advanced to screen column "wcol".
- * return OK if desired column is reached, FAIL if not
- */
+/// Return in "pos" the position of the cursor advanced to screen column "wcol".
+///
+/// @return OK if desired column is reached, FAIL if not
int getvpos(pos_T *pos, colnr_T wcol)
{
return coladvance2(pos, false, virtual_active(), wcol);
}
-/*
- * Increment the cursor position. See inc() for return values.
- */
+/// Increment the cursor position. See inc() for return values.
int inc_cursor(void)
{
return inc(&curwin->w_cursor);
}
-/*
- * dec(p)
- *
- * Decrement the line pointer 'p' crossing line boundaries as necessary.
- * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
- */
+/// Decrement the line pointer 'p' crossing line boundaries as necessary.
+///
+/// @return 1 when crossing a line, -1 when at start of file, 0 otherwise.
int dec_cursor(void)
{
return dec(&curwin->w_cursor);
@@ -313,34 +295,29 @@ 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.
+/// 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);
+ char_u *line = ml_get_buf(buf, pos->lnum, false);
+ colnr_T len = (colnr_T)STRLEN(line);
if (pos->col > len) {
pos->col = len;
}
}
}
-/*
- * Make sure curwin->w_cursor.lnum is valid.
- */
+/// Make sure curwin->w_cursor.lnum is valid.
void check_cursor_lnum(void)
{
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
- /* If there is a closed fold at the end of the file, put the cursor in
- * its first line. Otherwise in the last line. */
+ // If there is a closed fold at the end of the file, put the cursor in
+ // its first line. Otherwise in the last line.
if (!hasFolding(curbuf->b_ml.ml_line_count,
&curwin->w_cursor.lnum, NULL)) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
@@ -351,9 +328,7 @@ void check_cursor_lnum(void)
}
}
-/*
- * Make sure curwin->w_cursor.col is valid.
- */
+/// Make sure curwin->w_cursor.col is valid.
void check_cursor_col(void)
{
check_cursor_col_win(curwin);
@@ -363,21 +338,21 @@ void check_cursor_col(void)
/// @see mb_check_adjust_col
void check_cursor_col_win(win_T *win)
{
- colnr_T len;
colnr_T oldcol = win->w_cursor.col;
colnr_T oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
+ unsigned int cur_ve_flags = get_ve_flags();
- len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, false));
+ colnr_T len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, false));
if (len == 0) {
win->w_cursor.col = 0;
} else if (win->w_cursor.col >= len) {
- /* Allow cursor past end-of-line when:
- * - in Insert mode or restarting Insert mode
- * - in Visual mode and 'selection' isn't "old"
- * - 'virtualedit' is set */
- if ((State & INSERT) || restart_edit
+ // Allow cursor past end-of-line when:
+ // - in Insert mode or restarting Insert mode
+ // - in Visual mode and 'selection' isn't "old"
+ // - 'virtualedit' is set */
+ if ((State & MODE_INSERT) || restart_edit
|| (VIsual_active && *p_sel != 'o')
- || (ve_flags & VE_ONEMORE)
+ || (cur_ve_flags & VE_ONEMORE)
|| virtual_active()) {
win->w_cursor.col = len;
} else {
@@ -394,7 +369,7 @@ void check_cursor_col_win(win_T *win)
// line.
if (oldcol == MAXCOL) {
win->w_cursor.coladd = 0;
- } else if (ve_flags == VE_ALL) {
+ } else if (cur_ve_flags == VE_ALL) {
if (oldcoladd > win->w_cursor.col) {
win->w_cursor.coladd = oldcoladd - win->w_cursor.col;
@@ -417,32 +392,45 @@ void check_cursor_col_win(win_T *win)
}
}
-/*
- * make sure curwin->w_cursor in on a valid character
- */
+/// Make sure curwin->w_cursor in on a valid character
void check_cursor(void)
{
check_cursor_lnum();
check_cursor_col();
}
-/*
- * Make sure curwin->w_cursor is not on the NUL at the end of the line.
- * Allow it when in Visual mode and 'selection' is not "old".
- */
+/// Check if VIsual position is valid, correct it if not.
+/// Can be called when in Visual mode and a change has been made.
+void check_visual_pos(void)
+{
+ if (VIsual.lnum > curbuf->b_ml.ml_line_count) {
+ VIsual.lnum = curbuf->b_ml.ml_line_count;
+ VIsual.col = 0;
+ VIsual.coladd = 0;
+ } else {
+ int len = (int)STRLEN(ml_get(VIsual.lnum));
+
+ if (VIsual.col > len) {
+ VIsual.col = len;
+ VIsual.coladd = 0;
+ }
+ }
+}
+
+/// Make sure curwin->w_cursor is not on the NUL at the end of the line.
+/// Allow it when in Visual mode and 'selection' is not "old".
void adjust_cursor_col(void)
{
if (curwin->w_cursor.col > 0
&& (!VIsual_active || *p_sel == 'o')
&& gchar_cursor() == NUL) {
- --curwin->w_cursor.col;
+ curwin->w_cursor.col--;
}
}
-/*
- * When curwin->w_leftcol has changed, adjust the cursor position.
- * Return true if the cursor was moved.
- */
+/// When curwin->w_leftcol has changed, adjust the cursor position.
+///
+/// @return true if the cursor was moved.
bool leftcol_changed(void)
{
// TODO(hinidu): I think it should be colnr_T or int, but p_siso is long.
@@ -455,10 +443,8 @@ bool leftcol_changed(void)
lastcol = curwin->w_leftcol + curwin->w_width_inner - curwin_col_off() - 1;
validate_virtcol();
- /*
- * If the cursor is right or left of the screen, move it to last or first
- * character.
- */
+ // If the cursor is right or left of the screen, move it to last or first
+ // character.
if (curwin->w_virtcol > (colnr_T)(lastcol - p_siso)) {
retval = true;
coladvance((colnr_T)(lastcol - p_siso));
@@ -467,11 +453,9 @@ bool leftcol_changed(void)
coladvance((colnr_T)(curwin->w_leftcol + p_siso));
}
- /*
- * If the start of the character under the cursor is not on the screen,
- * advance the cursor one more char. If this fails (last char of the
- * line) adjust the scrolling.
- */
+ // If the start of the character under the cursor is not on the screen,
+ // advance the cursor one more char. If this fails (last char of the
+ // line) adjust the scrolling.
getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
if (e > (colnr_T)lastcol) {
retval = true;
@@ -493,30 +477,24 @@ bool leftcol_changed(void)
int gchar_cursor(void)
{
- return utf_ptr2char(get_cursor_pos_ptr());
+ return utf_ptr2char((char *)get_cursor_pos_ptr());
}
-/*
- * Write a character at the current cursor position.
- * It is directly written into the block.
- */
+/// Write a character at the current cursor position.
+/// It is directly written into the block.
void pchar_cursor(char_u c)
{
*(ml_get_buf(curbuf, curwin->w_cursor.lnum, true)
+ curwin->w_cursor.col) = c;
}
-/*
- * Return pointer to cursor line.
- */
+/// @return pointer to cursor line.
char_u *get_cursor_line_ptr(void)
{
return ml_get_buf(curbuf, curwin->w_cursor.lnum, false);
}
-/*
- * Return pointer to cursor position.
- */
+/// @return pointer to cursor position.
char_u *get_cursor_pos_ptr(void)
{
return ml_get_buf(curbuf, curwin->w_cursor.lnum, false) +