Mercurial > vim
changeset 22278:0416105e103b v8.2.1688
patch 8.2.1688: increment/decrement removes text property
Commit: https://github.com/vim/vim/commit/c8f12c9856df58c760fe54d81b2ec5ed4dcaffd6
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Sep 15 20:34:10 2020 +0200
patch 8.2.1688: increment/decrement removes text property
Problem: Increment/decrement removes text property.
Solution: Insert the new number before deleting the old one. (closes https://github.com/vim/vim/issues/6962)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 15 Sep 2020 20:45:03 +0200 |
parents | 4575b886c258 |
children | 3f60b0caf243 |
files | src/ops.c src/testdir/test_textprop.vim src/version.c |
diffstat | 3 files changed, 55 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ops.c +++ b/src/ops.c @@ -2636,6 +2636,9 @@ do_addsub( } else { + pos_T save_pos; + int i; + if (col > 0 && ptr[col - 1] == '-' && (!has_mbyte || !(*mb_head_off)(ptr, ptr + col - 1)) @@ -2734,7 +2737,9 @@ do_addsub( */ if (c == '-') --length; - while (todel-- > 0) + + save_pos = curwin->w_cursor; + for (i = 0; i < todel; ++i) { if (c < 0x100 && isalpha(c)) { @@ -2743,10 +2748,10 @@ do_addsub( else hexupper = FALSE; } - // del_char() will mark line needing displaying - (void)del_char(FALSE); + inc_cursor(); c = gchar_cursor(); } + curwin->w_cursor = save_pos; /* * Prepare the leading characters in buf1[]. @@ -2776,7 +2781,6 @@ do_addsub( */ if (pre == 'b' || pre == 'B') { - int i; int bit = 0; int bits = sizeof(uvarnumber_T) * 8; @@ -2809,9 +2813,33 @@ do_addsub( while (length-- > 0) *ptr++ = '0'; *ptr = NUL; + STRCAT(buf1, buf2); + + // Insert just after the first character to be removed, so that any + // text properties will be adjusted. Then delete the old number + // afterwards. + save_pos = curwin->w_cursor; + if (todel > 0) + inc_cursor(); ins_str(buf1); // insert the new number vim_free(buf1); + + // del_char() will also mark line needing displaying + if (todel > 0) + { + int bytes_after = (int)STRLEN(ml_get_curline()) + - curwin->w_cursor.col; + + // Delete the one character before the insert. + curwin->w_cursor = save_pos; + (void)del_char(FALSE); + curwin->w_cursor.col = STRLEN(ml_get_curline()) - bytes_after; + --todel; + } + while (todel-- > 0) + (void)del_char(FALSE); + endpos = curwin->w_cursor; if (did_change && curwin->w_cursor.col) --curwin->w_cursor.col;
--- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -1273,7 +1273,7 @@ func Test_prop_func_invalid_args() call assert_fails("call prop_type_list([])", 'E715:') endfunc -func Test_split_join() +func Test_prop_split_join() new call prop_type_add('test', {'highlight': 'ErrorMsg'}) call setline(1, 'just some text') @@ -1294,4 +1294,24 @@ func Test_split_join() call prop_type_delete('test') endfunc +func Test_prop_increment_decrement() + new + call prop_type_add('test', {'highlight': 'ErrorMsg'}) + call setline(1, 'its 998 times') + call prop_add(1, 5, {'length': 3, 'type': 'test'}) + + exe "normal! 0f9\<C-A>" + eval getline(1)->assert_equal('its 999 times') + eval prop_list(1)->assert_equal([ + \ #{id: 0, col: 5, end: 1, type: 'test', length: 3, start: 1}]) + + exe "normal! 0f9\<C-A>" + eval getline(1)->assert_equal('its 1000 times') + eval prop_list(1)->assert_equal([ + \ #{id: 0, col: 5, end: 1, type: 'test', length: 4, start: 1}]) + + bwipe! + call prop_type_delete('test') +endfunc + " vim: shiftwidth=2 sts=2 expandtab