Patch 8.2.0860
Problem:    Cannot use CTRL-A and CTRL-X on unsigned numbers.
Solution:   Add "unsigned" to 'nrformats'. (Naruhiko Nishino, closes #6144)
Files:      runtime/doc/options.txt, src/ops.c, src/optionstr.c,
            src/testdir/test_increment.vim


*** ../vim-8.2.0859/runtime/doc/options.txt     2020-05-29 23:03:06.056851747 
+0200
--- runtime/doc/options.txt     2020-05-31 15:02:30.016497429 +0200
***************
*** 5426,5431 ****
--- 5427,5441 ----
        bin     If included, numbers starting with "0b" or "0B" will be
                considered to be binary.  Example: Using CTRL-X on
                "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
        considered decimal.  This also happens for numbers that are not
        recognized as octal or hex.
*** ../vim-8.2.0859/src/ops.c   2020-05-30 15:31:57.858700863 +0200
--- src/ops.c   2020-05-31 15:04:13.748000005 +0200
***************
*** 2428,2437 ****
      char_u    *ptr;
      int               c;
      int               todel;
!     int               dohex;
!     int               dooct;
!     int               dobin;
!     int               doalp;
      int               firstdigit;
      int               subtract;
      int               negative = FALSE;
--- 2428,2438 ----
      char_u    *ptr;
      int               c;
      int               todel;
!     int               do_hex;
!     int               do_oct;
!     int               do_bin;
!     int               do_alpha;
!     int               do_unsigned;
      int               firstdigit;
      int               subtract;
      int               negative = FALSE;
***************
*** 2443,2452 ****
      pos_T     startpos;
      pos_T     endpos;
  
!     dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL);        // "heX"
!     dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL);        // "Octal"
!     dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL);        // "Bin"
!     doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL);        // "alPha"
  
      curwin->w_cursor = *pos;
      ptr = ml_get(pos->lnum);
--- 2444,2454 ----
      pos_T     startpos;
      pos_T     endpos;
  
!     do_hex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL);       // "heX"
!     do_oct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL);       // "Octal"
!     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"
  
      curwin->w_cursor = *pos;
      ptr = ml_get(pos->lnum);
