mirror of
https://github.com/neovim/neovim.git
synced 2025-09-17 16:58:17 +00:00
vim-patch:8.2.0860: cannot use CTRL-A and CTRL-X on unsigned numbers
Problem: Cannot use CTRL-A and CTRL-X on unsigned numbers.
Solution: Add "unsigned" to 'nrformats'. (Naruhiko Nishino, closes vim/vim#6144)
aaad995f83
This commit is contained in:
@@ -4208,6 +4208,15 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
bin If included, numbers starting with "0b" or "0B" will be
|
bin If included, numbers starting with "0b" or "0B" will be
|
||||||
considered to be binary. Example: Using CTRL-X on
|
considered to be binary. Example: Using CTRL-X on
|
||||||
"0b1000" subtracts one, resulting in "0b0111".
|
"0b1000" subtracts one, resulting in "0b0111".
|
||||||
|
unsigned If included, numbers are recognized as unsigned. Thus a
|
||||||
|
leading dash or negative sign won't be considered as part of
|
||||||
|
the number. Examples:
|
||||||
|
Using CTRL-X on "2020" in "9-2020" results in "9-2019"
|
||||||
|
(without "unsigned" it would become "9-2021").
|
||||||
|
Using CTRL-A on "2020" in "9-2020" results in "9-2021"
|
||||||
|
(without "unsigned" it would become "9-2019").
|
||||||
|
Using CTRL-X on "0" or "18446744073709551615" (2^64) has
|
||||||
|
no effect, overflow is prevented.
|
||||||
Numbers which simply begin with a digit in the range 1-9 are always
|
Numbers which simply begin with a digit in the range 1-9 are always
|
||||||
considered decimal. This also happens for numbers that are not
|
considered decimal. This also happens for numbers that are not
|
||||||
recognized as octal or hex.
|
recognized as octal or hex.
|
||||||
|
@@ -4731,12 +4731,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
char_u *ptr;
|
char_u *ptr;
|
||||||
int c;
|
int c;
|
||||||
int todel;
|
int todel;
|
||||||
bool dohex;
|
|
||||||
bool dooct;
|
|
||||||
bool dobin;
|
|
||||||
bool doalp;
|
|
||||||
int firstdigit;
|
int firstdigit;
|
||||||
bool subtract;
|
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
bool was_positive = true;
|
bool was_positive = true;
|
||||||
bool visual = VIsual_active;
|
bool visual = VIsual_active;
|
||||||
@@ -4747,10 +4742,12 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
pos_T endpos;
|
pos_T endpos;
|
||||||
colnr_T save_coladd = 0;
|
colnr_T save_coladd = 0;
|
||||||
|
|
||||||
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX"
|
const bool do_hex = vim_strchr(curbuf->b_p_nf, 'x') != NULL; // "heX"
|
||||||
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal"
|
const bool do_oct = vim_strchr(curbuf->b_p_nf, 'o') != NULL; // "Octal"
|
||||||
dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin"
|
const bool do_bin = vim_strchr(curbuf->b_p_nf, 'b') != NULL; // "Bin"
|
||||||
doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha"
|
const bool do_alpha = vim_strchr(curbuf->b_p_nf, 'p') != NULL; // "alPha"
|
||||||
|
// "Unsigned"
|
||||||
|
const bool do_unsigned = vim_strchr(curbuf->b_p_nf, 'u') != NULL;
|
||||||
|
|
||||||
if (virtual_active()) {
|
if (virtual_active()) {
|
||||||
save_coladd = pos->coladd;
|
save_coladd = pos->coladd;
|
||||||
@@ -4767,21 +4764,21 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
|
|
||||||
// First check if we are on a hexadecimal number, after the "0x".
|
// First check if we are on a hexadecimal number, after the "0x".
|
||||||
if (!VIsual_active) {
|
if (!VIsual_active) {
|
||||||
if (dobin) {
|
if (do_bin) {
|
||||||
while (col > 0 && ascii_isbdigit(ptr[col])) {
|
while (col > 0 && ascii_isbdigit(ptr[col])) {
|
||||||
col--;
|
col--;
|
||||||
col -= utf_head_off(ptr, ptr + col);
|
col -= utf_head_off(ptr, ptr + col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dohex) {
|
if (do_hex) {
|
||||||
while (col > 0 && ascii_isxdigit(ptr[col])) {
|
while (col > 0 && ascii_isxdigit(ptr[col])) {
|
||||||
col--;
|
col--;
|
||||||
col -= utf_head_off(ptr, ptr + col);
|
col -= utf_head_off(ptr, ptr + col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dobin
|
if (do_bin
|
||||||
&& dohex
|
&& do_hex
|
||||||
&& !((col > 0
|
&& !((col > 0
|
||||||
&& (ptr[col] == 'X' || ptr[col] == 'x')
|
&& (ptr[col] == 'X' || ptr[col] == 'x')
|
||||||
&& ptr[col - 1] == '0'
|
&& ptr[col - 1] == '0'
|
||||||
@@ -4797,13 +4794,13 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dohex
|
if ((do_hex
|
||||||
&& col > 0
|
&& col > 0
|
||||||
&& (ptr[col] == 'X' || ptr[col] == 'x')
|
&& (ptr[col] == 'X' || ptr[col] == 'x')
|
||||||
&& ptr[col - 1] == '0'
|
&& ptr[col - 1] == '0'
|
||||||
&& !utf_head_off(ptr, ptr + col - 1)
|
&& !utf_head_off(ptr, ptr + col - 1)
|
||||||
&& ascii_isxdigit(ptr[col + 1]))
|
&& ascii_isxdigit(ptr[col + 1]))
|
||||||
|| (dobin
|
|| (do_bin
|
||||||
&& col > 0
|
&& col > 0
|
||||||
&& (ptr[col] == 'B' || ptr[col] == 'b')
|
&& (ptr[col] == 'B' || ptr[col] == 'b')
|
||||||
&& ptr[col - 1] == '0'
|
&& ptr[col - 1] == '0'
|
||||||
@@ -4818,13 +4815,13 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
|
|
||||||
while (ptr[col] != NUL
|
while (ptr[col] != NUL
|
||||||
&& !ascii_isdigit(ptr[col])
|
&& !ascii_isdigit(ptr[col])
|
||||||
&& !(doalp && ASCII_ISALPHA(ptr[col]))) {
|
&& !(do_alpha && ASCII_ISALPHA(ptr[col]))) {
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (col > 0
|
while (col > 0
|
||||||
&& ascii_isdigit(ptr[col - 1])
|
&& ascii_isdigit(ptr[col - 1])
|
||||||
&& !(doalp && ASCII_ISALPHA(ptr[col]))) {
|
&& !(do_alpha && ASCII_ISALPHA(ptr[col]))) {
|
||||||
col--;
|
col--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4832,7 +4829,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
|
|
||||||
if (visual) {
|
if (visual) {
|
||||||
while (ptr[col] != NUL && length > 0 && !ascii_isdigit(ptr[col])
|
while (ptr[col] != NUL && length > 0 && !ascii_isdigit(ptr[col])
|
||||||
&& !(doalp && ASCII_ISALPHA(ptr[col]))) {
|
&& !(do_alpha && ASCII_ISALPHA(ptr[col]))) {
|
||||||
int mb_len = utfc_ptr2len(ptr + col);
|
int mb_len = utfc_ptr2len(ptr + col);
|
||||||
|
|
||||||
col += mb_len;
|
col += mb_len;
|
||||||
@@ -4844,7 +4841,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (col > pos->col && ptr[col - 1] == '-'
|
if (col > pos->col && ptr[col - 1] == '-'
|
||||||
&& !utf_head_off(ptr, ptr + col - 1)) {
|
&& !utf_head_off(ptr, ptr + col - 1)
|
||||||
|
&& !do_unsigned) {
|
||||||
negative = true;
|
negative = true;
|
||||||
was_positive = false;
|
was_positive = false;
|
||||||
}
|
}
|
||||||
@@ -4852,12 +4850,12 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
|
|
||||||
// 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];
|
||||||
if (!ascii_isdigit(firstdigit) && !(doalp && ASCII_ISALPHA(firstdigit))) {
|
if (!ascii_isdigit(firstdigit) && !(do_alpha && ASCII_ISALPHA(firstdigit))) {
|
||||||
beep_flush();
|
beep_flush();
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doalp && ASCII_ISALPHA(firstdigit)) {
|
if (do_alpha && ASCII_ISALPHA(firstdigit)) {
|
||||||
// decrement or increment alphabetic character
|
// decrement or increment alphabetic character
|
||||||
if (op_type == OP_NR_SUB) {
|
if (op_type == OP_NR_SUB) {
|
||||||
if (CharOrd(firstdigit) < Prenum1) {
|
if (CharOrd(firstdigit) < Prenum1) {
|
||||||
@@ -4889,7 +4887,9 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
curwin->w_cursor.col = col;
|
curwin->w_cursor.col = col;
|
||||||
} else {
|
} else {
|
||||||
if (col > 0 && ptr[col - 1] == '-'
|
if (col > 0 && ptr[col - 1] == '-'
|
||||||
&& !utf_head_off(ptr, ptr + col - 1) && !visual) {
|
&& !utf_head_off(ptr, ptr + col - 1)
|
||||||
|
&& !visual
|
||||||
|
&& !do_unsigned) {
|
||||||
// negative number
|
// negative number
|
||||||
col--;
|
col--;
|
||||||
negative = true;
|
negative = true;
|
||||||
@@ -4903,9 +4903,9 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vim_str2nr(ptr + col, &pre, &length,
|
vim_str2nr(ptr + col, &pre, &length,
|
||||||
0 + (dobin ? STR2NR_BIN : 0)
|
0 + (do_bin ? STR2NR_BIN : 0)
|
||||||
+ (dooct ? STR2NR_OCT : 0)
|
+ (do_oct ? STR2NR_OCT : 0)
|
||||||
+ (dohex ? STR2NR_HEX : 0),
|
+ (do_hex ? STR2NR_HEX : 0),
|
||||||
NULL, &n, maxlen);
|
NULL, &n, maxlen);
|
||||||
|
|
||||||
// ignore leading '-' for hex, octal and bin numbers
|
// ignore leading '-' for hex, octal and bin numbers
|
||||||
@@ -4916,7 +4916,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add or subtract
|
// add or subtract
|
||||||
subtract = false;
|
bool subtract = false;
|
||||||
if (op_type == OP_NR_SUB) {
|
if (op_type == OP_NR_SUB) {
|
||||||
subtract ^= true;
|
subtract ^= true;
|
||||||
}
|
}
|
||||||
@@ -4948,6 +4948,17 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_unsigned && negative) {
|
||||||
|
if (subtract) {
|
||||||
|
// sticking at zero.
|
||||||
|
n = (uvarnumber_T)0;
|
||||||
|
} else {
|
||||||
|
// sticking at 2^64 - 1.
|
||||||
|
n = (uvarnumber_T)(-1);
|
||||||
|
}
|
||||||
|
negative = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (visual && !was_positive && !negative && col > 0) {
|
if (visual && !was_positive && !negative && col > 0) {
|
||||||
// need to remove the '-'
|
// need to remove the '-'
|
||||||
col--;
|
col--;
|
||||||
@@ -5029,7 +5040,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
|||||||
// 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
|
||||||
// the result may look like an octal number.
|
// the result may look like an octal number.
|
||||||
if (firstdigit == '0' && !(dooct && pre == 0)) {
|
if (firstdigit == '0' && !(do_oct && pre == 0)) {
|
||||||
while (length-- > 0) {
|
while (length-- > 0) {
|
||||||
*ptr++ = '0';
|
*ptr++ = '0';
|
||||||
}
|
}
|
||||||
|
@@ -292,7 +292,8 @@ typedef struct vimoption {
|
|||||||
|
|
||||||
static char *(p_ambw_values[]) = { "single", "double", NULL };
|
static char *(p_ambw_values[]) = { "single", "double", NULL };
|
||||||
static char *(p_bg_values[]) = { "light", "dark", NULL };
|
static char *(p_bg_values[]) = { "light", "dark", NULL };
|
||||||
static char *(p_nf_values[]) = { "bin", "octal", "hex", "alpha", NULL };
|
static char *(p_nf_values[]) = { "bin", "octal", "hex", "alpha",
|
||||||
|
"unsigned", NULL };
|
||||||
static char *(p_ff_values[]) = { FF_UNIX, FF_DOS, FF_MAC, NULL };
|
static char *(p_ff_values[]) = { FF_UNIX, FF_DOS, FF_MAC, NULL };
|
||||||
static char *(p_wak_values[]) = { "yes", "menu", "no", NULL };
|
static char *(p_wak_values[]) = { "yes", "menu", "no", NULL };
|
||||||
static char *(p_mousem_values[]) = { "extend", "popup", "popup_setpos",
|
static char *(p_mousem_values[]) = { "extend", "popup", "popup_setpos",
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
" Tests for using Ctrl-A/Ctrl-X on visual selections
|
" Tests for using Ctrl-A/Ctrl-X
|
||||||
|
|
||||||
func SetUp()
|
func SetUp()
|
||||||
new dummy
|
new dummy
|
||||||
@@ -779,6 +779,50 @@ func Test_increment_empty_line()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Try incrementing/decrementing a number when nrformats contains unsigned
|
||||||
|
func Test_increment_unsigned()
|
||||||
|
set nrformats+=unsigned
|
||||||
|
|
||||||
|
call setline(1, '0')
|
||||||
|
exec "norm! gg0\<C-X>"
|
||||||
|
call assert_equal('0', getline(1))
|
||||||
|
|
||||||
|
call setline(1, '3')
|
||||||
|
exec "norm! gg010\<C-X>"
|
||||||
|
call assert_equal('0', getline(1))
|
||||||
|
|
||||||
|
call setline(1, '-0')
|
||||||
|
exec "norm! gg0\<C-X>"
|
||||||
|
call assert_equal("-0", getline(1))
|
||||||
|
|
||||||
|
call setline(1, '-11')
|
||||||
|
exec "norm! gg08\<C-X>"
|
||||||
|
call assert_equal('-3', getline(1))
|
||||||
|
|
||||||
|
" NOTE: 18446744073709551615 == 2^64 - 1
|
||||||
|
call setline(1, '18446744073709551615')
|
||||||
|
exec "norm! gg0\<C-A>"
|
||||||
|
call assert_equal('18446744073709551615', getline(1))
|
||||||
|
|
||||||
|
call setline(1, '-18446744073709551615')
|
||||||
|
exec "norm! gg0\<C-A>"
|
||||||
|
call assert_equal('-18446744073709551615', getline(1))
|
||||||
|
|
||||||
|
call setline(1, '-18446744073709551614')
|
||||||
|
exec "norm! gg08\<C-A>"
|
||||||
|
call assert_equal('-18446744073709551615', getline(1))
|
||||||
|
|
||||||
|
call setline(1, '-1')
|
||||||
|
exec "norm! gg0\<C-A>"
|
||||||
|
call assert_equal('-2', getline(1))
|
||||||
|
|
||||||
|
call setline(1, '-3')
|
||||||
|
exec "norm! gg08\<C-A>"
|
||||||
|
call assert_equal('-11', getline(1))
|
||||||
|
|
||||||
|
set nrformats-=unsigned
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_normal_increment_with_virtualedit()
|
func Test_normal_increment_with_virtualedit()
|
||||||
set virtualedit=all
|
set virtualedit=all
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user