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>
diff --git a/src/ops.c b/src/ops.c
index eb75c34..dcb48d3 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -2673,6 +2673,8 @@
     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_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 @@
 		&& (!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 @@
 		&& !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 @@
 		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 170d48e..9adb77d 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -33,7 +33,7 @@
 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 fdd7c0c..3a5f5ee 100644
--- a/src/testdir/test_increment.vim
+++ b/src/testdir/test_increment.vim
@@ -840,6 +840,44 @@
   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 359605b..6b1da3e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    537,
+/**/
     536,
 /**/
     535,