summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-01-09 21:35:48 +0100
committerBram Moolenaar <Bram@vim.org>2020-01-09 21:35:48 +0100
commitac15fd8c6761763c8feedef1a2fbd8309f0a823c (patch)
tree894e9e51f2f0a13c10cd3ac540db63d6f64beecd
parentbf0acff012c2f75563c20241f1a5478534fe2c7a (diff)
patch 8.2.0109: corrupted text properties when expanding spacesv8.2.0109
Problem: Corrupted text properties when expanding spaces. Solution: Reallocate the line. (Nobuhiro Takasaki, closes #5457)
-rw-r--r--src/edit.c20
-rw-r--r--src/testdir/test_textprop.vim77
-rw-r--r--src/version.c2
3 files changed, 86 insertions, 13 deletions
diff --git a/src/edit.c b/src/edit.c
index d2e45dd2f0..8160fe5693 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -5604,9 +5604,25 @@ ins_tab(void)
#ifdef FEAT_PROP_POPUP
if (!(State & VREPLACE_FLAG))
{
- mch_memmove(ptr, ptr + i, curbuf->b_ml.ml_line_len - i
- - (ptr - curbuf->b_ml.ml_line_ptr));
+ char_u *newp;
+ int col;
+
+ newp = alloc(curbuf->b_ml.ml_line_len - i);
+ if (newp == NULL)
+ return FALSE;
+
+ col = ptr - curbuf->b_ml.ml_line_ptr;
+ if (col > 0)
+ mch_memmove(newp, ptr - col, col);
+ mch_memmove(newp + col, ptr + i,
+ curbuf->b_ml.ml_line_len - col - i);
+
+ if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY)
+ vim_free(curbuf->b_ml.ml_line_ptr);
+ curbuf->b_ml.ml_line_ptr = newp;
curbuf->b_ml.ml_line_len -= i;
+ curbuf->b_ml.ml_flags =
+ (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
}
else
#endif
diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim
index 54b42c1467..c71f1a7d4d 100644
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -926,19 +926,32 @@ func Test_proptype_substitute2()
bwipe!
endfunc
+func SaveOptions()
+ let d = #{tabstop: &tabstop,
+ \ softtabstop: &softtabstop,
+ \ shiftwidth: &shiftwidth,
+ \ expandtab: &expandtab,
+ \ foldmethod: '"' .. &foldmethod .. '"',
+ \ }
+ return d
+endfunc
+
+func RestoreOptions(dict)
+ for name in keys(a:dict)
+ exe 'let &' .. name .. ' = ' .. a:dict[name]
+ endfor
+endfunc
+
func Test_textprop_noexpandtab()
- %bwipe!
new
- let save_ts = &tabstop
+ let save_dict = SaveOptions()
+
set tabstop=8
- let save_sts = &softtabstop
set softtabstop=4
- let save_sw = &shiftwidth
set shiftwidth=4
- let save_et = &expandtab
set noexpandtab
- let save_fdm = &foldmethod
set foldmethod=marker
+
call feedkeys("\<esc>\<esc>0Ca\<cr>\<esc>\<up>", "tx")
call prop_type_add('test', {'highlight': 'ErrorMsg'})
call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
@@ -955,9 +968,51 @@ func Test_textprop_noexpandtab()
catch /^Vim\%((\a\+)\)\=:E964/
endtry
call prop_remove({'type': 'test'})
- let &foldmethod = save_fdm
- let &expandtab = save_et
- let &shiftwidth = save_sw
- let &softtabstop = save_sts
- let &tabstop = save_ts
+ call prop_type_delete('test')
+
+ call RestoreOptions(save_dict)
+ bwipe!
+endfunc
+
+func Test_textprop_noexpandtab_redraw()
+ new
+ let save_dict = SaveOptions()
+
+ set tabstop=8
+ set softtabstop=4
+ set shiftwidth=4
+ set noexpandtab
+ set foldmethod=marker
+
+ call feedkeys("\<esc>\<esc>0Ca\<cr>\<space>\<esc>\<up>", "tx")
+ call prop_type_add('test', {'highlight': 'ErrorMsg'})
+ call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
+ call feedkeys("0i\<tab>", "tx")
+ " Internally broken at the next line
+ call feedkeys("A\<left>\<tab>", "tx")
+ redraw
+ " Index calculation failed internally on next line
+ call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
+ call prop_remove({'type': 'test', 'all': v:true})
+ call prop_type_delete('test')
+ call prop_type_delete('test')
+
+ call RestoreOptions(save_dict)
+ bwipe!
+endfunc
+
+func Test_textprop_ins_str()
+ new
+ call setline(1, 'just some text')
+ call prop_type_add('test', {'highlight': 'ErrorMsg'})
+ call prop_add(1, 1, {'end_col': 2, 'type': 'test'})
+ call assert_equal([{'id': 0, 'col': 1, 'end': 1, 'type': 'test', 'length': 1, 'start': 1}], prop_list(1))
+
+ call feedkeys("foi\<F8>\<Esc>", "tx")
+ call assert_equal('just s<F8>ome text', getline(1))
+ call assert_equal([{'id': 0, 'col': 1, 'end': 1, 'type': 'test', 'length': 1, 'start': 1}], prop_list(1))
+
+ bwipe!
+ call prop_remove({'type': 'test'})
+ call prop_type_delete('test')
endfunc
diff --git a/src/version.c b/src/version.c
index e06dfc6d1c..815fc472af 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 109,
+/**/
108,
/**/
107,