0
0
mirror of https://github.com/vim/vim.git synced 2025-08-26 20:03:41 -04:00

patch 9.1.0537: signed number detection for CTRL-X/A can be improved

Problem:  signed number detection for CTRL-X/A can be improved
          (Chris Patuzzo)
Solution: Add the new "blank" value for the 'nrformat' setting. This
          will make Vim assume a signed number only if there is a blank
          in front of the sign.
          (distobs)

fixes: #15033
closes: #15110

Signed-off-by: distobs <cuppotatocake@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
distobs 2024-07-06 17:50:09 +02:00 committed by Christian Brabandt
parent f095539b39
commit 25ac6d67d9
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
6 changed files with 79 additions and 9 deletions

View File

@ -1,4 +1,4 @@
*options.txt* For Vim version 9.1. Last change: 2024 Jun 19 *options.txt* For Vim version 9.1. Last change: 2024 Jul 06
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -5918,6 +5918,20 @@ A jump table for the options with a short description can be found at |Q_op|.
(without "unsigned" it would become "9-2019"). (without "unsigned" it would become "9-2019").
Using CTRL-X on "0" or CTRL-A on "18446744073709551615" Using CTRL-X on "0" or CTRL-A on "18446744073709551615"
(2^64 - 1) has no effect, overflow is prevented. (2^64 - 1) has no effect, overflow is prevented.
blank If included, treat numbers as signed or unsigned based on
preceding whitespace. If a number with a leading dash has its
dash immediately preceded by a non-whitespace character (i.e.,
not a tab or a " "), the negative sign won't be considered as
part of the number. For example:
Using CTRL-A on "14" in "Carbon-14" results in "Carbon-15"
(without "blank" it would become "Carbon-13").
Using CTRL-X on "8" in "Carbon -8" results in "Carbon -9"
(because -8 is preceded by whitespace. If "unsigned" was
set, it would result in "Carbon -7").
If this format is included, overflow is prevented as if
"unsigned" were set. If both this format and "unsigned" are
included, "unsigned" will take precedence.
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.

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2024 Jun 20 *version9.txt* For Vim version 9.1. Last change: 2024 Jul 06
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -41574,6 +41574,8 @@ Changed~
- the default for 'commentstring' contains whitespace padding to have - the default for 'commentstring' contains whitespace padding to have
automatic comments look nicer |comment-install| automatic comments look nicer |comment-install|
- 'completeopt' is now a |global-local| option. - 'completeopt' is now a |global-local| option.
- 'nrformat' accepts the new "blank" suboption, to determine a signed or
unsigned number based on whitespace in front of a minus sign.
*added-9.2* *added-9.2*
Added ~ Added ~

View File

@ -2673,6 +2673,8 @@ do_addsub(
int do_bin; int do_bin;
int do_alpha; int do_alpha;
int do_unsigned; int do_unsigned;
int do_blank;
int blank_unsigned = FALSE; // blank: treat as unsigned?
int firstdigit; int firstdigit;
int subtract; int subtract;
int negative = FALSE; int negative = FALSE;
@ -2690,6 +2692,7 @@ do_addsub(
do_bin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin" do_bin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin"
do_alpha = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha" do_alpha = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha"
do_unsigned = (vim_strchr(curbuf->b_p_nf, 'u') != NULL); // "Unsigned" do_unsigned = (vim_strchr(curbuf->b_p_nf, 'u') != NULL); // "Unsigned"
do_blank = (vim_strchr(curbuf->b_p_nf, 'k') != NULL); // "blanK"
if (virtual_active()) if (virtual_active())
{ {
@ -2813,8 +2816,13 @@ do_addsub(
&& (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1)) && (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1))
&& !do_unsigned) && !do_unsigned)
{ {
negative = TRUE; if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2]))
was_positive = FALSE; blank_unsigned = TRUE;
else
{
negative = TRUE;
was_positive = FALSE;
}
} }
} }
@ -2875,10 +2883,16 @@ do_addsub(
&& !visual && !visual
&& !do_unsigned) && !do_unsigned)
{ {
// negative number if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2]))
--col; blank_unsigned = TRUE;
negative = TRUE; else
{
// negative number
--col;
negative = TRUE;
}
} }
// get the number value (unsigned) // get the number value (unsigned)
if (visual && VIsual_mode != 'V') if (visual && VIsual_mode != 'V')
maxlen = (curbuf->b_visual.vi_curswant == MAXCOL maxlen = (curbuf->b_visual.vi_curswant == MAXCOL
@ -2938,7 +2952,7 @@ do_addsub(
negative = FALSE; negative = FALSE;
} }
if (do_unsigned && negative) if ((do_unsigned || blank_unsigned) && negative)
{ {
if (subtract) if (subtract)
// sticking at zero. // sticking at zero.

View File

@ -33,7 +33,7 @@ static char *(p_briopt_values[]) = {"shift:", "min:", "sbr", "list:", "column:",
static char *(p_dip_values[]) = {"filler", "context:", "iblank", "icase", "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "algorithm:", NULL}; static char *(p_dip_values[]) = {"filler", "context:", "iblank", "icase", "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "algorithm:", NULL};
static char *(p_dip_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL}; static char *(p_dip_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL};
#endif #endif
static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL}; static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", "blank", 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};
#ifdef FEAT_CLIPBOARD #ifdef FEAT_CLIPBOARD
// Note: Keep this in sync with did_set_clipboard() // Note: Keep this in sync with did_set_clipboard()

View File

@ -840,6 +840,44 @@ func Test_increment_unsigned()
set nrformats-=unsigned set nrformats-=unsigned
endfunc endfunc
" Try incrementing/decrementing a number when nrformats contains blank
func Test_increment_blank()
set nrformats+=blank
" Signed
call setline(1, '0')
exec "norm! gg0\<C-X>"
call assert_equal('-1', getline(1))
call setline(1, '3')
exec "norm! gg010\<C-X>"
call assert_equal('-7', getline(1))
call setline(1, '-0')
exec "norm! gg0\<C-X>"
call assert_equal("-1", getline(1))
" Unsigned
" NOTE: 18446744073709551615 == 2^64 - 1
call setline(1, 'a-18446744073709551615')
exec "norm! gg0\<C-A>"
call assert_equal('a-18446744073709551615', getline(1))
call setline(1, 'a-18446744073709551615')
exec "norm! gg0\<C-A>"
call assert_equal('a-18446744073709551615', getline(1))
call setline(1, 'a-18446744073709551614')
exec "norm! gg08\<C-A>"
call assert_equal('a-18446744073709551615', getline(1))
call setline(1, 'a-1')
exec "norm! gg0\<C-A>"
call assert_equal('a-2', getline(1))
set nrformats-=blank
endfunc
func Test_in_decrement_large_number() func Test_in_decrement_large_number()
" NOTE: 18446744073709551616 == 2^64 " NOTE: 18446744073709551616 == 2^64
call setline(1, '18446744073709551616') call setline(1, '18446744073709551616')

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
537,
/**/ /**/
536, 536,
/**/ /**/