normal: use oap->motion_type also to represent block motion type

Previously oap->motion_type == MCHAR would be blockwise if
oap->block_mode was set.
This commit is contained in:
Björn Linse
2015-11-19 22:22:16 +01:00
parent 04cd3eef24
commit 303ac3f283
3 changed files with 108 additions and 110 deletions

View File

@@ -1601,7 +1601,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
if (VIsual_mode == Ctrl_V) { /* block mode */ if (VIsual_mode == Ctrl_V) { /* block mode */
colnr_T start, end; colnr_T start, end;
oap->block_mode = true; oap->motion_type = MBLOCK;
getvvcol(curwin, &(oap->start), getvvcol(curwin, &(oap->start),
&oap->start_vcol, NULL, &oap->end_vcol); &oap->start_vcol, NULL, &oap->end_vcol);
@@ -1711,11 +1711,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
*/ */
if (oap->motion_force == NUL || oap->motion_type == MLINE) if (oap->motion_force == NUL || oap->motion_type == MLINE)
oap->inclusive = true; oap->inclusive = true;
if (VIsual_mode == 'V') if (VIsual_mode == 'V') {
oap->motion_type = MLINE; oap->motion_type = MLINE;
else { } else if (VIsual_mode == 'v') {
oap->motion_type = MCHAR; oap->motion_type = MCHAR;
if (VIsual_mode != Ctrl_V && *ml_get_pos(&(oap->end)) == NUL if (*ml_get_pos(&(oap->end)) == NUL
&& (include_line_break || !virtual_op) && (include_line_break || !virtual_op)
) { ) {
oap->inclusive = false; oap->inclusive = false;
@@ -1780,7 +1780,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* oap->empty is set when start and end are the same. The inclusive * oap->empty is set when start and end are the same. The inclusive
* flag affects this too, unless yanking and the end is on a NUL. * flag affects this too, unless yanking and the end is on a NUL.
*/ */
oap->empty = (oap->motion_type == MCHAR oap->empty = (oap->motion_type != MLINE
&& (!oap->inclusive && (!oap->inclusive
|| (oap->op_type == OP_YANK || (oap->op_type == OP_YANK
&& gchar_pos(&oap->end) == NUL)) && gchar_pos(&oap->end) == NUL))
@@ -1810,14 +1810,13 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* first non-blank in the line, the operator becomes linewise * first non-blank in the line, the operator becomes linewise
* (strange, but that's the way vi does it). * (strange, but that's the way vi does it).
*/ */
if ( oap->motion_type == MCHAR if (oap->motion_type == MCHAR
&& oap->inclusive == false && oap->inclusive == false
&& !(cap->retval & CA_NO_ADJ_OP_END) && !(cap->retval & CA_NO_ADJ_OP_END)
&& oap->end.col == 0 && oap->end.col == 0
&& (!oap->is_VIsual || *p_sel == 'o') && (!oap->is_VIsual || *p_sel == 'o')
&& !oap->block_mode
&& oap->line_count > 1) { && oap->line_count > 1) {
oap->end_adjusted = true; /* remember that we did this */ oap->end_adjusted = true; // remember that we did this
--oap->line_count; --oap->line_count;
--oap->end.lnum; --oap->end.lnum;
if (inindent(0)) if (inindent(0))
@@ -2044,7 +2043,6 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
} else { } else {
curwin->w_cursor = old_cursor; curwin->w_cursor = old_cursor;
} }
oap->block_mode = false;
clearop(oap); clearop(oap);
} }
curwin->w_p_lbr = lbr_saved; curwin->w_p_lbr = lbr_saved;
@@ -2115,12 +2113,13 @@ static void op_function(oparg_T *oap)
/* Exclude the end position. */ /* Exclude the end position. */
decl(&curbuf->b_op_end); decl(&curbuf->b_op_end);
if (oap->block_mode) if (oap->motion_type == MBLOCK) {
argv[0] = (char_u *)"block"; argv[0] = (char_u *)"block";
else if (oap->motion_type == MLINE) } else if (oap->motion_type == MLINE) {
argv[0] = (char_u *)"line"; argv[0] = (char_u *)"line";
else } else {
argv[0] = (char_u *)"char"; argv[0] = (char_u *)"char";
}
/* Reset virtual_op so that 'virtualedit' can be changed in the /* Reset virtual_op so that 'virtualedit' can be changed in the
* function. */ * function. */

View File

@@ -14,28 +14,27 @@
* Arguments for operators. * Arguments for operators.
*/ */
typedef struct oparg_S { typedef struct oparg_S {
int op_type; /* current pending operator type */ int op_type; // current pending operator type
int regname; /* register to use for the operator */ int regname; // register to use for the operator
int motion_type; /* type of the current cursor motion */ int motion_type; // type of the current cursor motion
int motion_force; /* force motion type: 'v', 'V' or CTRL-V */ int motion_force; // force motion type: 'v', 'V' or CTRL-V
bool use_reg_one; /* true if delete uses reg 1 even when not bool use_reg_one; // true if delete uses reg 1 even when not
linewise */ // linewise
bool inclusive; /* true if char motion is inclusive (only bool inclusive; // true if char motion is inclusive (only
valid when motion_type is MCHAR */ // valid when motion_type is MCHAR)
bool end_adjusted; /* backuped b_op_end one char (only used by bool end_adjusted; // backuped b_op_end one char (only used by
do_format()) */ // do_format())
pos_T start; /* start of the operator */ pos_T start; // start of the operator
pos_T end; /* end of the operator */ pos_T end; // end of the operator
pos_T cursor_start; /* cursor position before motion for "gw" */ pos_T cursor_start; // cursor position before motion for "gw"
long line_count; /* number of lines from op_start to op_end long line_count; // number of lines from op_start to op_end
(inclusive) */ // (inclusive)
bool empty; /* op_start and op_end the same (only used by bool empty; // op_start and op_end the same (only used by
op_change()) */ // op_change())
bool is_VIsual; /* operator on Visual area */ bool is_VIsual; // operator on Visual area
bool block_mode; /* current operator is Visual block mode */ colnr_T start_vcol; // start col for block mode operator
colnr_T start_vcol; /* start col for block mode operator */ colnr_T end_vcol; // end col for block mode operator
colnr_T end_vcol; /* end col for block mode operator */
long prev_opcount; // ca.opcount saved for K_EVENT long prev_opcount; // ca.opcount saved for K_EVENT
long prev_count0; // ca.count0 saved for K_EVENT long prev_count0; // ca.count0 saved for K_EVENT
} oparg_T; } oparg_T;

View File

@@ -174,20 +174,20 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
(linenr_T)(oap->end.lnum + 1)) == FAIL) (linenr_T)(oap->end.lnum + 1)) == FAIL)
return; return;
if (oap->block_mode) if (oap->motion_type == MBLOCK) {
block_col = curwin->w_cursor.col; block_col = curwin->w_cursor.col;
}
for (i = oap->line_count - 1; i >= 0; i--) { for (i = oap->line_count - 1; i >= 0; i--) {
first_char = *get_cursor_line_ptr(); first_char = *get_cursor_line_ptr();
if (first_char == NUL) /* empty line */ if (first_char == NUL) { // empty line
curwin->w_cursor.col = 0; curwin->w_cursor.col = 0;
else if (oap->block_mode) } else if (oap->motion_type == MBLOCK) {
shift_block(oap, amount); shift_block(oap, amount);
else } else if (first_char != '#' || !preprocs_left()) {
/* Move the line right if it doesn't start with '#', 'smartindent' // Move the line right if it doesn't start with '#', 'smartindent'
* isn't set or 'cindent' isn't set or '#' isn't in 'cino'. */ // isn't set or 'cindent' isn't set or '#' isn't in 'cino'.
if (first_char != '#' || !preprocs_left()) { shift_line(oap->op_type == OP_LSHIFT, p_sr, amount, false);
shift_line(oap->op_type == OP_LSHIFT, p_sr, amount, FALSE);
} }
++curwin->w_cursor.lnum; ++curwin->w_cursor.lnum;
} }
@@ -196,7 +196,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
/* The cursor line is not in a closed fold */ /* The cursor line is not in a closed fold */
foldOpenCursor(); foldOpenCursor();
if (oap->block_mode) { if (oap->motion_type == MBLOCK) {
curwin->w_cursor.lnum = oap->start.lnum; curwin->w_cursor.lnum = oap->start.lnum;
curwin->w_cursor.col = block_col; curwin->w_cursor.col = block_col;
} else if (curs_top) { /* put cursor on first line, for ">>" */ } else if (curs_top) { /* put cursor on first line, for ">>" */
@@ -1275,8 +1275,9 @@ cmdline_paste_reg (
|| (i < reg->y_size - 1 || (i < reg->y_size - 1
&& !(remcr && !(remcr
&& i == reg->y_size - 2 && i == reg->y_size - 2
&& *reg->y_array[i + 1] == NUL))) && *reg->y_array[i + 1] == NUL))) {
cmdline_paste_str((char_u *)"\r", literally); cmdline_paste_str((char_u *)"\r", literally);
}
/* Check for CTRL-C, in case someone tries to paste a few thousand /* Check for CTRL-C, in case someone tries to paste a few thousand
* lines and gets bored. */ * lines and gets bored. */
@@ -1321,9 +1322,8 @@ int op_delete(oparg_T *oap)
* line and motion_type == MCHAR and the result is a blank line, make the * line and motion_type == MCHAR and the result is a blank line, make the
* delete linewise. Don't do this for the change command or Visual mode. * delete linewise. Don't do this for the change command or Visual mode.
*/ */
if ( oap->motion_type == MCHAR if (oap->motion_type == MCHAR
&& !oap->is_VIsual && !oap->is_VIsual
&& !oap->block_mode
&& oap->line_count > 1 && oap->line_count > 1
&& oap->motion_force == NUL && oap->motion_force == NUL
&& oap->op_type == OP_DELETE) { && oap->op_type == OP_DELETE) {
@@ -1339,20 +1339,20 @@ int op_delete(oparg_T *oap)
* Check for trying to delete (e.g. "D") in an empty line. * Check for trying to delete (e.g. "D") in an empty line.
* Note: For the change operator it is ok. * Note: For the change operator it is ok.
*/ */
if ( oap->motion_type == MCHAR if (oap->motion_type != MLINE
&& oap->line_count == 1 && oap->line_count == 1
&& oap->op_type == OP_DELETE && oap->op_type == OP_DELETE
&& *ml_get(oap->start.lnum) == NUL) { && *ml_get(oap->start.lnum) == NUL) {
/* // It's an error to operate on an empty region, when 'E' included in
* It's an error to operate on an empty region, when 'E' included in // 'cpoptions' (Vi compatible).
* 'cpoptions' (Vi compatible). if (virtual_op) {
*/ // Virtual editing: Nothing gets deleted, but we set the '[ and ']
if (virtual_op) // marks as if it happened.
/* Virtual editing: Nothing gets deleted, but we set the '[ and ']
* marks as if it happened. */
goto setmarks; goto setmarks;
if (vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL) }
if (vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL) {
beep_flush(); beep_flush();
}
return OK; return OK;
} }
@@ -1403,10 +1403,11 @@ int op_delete(oparg_T *oap)
/* /*
* block mode delete * block mode delete
*/ */
if (oap->block_mode) { if (oap->motion_type == MBLOCK) {
if (u_save((linenr_T)(oap->start.lnum - 1), if (u_save((linenr_T)(oap->start.lnum - 1),
(linenr_T)(oap->end.lnum + 1)) == FAIL) (linenr_T)(oap->end.lnum + 1)) == FAIL) {
return FAIL; return FAIL;
}
for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; ++lnum) { for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; ++lnum) {
block_prep(oap, &bd, lnum, TRUE); block_prep(oap, &bd, lnum, TRUE);
@@ -1594,7 +1595,7 @@ int op_delete(oparg_T *oap)
msgmore(curbuf->b_ml.ml_line_count - old_lcount); msgmore(curbuf->b_ml.ml_line_count - old_lcount);
setmarks: setmarks:
if (oap->block_mode) { if (oap->motion_type == MBLOCK) {
curbuf->b_op_end.lnum = oap->end.lnum; curbuf->b_op_end.lnum = oap->end.lnum;
curbuf->b_op_end.col = oap->start.col; curbuf->b_op_end.col = oap->start.col;
} else } else
@@ -1655,7 +1656,7 @@ int op_replace(oparg_T *oap, int c)
/* /*
* block mode replace * block mode replace
*/ */
if (oap->block_mode) { if (oap->motion_type == MBLOCK) {
bd.is_MAX = (curwin->w_curswant == MAXCOL); bd.is_MAX = (curwin->w_curswant == MAXCOL);
for (; curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum) { for (; curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum) {
curwin->w_cursor.col = 0; /* make sure cursor position is valid */ curwin->w_cursor.col = 0; /* make sure cursor position is valid */
@@ -1837,7 +1838,7 @@ void op_tilde(oparg_T *oap)
return; return;
pos = oap->start; pos = oap->start;
if (oap->block_mode) { /* Visual block mode */ if (oap->motion_type == MBLOCK) { // Visual block mode
for (; pos.lnum <= oap->end.lnum; ++pos.lnum) { for (; pos.lnum <= oap->end.lnum; ++pos.lnum) {
int one_change; int one_change;
@@ -1999,11 +2000,11 @@ void op_insert(oparg_T *oap, long count1)
curwin->w_cursor.lnum = oap->start.lnum; curwin->w_cursor.lnum = oap->start.lnum;
update_screen(INVERTED); update_screen(INVERTED);
if (oap->block_mode) { if (oap->motion_type == MBLOCK) {
/* When 'virtualedit' is used, need to insert the extra spaces before // When 'virtualedit' is used, need to insert the extra spaces before
* doing block_prep(). When only "block" is used, virtual edit is // doing block_prep(). When only "block" is used, virtual edit is
* already disabled, but still need it when calling // already disabled, but still need it when calling
* coladvance_force(). */ // coladvance_force().
if (curwin->w_cursor.coladd > 0) { if (curwin->w_cursor.coladd > 0) {
int old_ve_flags = ve_flags; int old_ve_flags = ve_flags;
@@ -2025,7 +2026,7 @@ void op_insert(oparg_T *oap, long count1)
} }
if (oap->op_type == OP_APPEND) { if (oap->op_type == OP_APPEND) {
if (oap->block_mode if (oap->motion_type == MBLOCK
&& curwin->w_cursor.coladd == 0 && curwin->w_cursor.coladd == 0
) { ) {
/* Move the cursor to the character right of the block. */ /* Move the cursor to the character right of the block. */
@@ -2061,7 +2062,7 @@ void op_insert(oparg_T *oap, long count1)
if (curwin->w_cursor.lnum != oap->start.lnum || got_int) if (curwin->w_cursor.lnum != oap->start.lnum || got_int)
return; return;
if (oap->block_mode) { if (oap->motion_type == MBLOCK) {
struct block_def bd2; struct block_def bd2;
/* The user may have moved the cursor before inserting something, try /* The user may have moved the cursor before inserting something, try
@@ -2166,13 +2167,14 @@ int op_change(oparg_T *oap)
&& !virtual_op) && !virtual_op)
inc_cursor(); inc_cursor();
/* check for still on same line (<CR> in inserted text meaningless) */ // check for still on same line (<CR> in inserted text meaningless)
/* skip blank lines too */ // skip blank lines too
if (oap->block_mode) { if (oap->motion_type == MBLOCK) {
/* Add spaces before getting the current line length. */ // Add spaces before getting the current line length.
if (virtual_op && (curwin->w_cursor.coladd > 0 if (virtual_op && (curwin->w_cursor.coladd > 0
|| gchar_cursor() == NUL)) || gchar_cursor() == NUL)) {
coladvance_force(getviscol()); coladvance_force(getviscol());
}
firstline = ml_get(oap->start.lnum); firstline = ml_get(oap->start.lnum);
pre_textlen = (long)STRLEN(firstline); pre_textlen = (long)STRLEN(firstline);
pre_indent = (long)(skipwhite(firstline) - firstline); pre_indent = (long)(skipwhite(firstline) - firstline);
@@ -2189,9 +2191,10 @@ int op_change(oparg_T *oap)
* block. * block.
* Don't repeat the insert when Insert mode ended with CTRL-C. * Don't repeat the insert when Insert mode ended with CTRL-C.
*/ */
if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int) { if (oap->motion_type == MBLOCK
/* Auto-indenting may have changed the indent. If the cursor was past && oap->start.lnum != oap->end.lnum && !got_int) {
* the indent, exclude that indent change from the inserted text. */ // Auto-indenting may have changed the indent. If the cursor was past
// the indent, exclude that indent change from the inserted text.
firstline = ml_get(oap->start.lnum); firstline = ml_get(oap->start.lnum);
if (bd.textcol > (colnr_T)pre_indent) { if (bd.textcol > (colnr_T)pre_indent) {
long new_indent = (long)(skipwhite(firstline) - firstline); long new_indent = (long)(skipwhite(firstline) - firstline);
@@ -2332,11 +2335,10 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
* If the cursor was in column 1 before and after the movement, and the * If the cursor was in column 1 before and after the movement, and the
* operator is not inclusive, the yank is always linewise. * operator is not inclusive, the yank is always linewise.
*/ */
if ( oap->motion_type == MCHAR if (oap->motion_type == MCHAR
&& oap->start.col == 0 && oap->start.col == 0
&& !oap->inclusive && !oap->inclusive
&& (!oap->is_VIsual || *p_sel == 'o') && (!oap->is_VIsual || *p_sel == 'o')
&& !oap->block_mode
&& oap->end.col == 0 && oap->end.col == 0
&& yanklines > 1) { && yanklines > 1) {
yanktype = MLINE; yanktype = MLINE;
@@ -2354,9 +2356,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
y_idx = 0; y_idx = 0;
lnum = oap->start.lnum; lnum = oap->start.lnum;
if (oap->block_mode) { if (yanktype == MBLOCK) {
/* Visual block mode */ // Visual block mode
reg->y_type = MBLOCK; /* set the yank register type */
reg->y_width = oap->end_vcol - oap->start_vcol; reg->y_width = oap->end_vcol - oap->start_vcol;
if (curwin->w_curswant == MAXCOL && reg->y_width > 0) if (curwin->w_curswant == MAXCOL && reg->y_width > 0)
@@ -2470,36 +2471,35 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
if (curwin->w_p_rnu) { if (curwin->w_p_rnu) {
redraw_later(SOME_VALID); // cursor moved to start redraw_later(SOME_VALID); // cursor moved to start
} }
if (message) { /* Display message about yank? */ if (message) { // Display message about yank?
if (yanktype == MCHAR if (yanktype == MCHAR && yanklines == 1) {
&& !oap->block_mode
&& yanklines == 1)
yanklines = 0; yanklines = 0;
/* Some versions of Vi use ">=" here, some don't... */ }
// Some versions of Vi use ">=" here, some don't...
if (yanklines > p_report) { if (yanklines > p_report) {
/* redisplay now, so message is not deleted */ // redisplay now, so message is not deleted
update_topline_redraw(); update_topline_redraw();
if (yanklines == 1) { if (yanklines == 1) {
if (oap->block_mode) if (yanktype == MBLOCK) {
MSG(_("block of 1 line yanked")); MSG(_("block of 1 line yanked"));
else } else {
MSG(_("1 line yanked")); MSG(_("1 line yanked"));
} else if (oap->block_mode) }
} else if (yanktype == MBLOCK) {
smsg(_("block of %" PRId64 " lines yanked"), smsg(_("block of %" PRId64 " lines yanked"),
(int64_t)yanklines); (int64_t)yanklines);
else } else {
smsg(_("%" PRId64 " lines yanked"), (int64_t)yanklines); smsg(_("%" PRId64 " lines yanked"), (int64_t)yanklines);
} }
} }
}
/* /*
* Set "'[" and "']" marks. * Set "'[" and "']" marks.
*/ */
curbuf->b_op_start = oap->start; curbuf->b_op_start = oap->start;
curbuf->b_op_end = oap->end; curbuf->b_op_end = oap->end;
if (yanktype == MLINE if (yanktype == MLINE) {
&& !oap->block_mode
) {
curbuf->b_op_start.col = 0; curbuf->b_op_start.col = 0;
curbuf->b_op_end.col = MAXCOL; curbuf->b_op_end.col = MAXCOL;
} }
@@ -4903,7 +4903,7 @@ void cursor_pos_info(void)
/* Make 'sbr' empty for a moment to get the correct size. */ /* Make 'sbr' empty for a moment to get the correct size. */
p_sbr = empty_option; p_sbr = empty_option;
oparg.is_VIsual = true; oparg.is_VIsual = true;
oparg.block_mode = true; oparg.motion_type = MBLOCK;
oparg.op_type = OP_NOP; oparg.op_type = OP_NOP;
getvcols(curwin, &min_pos, &max_pos, getvcols(curwin, &min_pos, &max_pos,
&oparg.start_vcol, &oparg.end_vcol); &oparg.start_vcol, &oparg.end_vcol);