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

Commit: 
https://github.com/vim/vim/commit/25ac6d67d92e0adda53b8d44b81c15031643ca1e
Author: distobs <cuppotatoc...@gmail.com>
Date:   Sat Jul 6 17:50:09 2024 +0200

    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 <cuppotatoc...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 62d6ded11..e9c94aa8e 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 b60f3869a..d70c3b19e 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 eb75c34b1..dcb48d323 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 170d48e9a..9adb77dff 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 fdd7c0ce0..3a5f5ee02 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 359605b8c..6b1da3ea7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    537,
 /**/
     536,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1sQ7pT-006mwr-1d%40256bit.org.

Raspunde prin e-mail lui