***************
*** 2460,2466 ****
       */
      if (!VIsual_active)
      {
!       if (dobin)
            while (col > 0 && vim_isbdigit(ptr[col]))
            {
                --col;
--- 2462,2468 ----
       */
      if (!VIsual_active)
      {
!       if (do_bin)
            while (col > 0 && vim_isbdigit(ptr[col]))
            {
                --col;
***************
*** 2468,2474 ****
                    col -= (*mb_head_off)(ptr, ptr + col);
            }
  
!       if (dohex)
            while (col > 0 && vim_isxdigit(ptr[col]))
            {
                --col;
--- 2470,2476 ----
                    col -= (*mb_head_off)(ptr, ptr + col);
            }
  
!       if (do_hex)
            while (col > 0 && vim_isxdigit(ptr[col]))
            {
                --col;
***************
*** 2476,2483 ****
                    col -= (*mb_head_off)(ptr, ptr + col);
            }
  
!       if (       dobin
!               && dohex
                && ! ((col > 0
                    && (ptr[col] == 'X'
                        || ptr[col] == 'x')
--- 2478,2485 ----
                    col -= (*mb_head_off)(ptr, ptr + col);
            }
  
!       if (       do_bin
!               && do_hex
                && ! ((col > 0
                    && (ptr[col] == 'X'
                        || ptr[col] == 'x')
***************
*** 2499,2505 ****
            }
        }
  
!       if ((       dohex
                && col > 0
                && (ptr[col] == 'X'
                    || ptr[col] == 'x')
--- 2501,2507 ----
            }
        }
  
!       if ((       do_hex
                && col > 0
                && (ptr[col] == 'X'
                    || ptr[col] == 'x')
***************
*** 2507,2513 ****
                && (!has_mbyte ||
                    !(*mb_head_off)(ptr, ptr + col - 1))
                && vim_isxdigit(ptr[col + 1])) ||
!           (       dobin
                && col > 0
                && (ptr[col] == 'B'
                    || ptr[col] == 'b')
--- 2509,2515 ----
                && (!has_mbyte ||
                    !(*mb_head_off)(ptr, ptr + col - 1))
                && vim_isxdigit(ptr[col + 1])) ||
!           (       do_bin
                && col > 0
                && (ptr[col] == 'B'
                    || ptr[col] == 'b')
***************
*** 2530,2541 ****
  
            while (ptr[col] != NUL
                    && !vim_isdigit(ptr[col])
!                   && !(doalp && ASCII_ISALPHA(ptr[col])))
                col += mb_ptr2len(ptr + col);
  
            while (col > 0
                    && vim_isdigit(ptr[col - 1])
!                   && !(doalp && ASCII_ISALPHA(ptr[col])))
            {
                --col;
                if (has_mbyte)
--- 2532,2543 ----
  
            while (ptr[col] != NUL
                    && !vim_isdigit(ptr[col])
!                   && !(do_alpha && ASCII_ISALPHA(ptr[col])))
                col += mb_ptr2len(ptr + col);
  
            while (col > 0
                    && vim_isdigit(ptr[col - 1])
!                   && !(do_alpha && ASCII_ISALPHA(ptr[col])))
            {
                --col;
                if (has_mbyte)
***************
*** 2548,2554 ****
      {
        while (ptr[col] != NUL && length > 0
                && !vim_isdigit(ptr[col])
!               && !(doalp && ASCII_ISALPHA(ptr[col])))
        {
            int mb_len = mb_ptr2len(ptr + col);
  
--- 2550,2556 ----
      {
        while (ptr[col] != NUL && length > 0
                && !vim_isdigit(ptr[col])
!               && !(do_alpha && ASCII_ISALPHA(ptr[col])))
        {
            int mb_len = mb_ptr2len(ptr + col);
  
***************
*** 2560,2566 ****
            goto theend;
  
        if (col > pos->col && ptr[col - 1] == '-'
!               && (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1)))
        {
            negative = TRUE;
            was_positive = FALSE;
--- 2562,2569 ----
            goto theend;
  
        if (col > pos->col && ptr[col - 1] == '-'
!               && (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1))
!               && !do_unsigned)
        {
            negative = TRUE;
            was_positive = FALSE;
***************
*** 2571,2583 ****
       * If a number was found, and saving for undo works, replace the number.
       */
      firstdigit = ptr[col];
!     if (!VIM_ISDIGIT(firstdigit) && !(doalp && ASCII_ISALPHA(firstdigit)))
      {
        beep_flush();
        goto theend;
      }
  
!     if (doalp && ASCII_ISALPHA(firstdigit))
      {
        // decrement or increment alphabetic character
        if (op_type == OP_NR_SUB)
--- 2574,2586 ----
       * If a number was found, and saving for undo works, replace the number.
       */
      firstdigit = ptr[col];
!     if (!VIM_ISDIGIT(firstdigit) && !(do_alpha && ASCII_ISALPHA(firstdigit)))
      {
        beep_flush();
        goto theend;
      }
  
!     if (do_alpha && ASCII_ISALPHA(firstdigit))
      {
        // decrement or increment alphabetic character
        if (op_type == OP_NR_SUB)
***************
*** 2626,2632 ****
        if (col > 0 && ptr[col - 1] == '-'
                && (!has_mbyte ||
                    !(*mb_head_off)(ptr, ptr + col - 1))
!               && !visual)
        {
            // negative number
            --col;
--- 2629,2636 ----
        if (col > 0 && ptr[col - 1] == '-'
                && (!has_mbyte ||
                    !(*mb_head_off)(ptr, ptr + col - 1))
!               && !visual
!               && !do_unsigned)
        {
            // negative number
            --col;
***************
*** 2639,2647 ****
                    : length);
  
        vim_str2nr(ptr + col, &pre, &length,
!               0 + (dobin ? STR2NR_BIN : 0)
!                   + (dooct ? STR2NR_OCT : 0)
!                   + (dohex ? STR2NR_HEX : 0),
                NULL, &n, maxlen, FALSE);
  
        // ignore leading '-' for hex and octal and bin numbers
--- 2643,2651 ----
                    : length);
  
        vim_str2nr(ptr + col, &pre, &length,
!               0 + (do_bin ? STR2NR_BIN : 0)
!                   + (do_oct ? STR2NR_OCT : 0)
!                   + (do_hex ? STR2NR_HEX : 0),
                NULL, &n, maxlen, FALSE);
  
        // ignore leading '-' for hex and octal and bin numbers
***************
*** 2687,2692 ****
--- 2691,2707 ----
                negative = FALSE;
        }
  
+       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)
        {
            // need to remove the '-'
***************
*** 2780,2786 ****
         * Don't do this when
         * the result may look like an octal number.
         */
!       if (firstdigit == '0' && !(dooct && pre == 0))
            while (length-- > 0)
                *ptr++ = '0';
        *ptr = NUL;
--- 2795,2801 ----
         * Don't do this when
         * the result may look like an octal number.
         */
!       if (firstdigit == '0' && !(do_oct && pre == 0))
            while (length-- > 0)
                *ptr++ = '0';
        *ptr = NUL;
*** ../vim-8.2.0859/src/optionstr.c     2020-05-31 14:07:02.688752446 +0200
--- src/optionstr.c     2020-05-31 14:57:25.962081153 +0200
***************
*** 21,27 ****
                                 "hangul", "insertmode", "lang", "mess",
                                 "showmatch", "operator", "register", "shell",
                                 "spell", "wildmode", NULL};
! static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", NULL};
  static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
  #ifdef FEAT_CRYPT
  static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL};
--- 21,27 ----
                                 "hangul", "insertmode", "lang", "mess",
                                 "showmatch", "operator", "register", "shell",
                                 "spell", "wildmode", NULL};
! static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", 
NULL};
  static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
  #ifdef FEAT_CRYPT
  static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL};
*** ../vim-8.2.0859/src/testdir/test_increment.vim      2020-04-11 
17:09:28.324426586 +0200
--- src/testdir/test_increment.vim      2020-05-31 14:57:25.962081153 +0200
***************
*** 1,4 ****
! " Tests for using Ctrl-A/Ctrl-X on visual selections
  
  func SetUp()
    new dummy
--- 1,4 ----
! " Tests for using Ctrl-A/Ctrl-X
  
  func SetUp()
    new dummy
***************
*** 796,799 ****
--- 796,843 ----
    call assert_beeps("normal \<C-X>")
  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
+ 
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.0859/src/version.c       2020-05-31 14:24:39.596878596 +0200
--- src/version.c       2020-05-31 14:58:02.033880848 +0200
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     860,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
229. You spend so much time thinking what to add on this list.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202005311309.04VD9O9U622417%40masaka.moolenaar.net.

Raspunde prin e-mail lui