mirror of
https://github.com/neovim/neovim.git
synced 2026-07-14 13:20:35 +00:00
refactor(core): group Visual-mode globals in VisualExtent #40722
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "nvim/insert_defs.h"
|
||||
#include "nvim/macros_defs.h"
|
||||
#include "nvim/menu_defs.h"
|
||||
#include "nvim/normal_defs.h"
|
||||
#include "nvim/os/os_defs.h"
|
||||
#include "nvim/runtime_defs.h"
|
||||
#include "nvim/state_defs.h"
|
||||
@@ -472,10 +473,9 @@ EXTERN int VIsual_mode INIT( = 'v');
|
||||
/// true when redoing Visual.
|
||||
EXTERN bool redo_VIsual_busy INIT( = false);
|
||||
|
||||
// The Visual area is remembered for reselection.
|
||||
EXTERN int resel_VIsual_mode INIT( = NUL); // 'v', 'V', or Ctrl-V
|
||||
EXTERN linenr_T resel_VIsual_line_count; // number of lines
|
||||
EXTERN colnr_T resel_VIsual_vcol; // nr of cols or end col
|
||||
// Remember the previous Visual area, for reselection ("gv"). Also seeds operator-redo.
|
||||
// mode == NUL: no previous Visual area.
|
||||
EXTERN VisualExtent resel_VIsual;
|
||||
|
||||
/// When pasting text with the middle mouse button in visual mode with
|
||||
/// restart_edit set, remember where it started so we can set Ins.start.
|
||||
|
||||
@@ -5039,7 +5039,7 @@ static void nv_visual(cmdarg_T *cap)
|
||||
}
|
||||
redraw_curbuf_later(UPD_INVERTED); // update the inversion
|
||||
} else { // start Visual mode
|
||||
if (cap->count0 > 0 && resel_VIsual_mode != NUL) {
|
||||
if (cap->count0 > 0 && resel_VIsual.mode != NUL) {
|
||||
// use previously selected part
|
||||
VIsual = curwin->w_cursor;
|
||||
|
||||
@@ -5055,25 +5055,25 @@ static void nv_visual(cmdarg_T *cap)
|
||||
}
|
||||
// For V and ^V, we multiply the number of lines even if there
|
||||
// was only one -- webb
|
||||
if (resel_VIsual_mode != 'v' || resel_VIsual_line_count > 1) {
|
||||
curwin->w_cursor.lnum += resel_VIsual_line_count * cap->count0 - 1;
|
||||
if (resel_VIsual.mode != 'v' || resel_VIsual.line_count > 1) {
|
||||
curwin->w_cursor.lnum += resel_VIsual.line_count * cap->count0 - 1;
|
||||
check_cursor(curwin);
|
||||
}
|
||||
VIsual_mode = resel_VIsual_mode;
|
||||
VIsual_mode = resel_VIsual.mode;
|
||||
if (VIsual_mode == 'v') {
|
||||
if (resel_VIsual_line_count <= 1) {
|
||||
if (resel_VIsual.line_count <= 1) {
|
||||
update_curswant_force();
|
||||
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
|
||||
curwin->w_curswant += resel_VIsual_vcol * cap->count0;
|
||||
curwin->w_curswant += resel_VIsual.vcol * cap->count0;
|
||||
if (*p_sel != 'e') {
|
||||
curwin->w_curswant--;
|
||||
}
|
||||
} else {
|
||||
curwin->w_curswant = resel_VIsual_vcol;
|
||||
curwin->w_curswant = resel_VIsual.vcol;
|
||||
}
|
||||
coladvance(curwin, curwin->w_curswant);
|
||||
}
|
||||
if (resel_VIsual_vcol == MAXCOL) {
|
||||
if (resel_VIsual.vcol == MAXCOL) {
|
||||
curwin->w_curswant = MAXCOL;
|
||||
coladvance(curwin, MAXCOL);
|
||||
} else if (VIsual_mode == Ctrl_V) {
|
||||
@@ -5082,7 +5082,7 @@ static void nv_visual(cmdarg_T *cap)
|
||||
curwin->w_cursor.lnum = VIsual.lnum;
|
||||
update_curswant_force();
|
||||
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
|
||||
curwin->w_curswant += resel_VIsual_vcol * cap->count0 - 1;
|
||||
curwin->w_curswant += resel_VIsual.vcol * cap->count0 - 1;
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
if (*p_sel == 'e') {
|
||||
curwin->w_curswant++;
|
||||
|
||||
@@ -66,6 +66,17 @@ enum {
|
||||
CA_NO_ADJ_OP_END = 2, ///< don't adjust operator end
|
||||
};
|
||||
|
||||
/// A Visual selection's mode and extent (line/column span, not absolute positions), so it can be
|
||||
/// re-applied starting at the cursor: for "gv" reselect (`resel_VIsual`) and Visual-operator redo
|
||||
/// (`redo_VIsual`).
|
||||
typedef struct {
|
||||
int mode; ///< 'v', 'V', or Ctrl-V
|
||||
linenr_T line_count; ///< number of lines
|
||||
colnr_T vcol; ///< number of cols or end column (MAXCOL: to end of line)
|
||||
int count; ///< count for the Visual operator
|
||||
int arg; ///< extra argument
|
||||
} VisualExtent;
|
||||
|
||||
/// Replacement for nchar used by nv_replace().
|
||||
enum {
|
||||
REPLACE_CR_NCHAR = -1,
|
||||
|
||||
@@ -3259,15 +3259,6 @@ static void get_op_vcol(oparg_T *oap, colnr_T redo_VIsual_vcol, bool initial)
|
||||
oap->start = curwin->w_cursor;
|
||||
}
|
||||
|
||||
/// Information for redoing the previous Visual selection.
|
||||
typedef struct {
|
||||
int rv_mode; ///< 'v', 'V', or Ctrl-V
|
||||
linenr_T rv_line_count; ///< number of lines
|
||||
colnr_T rv_vcol; ///< number of cols or end column
|
||||
int rv_count; ///< count for Visual operator
|
||||
int rv_arg; ///< extra argument
|
||||
} redo_VIsual_T;
|
||||
|
||||
static bool is_ex_cmdchar(cmdarg_T *cap)
|
||||
{
|
||||
return cap->cmdchar == ':' || cap->cmdchar == K_COMMAND;
|
||||
@@ -3281,7 +3272,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
int lbr_saved = curwin->w_p_lbr;
|
||||
|
||||
// The visual area is remembered for redo
|
||||
static redo_VIsual_T redo_VIsual = { NUL, 0, 0, 0, 0 };
|
||||
static VisualExtent redo_VIsual = { NUL, 0, 0, 0, 0 };
|
||||
|
||||
pos_T old_cursor = curwin->w_cursor;
|
||||
|
||||
@@ -3370,25 +3361,25 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
|
||||
if (redo_VIsual_busy) {
|
||||
// Redo of an operation on a Visual area. Use the same size from
|
||||
// redo_VIsual.rv_line_count and redo_VIsual.rv_vcol.
|
||||
// redo_VIsual.line_count and redo_VIsual.vcol.
|
||||
oap->start = curwin->w_cursor;
|
||||
curwin->w_cursor.lnum += redo_VIsual.rv_line_count - 1;
|
||||
curwin->w_cursor.lnum += redo_VIsual.line_count - 1;
|
||||
curwin->w_cursor.lnum = MIN(curwin->w_cursor.lnum, curbuf->b_ml.ml_line_count);
|
||||
VIsual_mode = redo_VIsual.rv_mode;
|
||||
if (redo_VIsual.rv_vcol == MAXCOL || VIsual_mode == 'v') {
|
||||
VIsual_mode = redo_VIsual.mode;
|
||||
if (redo_VIsual.vcol == MAXCOL || VIsual_mode == 'v') {
|
||||
if (VIsual_mode == 'v') {
|
||||
if (redo_VIsual.rv_line_count <= 1) {
|
||||
if (redo_VIsual.line_count <= 1) {
|
||||
validate_virtcol(curwin);
|
||||
curwin->w_curswant = curwin->w_virtcol + redo_VIsual.rv_vcol - 1;
|
||||
curwin->w_curswant = curwin->w_virtcol + redo_VIsual.vcol - 1;
|
||||
} else {
|
||||
curwin->w_curswant = redo_VIsual.rv_vcol;
|
||||
curwin->w_curswant = redo_VIsual.vcol;
|
||||
}
|
||||
} else {
|
||||
curwin->w_curswant = MAXCOL;
|
||||
}
|
||||
coladvance(curwin, curwin->w_curswant);
|
||||
}
|
||||
cap->count0 = redo_VIsual.rv_count;
|
||||
cap->count0 = redo_VIsual.count;
|
||||
cap->count1 = (cap->count0 == 0 ? 1 : cap->count0);
|
||||
} else if (VIsual_active) {
|
||||
if (!gui_yank) {
|
||||
@@ -3473,14 +3464,14 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
virtual_op = virtual_active(curwin);
|
||||
|
||||
if (VIsual_active || redo_VIsual_busy) {
|
||||
get_op_vcol(oap, redo_VIsual.rv_vcol, true);
|
||||
get_op_vcol(oap, redo_VIsual.vcol, true);
|
||||
|
||||
if (!redo_VIsual_busy && !gui_yank) {
|
||||
// Prepare to reselect and redo Visual: this is based on the
|
||||
// size of the Visual text
|
||||
resel_VIsual_mode = VIsual_mode;
|
||||
resel_VIsual.mode = VIsual_mode;
|
||||
if (curwin->w_curswant == MAXCOL) {
|
||||
resel_VIsual_vcol = MAXCOL;
|
||||
resel_VIsual.vcol = MAXCOL;
|
||||
} else {
|
||||
if (VIsual_mode != Ctrl_V) {
|
||||
getvvcol(curwin, &(oap->end), NULL, NULL, &oap->end_vcol, 0);
|
||||
@@ -3489,12 +3480,12 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
if (VIsual_mode != Ctrl_V) {
|
||||
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, NULL, 0);
|
||||
}
|
||||
resel_VIsual_vcol = oap->end_vcol - oap->start_vcol + 1;
|
||||
resel_VIsual.vcol = oap->end_vcol - oap->start_vcol + 1;
|
||||
} else {
|
||||
resel_VIsual_vcol = oap->end_vcol;
|
||||
resel_VIsual.vcol = oap->end_vcol;
|
||||
}
|
||||
}
|
||||
resel_VIsual_line_count = oap->line_count;
|
||||
resel_VIsual.line_count = oap->line_count;
|
||||
}
|
||||
|
||||
// can't redo yank (unless 'y' is in 'cpoptions') and ":"
|
||||
@@ -3535,11 +3526,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
}
|
||||
}
|
||||
if (!redo_VIsual_busy) {
|
||||
redo_VIsual.rv_mode = resel_VIsual_mode;
|
||||
redo_VIsual.rv_vcol = resel_VIsual_vcol;
|
||||
redo_VIsual.rv_line_count = resel_VIsual_line_count;
|
||||
redo_VIsual.rv_count = cap->count0;
|
||||
redo_VIsual.rv_arg = cap->arg;
|
||||
redo_VIsual = resel_VIsual;
|
||||
redo_VIsual.count = cap->count0;
|
||||
redo_VIsual.arg = cap->arg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3794,7 +3783,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
break;
|
||||
|
||||
case OP_FUNCTION: {
|
||||
redo_VIsual_T save_redo_VIsual = redo_VIsual;
|
||||
VisualExtent save_redo_VIsual = redo_VIsual;
|
||||
|
||||
// Restore linebreak, so that when the user edits it looks as before.
|
||||
restore_lbr(lbr_saved);
|
||||
@@ -3889,7 +3878,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
} else {
|
||||
VIsual_active = true;
|
||||
restore_lbr(lbr_saved);
|
||||
op_addsub(oap, (linenr_T)cap->count1, redo_VIsual.rv_arg);
|
||||
op_addsub(oap, (linenr_T)cap->count1, redo_VIsual.arg);
|
||||
VIsual_active = false;
|
||||
}
|
||||
check_cursor_col(curwin);
|
||||
|
||||
Reference in New Issue
Block a user