summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordistobs <cuppotatocake@gmail.com>2024-07-06 17:50:09 +0200
committerChristian Brabandt <cb@256bit.org>2024-07-06 17:55:26 +0200
commit25ac6d67d92e0adda53b8d44b81c15031643ca1e (patch)
tree62b04fe76807209b46bbab09a9c8eba8a688afa3
parentf095539b3900d76f5eeaaa0897c6abf970829b31 (diff)
patch 9.1.0537: signed number detection for CTRL-X/A can be improvedv9.1.0537
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>
-rw-r--r--runtime/doc/options.txt16
-rw-r--r--runtime/doc/version9.txt4
-rw-r--r--src/ops.c26
-rw-r--r--src/optionstr.c2
-rw-r--r--src/testdir/test_increment.vim38
-rw-r--r--src/version.c2
6 files changed, 79 insertions, 9 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 62d6ded111..e9c94aa8e5 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -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
@@ -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").
Using CTRL-X on "0" or CTRL-A on "18446744073709551615"
(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
considered decimal. This also happens for numbers that are not
recognized as octal or hex.
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index b60f3869a5..d70c3b19e3 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -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
@@ -41574,6 +41574,8 @@ Changed~
- the default for 'commentstring' contains whitespace padding to have
automatic comments look nicer |comment-install|
- '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 ~
diff --git a/src/ops.c b/src/ops.c
index eb75c34b1b..dcb48d3233 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -2673,6 +2673,8 @@ do_addsub(
int do_bin;
int do_alpha;
int do_unsigned;
+ int do_blank;
+ int blank_unsigned = FALSE; // blank: treat as unsigned?
int firstdigit;
int subtract;
int negative = FALSE;
@@ -2690,6 +2692,7 @@ do_addsub(
do_bin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin"
do_alpha = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha"
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())
{
@@ -2813,8 +2816,13 @@ do_addsub(
&& (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1))
&& !do_unsigned)
{
- negative = TRUE;
- was_positive = FALSE;
+ if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2]))
+ blank_unsigned = TRUE;
+ else
+ {
+ negative = TRUE;
+ was_positive = FALSE;
+ }
}
}
@@ -2875,10 +2883,16 @@ do_addsub(
&& !visual
&& !do_unsigned)
{
- // negative number
- --col;
- negative = TRUE;
+ if (do_blank && col >= 2 && !VIM_ISWHITE(ptr[col - 2]))
+ blank_unsigned = TRUE;
+ else
+ {
+ // negative number
+ --col;
+ negative = TRUE;
+ }
}
+
// get the number value (unsigned)
if (visual && VIsual_mode != 'V')
maxlen = (curbuf->b_visual.vi_curswant == MAXCOL
@@ -2938,7 +2952,7 @@ do_addsub(
negative = FALSE;
}
- if (do_unsigned && negative)
+ if ((do_unsigned || blank_unsigned) && negative)
{
if (subtract)
// sticking at zero.
diff --git a/src/optionstr.c b/src/optionstr.c
index 170d48e9a2..9adb77dff5 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -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_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL};
#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};
#ifdef FEAT_CLIPBOARD
// Note: Keep this in sync with did_set_clipboard()
diff --git a/src/testdir/test_increment.vim b/src/testdir/test_increment.vim
index fdd7c0ce01..3a5f5ee028 100644
--- a/src/testdir/test_increment.vim
+++ b/src/testdir/test_increment.vim
@@ -840,6 +840,44 @@ func Test_increment_unsigned()
set nrformats-=unsigned
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()
" NOTE: 18446744073709551616 == 2^64
call setline(1, '18446744073709551616')
diff --git a/src/version.c b/src/version.c
index 359605b8c2..6b1da3ea7c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 537,
+/**/
536,
/**/
535,