Skip to content

Commit d9d8cbb

Browse files
brammooldouglasdrumond
authored andcommitted
patch 7.4.765 Problem: CTRL-A and CTRL-X in Visual mode do not always work well. Solution: Improvements for increment and decrement. (Christian Brabandt)
1 parent 154afff commit d9d8cbb

File tree

5 files changed

+446
-31
lines changed

5 files changed

+446
-31
lines changed

src/normal.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4209,7 +4209,24 @@ nv_addsub(cap)
42094209
int visual = VIsual_active;
42104210
if (cap->oap->op_type == OP_NOP
42114211
&& do_addsub((int)cap->cmdchar, cap->count1, cap->arg) == OK)
4212-
prep_redo_cmd(cap);
4212+
{
4213+
if (visual)
4214+
{
4215+
ResetRedobuff();
4216+
AppendCharToRedobuff(VIsual_mode);
4217+
if (VIsual_mode == 'V')
4218+
{
4219+
AppendNumberToRedobuff(cap->oap->line_count);
4220+
AppendCharToRedobuff('j');
4221+
}
4222+
AppendNumberToRedobuff(cap->count1);
4223+
if (cap->nchar != NUL)
4224+
AppendCharToRedobuff(cap->nchar);
4225+
AppendCharToRedobuff(cap->cmdchar);
4226+
}
4227+
else
4228+
prep_redo_cmd(cap);
4229+
}
42134230
else
42144231
clearopbeep(cap->oap);
42154232
if (visual)

src/ops.c

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5386,7 +5386,7 @@ do_addsub(command, Prenum1, g_cmd)
53865386
int hex; /* 'X' or 'x': hex; '0': octal */
53875387
static int hexupper = FALSE; /* 0xABC */
53885388
unsigned long n;
5389-
long offset = 0; /* line offset for Ctrl_V mode */
5389+
unsigned long offset = 0; /* line offset for Ctrl_V mode */
53905390
long_u oldn;
53915391
char_u *ptr;
53925392
int c;
@@ -5398,10 +5398,12 @@ do_addsub(command, Prenum1, g_cmd)
53985398
int firstdigit;
53995399
int subtract;
54005400
int negative = FALSE;
5401+
int was_positive = TRUE;
54015402
int visual = VIsual_active;
54025403
int i;
54035404
int lnum = curwin->w_cursor.lnum;
54045405
int lnume = curwin->w_cursor.lnum;
5406+
int startcol;
54055407

54065408
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); /* "heX" */
54075409
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); /* "Octal" */
@@ -5431,14 +5433,14 @@ do_addsub(command, Prenum1, g_cmd)
54315433
curbuf->b_visual.vi_end = curwin->w_cursor;
54325434
curbuf->b_visual.vi_mode = VIsual_mode;
54335435

5434-
col = VIsual.col;
5436+
if (VIsual_mode != 'v')
5437+
startcol = VIsual.col < curwin->w_cursor.col ? VIsual.col
5438+
: curwin->w_cursor.col;
5439+
else
5440+
startcol = VIsual.col;
5441+
col = startcol;
54355442
lnum = VIsual.lnum;
54365443
lnume = curwin->w_cursor.lnum;
5437-
if (ptr[col] == '-')
5438-
{
5439-
negative = TRUE;
5440-
col++;
5441-
}
54425444
}
54435445
else
54445446
{
@@ -5481,9 +5483,16 @@ do_addsub(command, Prenum1, g_cmd)
54815483
{
54825484
curwin->w_cursor.lnum = i;
54835485
ptr = ml_get_curline();
5484-
RLADDSUBFIX(ptr);
54855486
if ((int)STRLEN(ptr) <= col)
5486-
col = 0;
5487+
/* try again on next line */
5488+
continue;
5489+
if (visual && ptr[col] == '-')
5490+
{
5491+
negative = TRUE;
5492+
was_positive = FALSE;
5493+
col++;
5494+
}
5495+
RLADDSUBFIX(ptr);
54875496
/*
54885497
* If a number was found, and saving for undo works, replace the number.
54895498
*/
@@ -5598,6 +5607,14 @@ do_addsub(command, Prenum1, g_cmd)
55985607
negative = FALSE;
55995608
}
56005609

5610+
if (visual && !was_positive && !negative)
5611+
{
5612+
/* need to remove the '-' */
5613+
col--;
5614+
length++;
5615+
}
5616+
5617+
56015618
/*
56025619
* Delete the old number.
56035620
*/
@@ -5634,8 +5651,7 @@ do_addsub(command, Prenum1, g_cmd)
56345651
if (buf1 == NULL)
56355652
return FAIL;
56365653
ptr = buf1;
5637-
/* do not add leading '-' for visual mode */
5638-
if (negative && !visual)
5654+
if (negative && (!visual || (visual && was_positive)))
56395655
{
56405656
*ptr++ = '-';
56415657
}
@@ -5654,23 +5670,15 @@ do_addsub(command, Prenum1, g_cmd)
56545670
* Put the number characters in buf2[].
56555671
*/
56565672
if (hex == 0)
5657-
sprintf((char *)buf2, "%lu", n + offset);
5673+
sprintf((char *)buf2, "%lu", n);
56585674
else if (hex == '0')
5659-
sprintf((char *)buf2, "%lo", n + offset);
5675+
sprintf((char *)buf2, "%lo", n);
56605676
else if (hex && hexupper)
5661-
sprintf((char *)buf2, "%lX", n + offset);
5677+
sprintf((char *)buf2, "%lX", n);
56625678
else
5663-
sprintf((char *)buf2, "%lx", n + offset);
5679+
sprintf((char *)buf2, "%lx", n);
56645680
length -= (int)STRLEN(buf2);
56655681

5666-
if (g_cmd)
5667-
{
5668-
if (subtract)
5669-
offset -= (unsigned long)Prenum1;
5670-
else
5671-
offset += (unsigned long)Prenum1;
5672-
}
5673-
56745682
/*
56755683
* Adjust number of zeros to the new number of digits, so the
56765684
* total length of the number remains the same.
@@ -5685,13 +5693,27 @@ do_addsub(command, Prenum1, g_cmd)
56855693
ins_str(buf1); /* insert the new number */
56865694
vim_free(buf1);
56875695
}
5688-
--curwin->w_cursor.col;
5696+
5697+
if (g_cmd)
5698+
{
5699+
offset = (unsigned long)Prenum1;
5700+
g_cmd = 0;
5701+
}
5702+
/* reset */
5703+
subtract = FALSE;
5704+
negative = FALSE;
5705+
if (visual && VIsual_mode != Ctrl_V)
5706+
col = 0;
5707+
else
5708+
col = startcol;
5709+
Prenum1 += offset;
56895710
curwin->w_set_curswant = TRUE;
56905711
#ifdef FEAT_RIGHTLEFT
56915712
ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
56925713
RLADDSUBFIX(ptr);
56935714
#endif
56945715
}
5716+
--curwin->w_cursor.col;
56955717
return OK;
56965718
}
56975719

0 commit comments

Comments
 (0)