patch 8.1.0675: text property column in screen columns is not practical
Problem: Text property column is screen columns is not practical.
Solution: Use byte values for the column.
diff --git a/src/proto/textprop.pro b/src/proto/textprop.pro
index 52bb6bc..5a648c4 100644
--- a/src/proto/textprop.pro
+++ b/src/proto/textprop.pro
@@ -13,4 +13,5 @@
void f_prop_type_list(typval_T *argvars, typval_T *rettv);
void clear_global_prop_types(void);
void clear_buf_prop_types(buf_T *buf);
+void adjust_prop_columns(linenr_T lnum, colnr_T col, int bytes_added);
/* vim: set ft=c : */
diff --git a/src/structs.h b/src/structs.h
index 4ac98b1..5b8c80b 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -705,7 +705,7 @@
*/
typedef struct textprop_S
{
- colnr_T tp_col; // start column (one based)
+ colnr_T tp_col; // start column (one based, in bytes)
colnr_T tp_len; // length in bytes
int tp_id; // identifier
int tp_type; // property type
diff --git a/src/testdir/dumps/Test_textprop_01.dump b/src/testdir/dumps/Test_textprop_01.dump
index e6e756d..f78c447 100644
--- a/src/testdir/dumps/Test_textprop_01.dump
+++ b/src/testdir/dumps/Test_textprop_01.dump
@@ -1,20 +1,6 @@
| +0#af5f00255#ffffff0@1|1| >O+0#0000000&|n|e| +0&#ffff4012|t|w|o| +0&#ffffff0@63
-| +0#af5f00255&@1|2| |N+0#0000000#ffff4012|u|m|b|e|r| |1+0#4040ff13&|2|3| +0#0000000&|a|n|d| |t|h|e|n| |4+0#4040ff13&|5|6|7|.+0#0000000&| +0&#ffffff0@45
-| +0#af5f00255&@1|3| |T+0#0000000#ffff4012|h|r|e+0&#ffffff0@1| @65
+| +0#af5f00255&@1|2| |N+0#0000000#ffff4012|u|m|b|é|r| |1+0#4040ff13&|2|3| +0#0000000&|ä|n|d| |t|h|œ|n| |4+0#4040ff13&|¾|7|.+0#0000000&| +0&#ffffff0@46
+| +0#af5f00255&@1|3| |T+0#0000000#ffff4012|h|r+0&#ffffff0|e@1| @65
|~+0#4040ff13&| @73
|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
| +0#0000000&@56|1|,|1| @10|A|l@1|
diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim
index ad6fd09..fdf6045 100644
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -7,6 +7,8 @@
source screendump.vim
+" test length zero
+
func Test_proptype_global()
call prop_type_add('comment', {'highlight': 'Directory', 'priority': 123, 'start_incl': 1, 'end_incl': 1})
let proptypes = prop_type_list()
@@ -112,6 +114,12 @@
1del
call assert_equal(s:expected_props, prop_list(1))
+ " Prop without length or end column is zero length
+ call prop_clear(1)
+ call prop_add(1, 5, {'type': 'two'})
+ let expected = [{'col': 5, 'length': 0, 'type': 'two', 'id': 0, 'start': 1, 'end': 1}]
+ call assert_equal(expected, prop_list(1))
+
call DeletePropTypes()
bwipe!
endfunc
@@ -220,7 +228,7 @@
call assert_equal([expect1], prop_list(1))
let expect2 = {'col': 1, 'length': 10, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
call assert_equal([expect2], prop_list(2))
- let expect3 = {'col': 1, 'length': 5, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
+ let expect3 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
call assert_equal([expect3], prop_list(3))
call prop_clear(1, 3)
@@ -236,30 +244,31 @@
bwipe!
- " Test deleting the first line with a prop.
+ " Test deleting the first line of a multi-line prop.
call Setup_three_line_prop()
+ let expect_short = {'col': 2, 'length': 1, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
+ call assert_equal([expect_short], prop_list(1))
let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
call assert_equal([expect2], prop_list(2))
2del
- let expect_short = {'col': 2, 'length': 1, 'type': 'comment', 'start': 1, 'end': 1, 'id': 0}
call assert_equal([expect_short], prop_list(1))
let expect2 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
call assert_equal([expect2], prop_list(2))
bwipe!
- " Test deleting the last line with a prop.
+ " Test deleting the last line of a multi-line prop.
call Setup_three_line_prop()
let expect3 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 0, 'end': 0, 'id': 0}
call assert_equal([expect3], prop_list(3))
- let expect4 = {'col': 1, 'length': 5, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
+ let expect4 = {'col': 1, 'length': 4, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
call assert_equal([expect4], prop_list(4))
4del
- let expect3 = {'col': 1, 'length': 6, 'type': 'comment', 'start': 0, 'end': 1, 'id': 0}
+ let expect3.end = 1
call assert_equal([expect3], prop_list(3))
call assert_equal([expect_short], prop_list(4))
bwipe!
- " Test appending a line below the text prop start.
+ " Test appending a line below the multi-line text prop start.
call Setup_three_line_prop()
let expect2 = {'col': 4, 'length': 4, 'type': 'comment', 'start': 1, 'end': 0, 'id': 0}
call assert_equal([expect2], prop_list(2))
@@ -287,22 +296,23 @@
" screenshot test with textprop highlighting
funct Test_textprop_screenshots()
- if !CanRunVimInTerminal()
+ if !CanRunVimInTerminal() || &encoding != 'utf-8'
return
endif
call writefile([
- \ "call setline(1, ['One two', 'Number 123 and then 4567.', 'Three'])",
+ \ "call setline(1, ['One two', 'Numbér 123 änd thœn 4¾7.', 'Three'])",
\ "hi NumberProp ctermfg=blue",
\ "hi LongProp ctermbg=yellow",
\ "call prop_type_add('number', {'highlight': 'NumberProp'})",
\ "call prop_type_add('long', {'highlight': 'LongProp'})",
\ "call prop_add(1, 4, {'end_lnum': 3, 'end_col': 3, 'type': 'long'})",
- \ "call prop_add(2, 8, {'length': 3, 'type': 'number'})",
- \ "call prop_add(2, 21, {'length': 4, 'type': 'number'})",
+ \ "call prop_add(2, 9, {'length': 3, 'type': 'number'})",
+ \ "call prop_add(2, 24, {'length': 4, 'type': 'number'})",
\ "set number",
+ \ "hi clear SpellBad",
\ "set spell",
\], 'XtestProp')
- let buf = RunVimInTerminal('-S XtestProp', {})
+ let buf = RunVimInTerminal('-S XtestProp', {'rows': 6})
call VerifyScreenDump(buf, 'Test_textprop_01', {})
" clean up
diff --git a/src/textprop.c b/src/textprop.c
index 016298b..ce6b66c 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -17,8 +17,8 @@
* Text properties have a type, which can be used to specify highlighting.
*
* TODO:
- * - Perhaps we only need TP_FLAG_CONT_NEXT ?
- * - Adjust text property column and length when text is inserted/deleted
+ * - Adjust text property column and length when text is inserted/deleted.
+ * - Perhaps we only need TP_FLAG_CONT_NEXT and can drop TP_FLAG_CONT_PREV?
* - Add an arrray for global_proptypes, to quickly lookup a prop type by ID
* - Add an arrray for b_proptypes, to quickly lookup a prop type by ID
* - Checking the text length to detect text properties is slow. Use a flag in
@@ -198,12 +198,12 @@
{
long length = dict_get_number(dict, (char_u *)"length");
- if (length < 1 || end_lnum > start_lnum)
+ if (length < 0 || end_lnum > start_lnum)
{
EMSG2(_(e_invargval), "length");
return;
}
- end_col = start_col + length - 1;
+ end_col = start_col + length;
}
else if (dict_find(dict, (char_u *)"end_col", -1) != NULL)
{
@@ -260,13 +260,13 @@
}
if (lnum == end_lnum)
- length = end_col - col + 1;
+ length = end_col - col;
else
length = textlen - col + 1;
if (length > (long)textlen)
- length = textlen; // can include the end-of-line
- if (length < 1)
- length = 1;
+ length = textlen; // can include the end-of-line
+ if (length < 0)
+ length = 0; // zero-width property
// Allocate the new line with space for the new proprety.
newtext = alloc(buf->b_ml.ml_line_len + sizeof(textprop_T));
@@ -912,4 +912,14 @@
buf->b_proptypes = NULL;
}
+/*
+ * Adjust the columns of text properties in line "lnum" after position "col" to
+ * shift by "bytes_added" (can be negative).
+ */
+ void
+adjust_prop_columns(linenr_T lnum UNUSED, colnr_T col UNUSED, int bytes_added UNUSED)
+{
+ // TODO
+}
+
#endif // FEAT_TEXT_PROP
diff --git a/src/version.c b/src/version.c
index 17f7733..e3db6e5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -800,6 +800,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 675,
+/**/
674,
/**/
673,