diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-07-07 06:32:54 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-07 06:32:54 +0800 |
commit | 5da9b49b19240bb00f338249fef84a2bf1212b49 (patch) | |
tree | 07a864275674601b81c5f77927b7f2b8794d8186 | |
parent | 7a54d707fa6f32822b241140b31a348ad5ad0e6b (diff) | |
download | rneovim-5da9b49b19240bb00f338249fef84a2bf1212b49.tar.gz rneovim-5da9b49b19240bb00f338249fef84a2bf1212b49.tar.bz2 rneovim-5da9b49b19240bb00f338249fef84a2bf1212b49.zip |
vim-patch:9.1.0537: signed number detection for CTRL-X/A can be improved (#29590)
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: vim/vim#15033
closes: vim/vim#15110
https://github.com/vim/vim/commit/25ac6d67d92e0adda53b8d44b81c15031643ca1e
Co-authored-by: distobs <cuppotatocake@gmail.com>
-rw-r--r-- | runtime/doc/options.txt | 14 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/options.lua | 14 | ||||
-rw-r--r-- | src/nvim/ops.c | 33 | ||||
-rw-r--r-- | src/nvim/options.lua | 14 | ||||
-rw-r--r-- | src/nvim/optionstr.c | 2 | ||||
-rw-r--r-- | test/old/testdir/test_increment.vim | 38 |
6 files changed, 102 insertions, 13 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 70d0bd4369..4bb589fb2c 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4430,6 +4430,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/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index fb04da14a5..40c12d94fd 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -4549,6 +4549,20 @@ vim.go.mouset = vim.go.mousetime --- (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/src/nvim/ops.c b/src/nvim/ops.c index 7bffb12412..f2f8708235 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4420,6 +4420,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin static bool hexupper = false; // 0xABC uvarnumber_T n; + bool blank_unsigned = false; // blank: treat as unsigned? bool negative = false; bool was_positive = true; bool visual = VIsual_active; @@ -4430,12 +4431,12 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) pos_T endpos; colnr_T save_coladd = 0; - const bool do_hex = vim_strchr(curbuf->b_p_nf, 'x') != NULL; // "heX" - const bool do_oct = vim_strchr(curbuf->b_p_nf, 'o') != NULL; // "Octal" - const bool do_bin = vim_strchr(curbuf->b_p_nf, 'b') != NULL; // "Bin" - const bool do_alpha = vim_strchr(curbuf->b_p_nf, 'p') != NULL; // "alPha" - // "Unsigned" - const bool do_unsigned = vim_strchr(curbuf->b_p_nf, 'u') != NULL; + const bool do_hex = vim_strchr(curbuf->b_p_nf, 'x') != NULL; // "heX" + const bool do_oct = vim_strchr(curbuf->b_p_nf, 'o') != NULL; // "Octal" + const bool do_bin = vim_strchr(curbuf->b_p_nf, 'b') != NULL; // "Bin" + const bool do_alpha = vim_strchr(curbuf->b_p_nf, 'p') != NULL; // "alPha" + const bool do_unsigned = vim_strchr(curbuf->b_p_nf, 'u') != NULL; // "Unsigned" + const bool do_blank = vim_strchr(curbuf->b_p_nf, 'k') != NULL; // "blanK" if (virtual_active(curwin)) { save_coladd = pos->coladd; @@ -4532,8 +4533,12 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) if (col > pos->col && ptr[col - 1] == '-' && !utf_head_off(ptr, ptr + col - 1) && !do_unsigned) { - negative = true; - was_positive = false; + if (do_blank && col >= 2 && !ascii_iswhite(ptr[col - 2])) { + blank_unsigned = true; + } else { + negative = true; + was_positive = false; + } } } @@ -4579,9 +4584,13 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) && !utf_head_off(ptr, ptr + col - 1) && !visual && !do_unsigned) { - // negative number - col--; - negative = true; + if (do_blank && col >= 2 && !ascii_iswhite(ptr[col - 2])) { + blank_unsigned = true; + } else { + // negative number + col--; + negative = true; + } } // get the number value (unsigned) @@ -4638,7 +4647,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } } - if (do_unsigned && negative) { + if ((do_unsigned || blank_unsigned) && negative) { if (subtract) { // sticking at zero. n = 0; diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 365679261c..6e317a426c 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -5717,6 +5717,20 @@ return { (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/src/nvim/optionstr.c b/src/nvim/optionstr.c index cdbb8c2d6d..1a4c142fdd 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -82,7 +82,7 @@ static char *(p_dip_values[]) = { "filler", "context:", "iblank", "icase", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "linematch:", "algorithm:", NULL }; static char *(p_dip_algorithm_values[]) = { "myers", "minimal", "patience", "histogram", NULL }; -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_cb_values[]) = { "unnamed", "unnamedplus", NULL }; static char *(p_cmp_values[]) = { "internal", "keepascii", NULL }; diff --git a/test/old/testdir/test_increment.vim b/test/old/testdir/test_increment.vim index 433b2b4471..cf6334747a 100644 --- a/test/old/testdir/test_increment.vim +++ b/test/old/testdir/test_increment.vim @@ -841,6 +841,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') |