vim-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)

9bb1930af9
This commit is contained in:
watiko 2016-01-14 18:49:35 +09:00
parent 6d1b948b6b
commit 5ef1cb5c2e
5 changed files with 441 additions and 28 deletions

View File

@ -3506,7 +3506,21 @@ static void nv_addsub(cmdarg_T *cap)
bool visual = VIsual_active; bool visual = VIsual_active;
if (cap->oap->op_type == OP_NOP if (cap->oap->op_type == OP_NOP
&& do_addsub((int)cap->cmdchar, cap->count1, cap->arg) == OK) { && do_addsub((int)cap->cmdchar, cap->count1, cap->arg) == OK) {
prep_redo_cmd(cap); if (visual) {
ResetRedobuff();
AppendCharToRedobuff(VIsual_mode);
if (VIsual_mode == 'V') {
AppendNumberToRedobuff(cap->oap->line_count);
AppendCharToRedobuff('j');
}
AppendNumberToRedobuff(cap->count1);
if (cap->nchar != NUL) {
AppendCharToRedobuff(cap->nchar);
}
AppendCharToRedobuff(cap->cmdchar);
} else {
prep_redo_cmd(cap);
}
} else { } else {
clearopbeep(cap->oap); clearopbeep(cap->oap);
} }

View File

@ -4213,7 +4213,7 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin
static bool hexupper = false; // 0xABC static bool hexupper = false; // 0xABC
unsigned long n; unsigned long n;
long offset = 0; unsigned long offset = 0;
unsigned long oldn; unsigned long oldn;
char_u *ptr; char_u *ptr;
int c; int c;
@ -4226,9 +4226,11 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
int firstdigit; int firstdigit;
bool subtract; bool subtract;
bool negative = false; bool negative = false;
bool was_positive = true;
bool visual = VIsual_active; bool visual = VIsual_active;
int lnum = curwin->w_cursor.lnum; int lnum = curwin->w_cursor.lnum;
int lnume = curwin->w_cursor.lnum; int lnume = curwin->w_cursor.lnum;
int startcol;
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX" dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX"
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal" dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal"
@ -4255,13 +4257,16 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
curbuf->b_visual.vi_end = curwin->w_cursor; curbuf->b_visual.vi_end = curwin->w_cursor;
curbuf->b_visual.vi_mode = VIsual_mode; curbuf->b_visual.vi_mode = VIsual_mode;
col = VIsual.col; if (VIsual_mode != 'v') {
startcol = VIsual.col < curwin->w_cursor.col
? VIsual.col : curwin->w_cursor.col;
} else {
startcol = VIsual.col;
}
col = startcol;
lnum = VIsual.lnum; lnum = VIsual.lnum;
lnume = curwin->w_cursor.lnum; lnume = curwin->w_cursor.lnum;
if (ptr[col] == '-') {
negative = true;
col++;
}
} else { } else {
ptr = get_cursor_line_ptr(); ptr = get_cursor_line_ptr();
RLADDSUBFIX(ptr); RLADDSUBFIX(ptr);
@ -4328,10 +4333,16 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
for (int i = lnum; i <= lnume; i++) { for (int i = lnum; i <= lnume; i++) {
curwin->w_cursor.lnum = i; curwin->w_cursor.lnum = i;
ptr = get_cursor_line_ptr(); ptr = get_cursor_line_ptr();
RLADDSUBFIX(ptr);
if ((int)STRLEN(ptr) <= col) { if ((int)STRLEN(ptr) <= col) {
col = 0; // try again on next line
continue;
} }
if (visual && ptr[col] == '-') {
negative = true;
was_positive = false;
col++;
}
RLADDSUBFIX(ptr);
// If a number was found, and saving for undo works, replace the number. // If a number was found, and saving for undo works, replace the number.
firstdigit = ptr[col]; firstdigit = ptr[col];
RLADDSUBFIX(ptr); RLADDSUBFIX(ptr);
@ -4424,6 +4435,12 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
} }
} }
if (visual && !was_positive && !negative) {
// need to remove the '-'
col--;
length++;
}
// Delete the old number. // Delete the old number.
curwin->w_cursor.col = col; curwin->w_cursor.col = col;
todel = length; todel = length;
@ -4452,8 +4469,7 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
// Allocate a bit too much. // Allocate a bit too much.
buf1 = xmalloc(length + NUMBUFLEN); buf1 = xmalloc(length + NUMBUFLEN);
ptr = buf1; ptr = buf1;
// do not add leading '-' for visual mode' if (negative && (!visual || (visual && was_positive))) {
if (negative && !visual) {
*ptr++ = '-'; *ptr++ = '-';
} }
if (pre) { if (pre) {
@ -4483,21 +4499,16 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
buf2[pos] = '\0'; buf2[pos] = '\0';
} else if (pre == 0) { } else if (pre == 0) {
snprintf((char *)buf2, NUMBUFLEN, "%" PRIu64, (uint64_t)n + offset); vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n);
} else if (pre == '0') { } else if (pre == '0') {
snprintf((char *)buf2, NUMBUFLEN, "%" PRIo64, (uint64_t)n + offset); vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIo64, (uint64_t)n);
} else if (pre && hexupper) { } else if (pre && hexupper) {
snprintf((char *)buf2, NUMBUFLEN, "%" PRIX64, (uint64_t)n + offset); vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIX64, (uint64_t)n);
} else { } else {
snprintf((char *)buf2, NUMBUFLEN, "%" PRIx64, (uint64_t)n + offset); vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIx64, (uint64_t)n);
} }
length -= (int)STRLEN(buf2); length -= (int)STRLEN(buf2);
if (g_cmd) {
offset = subtract ? offset - (unsigned long) Prenum1
: offset + (unsigned long) Prenum1;
}
// Adjust number of zeros to the new number of digits, so the // Adjust number of zeros to the new number of digits, so the
// total length of the number remains the same. // total length of the number remains the same.
// Don't do this when // Don't do this when
@ -4512,11 +4523,25 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
ins_str(buf1); // insert the new number ins_str(buf1); // insert the new number
xfree(buf1); xfree(buf1);
} }
curwin->w_cursor.col--;
if (g_cmd) {
offset = (unsigned long)Prenum1;
g_cmd = 0;
}
// reset
subtract = false;
negative = false;
if (visual && VIsual_mode != Ctrl_V) {
col = 0;
} else {
col = startcol;
}
Prenum1 += offset;
curwin->w_set_curswant = true; curwin->w_set_curswant = true;
ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true); ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true);
RLADDSUBFIX(ptr); RLADDSUBFIX(ptr);
} }
curwin->w_cursor.col--;
return OK; return OK;
} }

View File

@ -6,6 +6,7 @@ Test cases
1) Ctrl-A on visually selected number 1) Ctrl-A on visually selected number
Text: Text:
foobar-10 foobar-10
Expected:
1) Ctrl-A on start of line: 1) Ctrl-A on start of line:
foobar-9 foobar-9
2) Ctrl-A on visually selected "-10": 2) Ctrl-A on visually selected "-10":
@ -24,6 +25,7 @@ Text:
30 30
40 40
Expected:
1) Ctrl-A on visually selected lines: 1) Ctrl-A on visually selected lines:
11 11
21 21
@ -46,6 +48,7 @@ Text:
40 40
Expected:
1) 2 g Ctrl-A on visually selected lines: 1) 2 g Ctrl-A on visually selected lines:
12 12
@ -66,9 +69,122 @@ Text:
4) Ctrl-A on non-number 4) Ctrl-A on non-number
Text: Text:
foobar-10 foobar-10
Expected:
1) visually select foobar: 1) visually select foobar:
foobar-10 foobar-10
5) g<Ctrl-A> on letter
Test:
a
a
a
a
Expected:
1) g Ctrl-A on visually selected lines
b
c
d
e
6) g<Ctrl-A> on letter
Test:
z
z
z
z
Expected:
1) g Ctrl-X on visually selected lines
y
x
w
v
7) <Ctrl-A> on letter
Test:
2
1
0
-1
-2
Expected:
1) Ctrl-A on visually selected lines
3
2
1
0
-1
2) Ctrl-X on visually selected lines
1
0
-1
-2
-3
8) Block increment on 0x9
Text:
0x9
0x9
Expected:
1) Ctrl-A on visually block selected region (cursor at beginning):
0xa
0xa
2) Ctrl-A on visually block selected region (cursor at end)
0xa
0xa
9) Increment and redo
Text:
2
2
3
3
Expected:
1) 2 Ctrl-A on first 2 visually selected lines
4
4
2) redo (.) on 3
5
5
10) sequentially decrement 1
Text:
1
1
1
1
Expected:
1) g Ctrl-X on visually selected lines
0
-1
-2
-3
11) visually block selected indented lines
Text:
1
1
1
1
Expexted:
1) g Ctrl-A on block selected indented lines
2
1
3
4
12) visually selected several columns
Text:
0 0
0 0
0 0
Expected:
1) 'v' select last zero and first zeroes
0 1
1 0
1 0
STARTTEST STARTTEST
:so small.vim :so small.vim
:" :"
@ -77,16 +193,16 @@ STARTTEST
:" :"
:" Test 1 :" Test 1
:/^S1=/+,/^E1=/-y a :/^S1=/+,/^E1=/-y a
:/^E1/+put a :/^E1=/+put a
:/^E1/+2put a :/^E1=/+2put a
f-v$:/^E1/+3put a f-v$:/^E1=/+3put a
f1v$:/^E1/+4put a f1v$:/^E1=/+4put a
f-v$:/^E1/+5put a f-v$:/^E1=/+5put a
f1v$ f1v$
:" Test 22 :" Test 22
:/^S2=/+,/^E2=/-y a :/^S2=/+,/^E2=/-y a
:/^E2/+put a :/^E2=/+put a
V3k$:.+put a V3k$:.+put a
V3k$ V3k$
@ -101,6 +217,49 @@ V6k2g
:/^E4=/+put a :/^E4=/+put a
vf- vf-
:" Test 5
:set nrformats+=alpha
:/^S5=/+,/^E5=/-y a
:/^E5=/+put a
v3kg
:" Test 6
:/^S6=/+,/^E6=/-y a
:/^E6=/+put a
v3kg
:" Test 7
:/^S7=/+,/^E7=/-y a
:/^E7=/+put a
V4k:.+put a
V4k
:" Test 8
:/^S8=/+,/^E8=/-y a
:/^E8=/+put a
kj$:.+put a
k$+
:" Test 9
:/^S9=/+,/^E9=/-y a
:/^E9=/+put a
5kVj22j.
:" Test 10
:/^S10=/+,/^E10=/-y a
:/^E10=/+put a
V3kg
: Test 11
:/^S11=/+,/^E11=/-y a
:/^E11=/+put a
3kf13jg
:" Test 12
:/^S12=/+,/^E12=/-y a
:/^E12=/+put a
2k$v++
:" Save the report :" Save the report
:/^# Test 1/,$w! test.out :/^# Test 1/,$w! test.out
:qa! :qa!
@ -142,5 +301,93 @@ foobar-10
E4===== E4=====
# Test 5
S5====
a
a
a
a
E5====
# Test 6
S6====
z
z
z
z
E6====
# Test 7
S7====
2
1
0
-1
-2
E7====
# Test 8
S8====
0x9
0x9
E8====
# Test 9
S9====
2
2
3
3
E9====
# Test 10
S10====
1
1
1
1
E10====
# Test 11
S11====
1
1
1
1
E11====
# Test 12
S12====
0 0
0 0
0 0
E12====
ENDTEST ENDTEST

View File

@ -62,5 +62,132 @@ E4=====
foobar-10 foobar-10
# Test 5
S5====
a
a
a
a
E5====
b
c
d
e
# Test 6
S6====
z
z
z
z
E6====
y
x
w
v
# Test 7
S7====
2
1
0
-1
-2
E7====
3
2
1
0
-1
1
0
-1
-2
-3
# Test 8
S8====
0x9
0x9
E8====
0xa
0xa
0xa
0xa
# Test 9
S9====
2
2
3
3
E9====
4
4
5
5
# Test 10
S10====
1
1
1
1
E10====
0
-1
-2
-3
# Test 11
S11====
1
1
1
1
E11====
2
1
3
4
# Test 12
S12====
0 0
0 0
0 0
E12====
0 1
1 0
1 0
ENDTEST ENDTEST

View File

@ -369,7 +369,7 @@ static int included_patches[] = {
// 768, // 768,
// 767, // 767,
// 766 NA // 766 NA
// 765, 765,
764, 764,
// 763 NA // 763 NA
// 762 NA // 762 NA