1
0
forked from aniani/vim

patch 9.0.0121: cannot put virtual text after or below a line

Problem:    Cannot put virtual text after or below a line.
Solution:   Add "text_align" and "text_wrap" arguments.
This commit is contained in:
Bram Moolenaar 2022-07-31 17:12:43 +01:00
parent 6b568b1cc7
commit b7963df98f
8 changed files with 246 additions and 48 deletions

View File

@ -141,7 +141,20 @@ prop_add({lnum}, {col}, {props})
then "id" must not be present and will be set then "id" must not be present and will be set
automatically to a negative number; otherwise automatically to a negative number; otherwise
zero is used zero is used
text text to be displayed at {col} text text to be displayed before {col}, or after the
line if {col} is zero
text_align when "text" is present and {col} is zero
specifies where to display the text:
after after the end of the line
right right aligned in the window
below in the next screen line
When omitted "after" is used.
text_wrap when "text" is present and {col} is zero,
specifies what happens if the text doesn't
fit:
wrap wrap the text to the next line
truncate truncate the text to make it fit
When omitted "truncate" is used.
type name of the text property type type name of the text property type
All fields except "type" are optional. All fields except "type" are optional.
@ -162,17 +175,26 @@ prop_add({lnum}, {col}, {props})
added to. When not found, the global property types are used. added to. When not found, the global property types are used.
If not found an error is given. If not found an error is given.
*virtual-text* *virtual-text*
When "text" is used this text will be displayed at the start When "text" is used and the column is non-zero then this text
location of the text property. The text of the buffer line will be displayed at the start location of the text property
will be shifted to make room. This is called "virtual text". after the text. The text of the buffer line will be shifted
to make room. This is called "virtual text".
When the column is zero the virtual text will appear after the
buffer text. The "text_align" and "text_wrap" arguments
determine how it is displayed.
The text will be displayed but it is not part of the actual The text will be displayed but it is not part of the actual
buffer line, the cursor cannot be placed on it. A mouse click buffer line, the cursor cannot be placed on it. A mouse click
in the text will move the cursor to the first character after in the text will move the cursor to the first character after
the text. the text, or the last character of the line.
A negative "id" will be chosen and is returned. Once a A negative "id" will be chosen and is returned. Once a
property with "text" has been added for a buffer then using a property with "text" has been added for a buffer then using a
negative "id" for any other property will give an error: negative "id" for any other property will give an error:
*E1293* *E1293*
Make sure to use a highlight that makes clear to the user that
this is virtual text, otherwise it will be very confusing that
the text cannot be edited.
To separate the virtual text from the buffer text prepend
and/or append spaces to the "text" field.
Can also be used as a |method|: > Can also be used as a |method|: >
GetLnum()->prop_add(col, props) GetLnum()->prop_add(col, props)

View File

@ -771,6 +771,7 @@ win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len)
chartabsize_T cts; chartabsize_T cts;
init_chartabsize_arg(&cts, wp, lnum, 0, line, line); init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
cts.cts_with_trailing = len = MAXCOL;
for ( ; *cts.cts_ptr != NUL && (len == MAXCOL || cts.cts_ptr < line + len); for ( ; *cts.cts_ptr != NUL && (len == MAXCOL || cts.cts_ptr < line + len);
MB_PTR_ADV(cts.cts_ptr)) MB_PTR_ADV(cts.cts_ptr))
cts.cts_vcol += win_lbr_chartabsize(&cts, NULL); cts.cts_vcol += win_lbr_chartabsize(&cts, NULL);
@ -1089,15 +1090,24 @@ win_lbr_chartabsize(
textprop_T *tp = cts->cts_text_props + i; textprop_T *tp = cts->cts_text_props + i;
if (tp->tp_id < 0 if (tp->tp_id < 0
&& tp->tp_col - 1 >= col && tp->tp_col - 1 < col + size && ((tp->tp_col - 1 >= col && tp->tp_col - 1 < col + size
&& -tp->tp_id <= wp->w_buffer->b_textprop_text.ga_len) && -tp->tp_id <= wp->w_buffer->b_textprop_text.ga_len)
|| (tp->tp_col == MAXCOL && (s[0] == NUL || s[1] == NUL)
&& cts->cts_with_trailing)))
{ {
char_u *p = ((char_u **)wp->w_buffer->b_textprop_text.ga_data)[ char_u *p = ((char_u **)wp->w_buffer->b_textprop_text.ga_data)[
-tp->tp_id - 1]; -tp->tp_id - 1];
int len = (int)STRLEN(p);
// TODO: count screen cells // TODO: count screen cells
cts->cts_cur_text_width = (int)STRLEN(p); if (tp->tp_col == MAXCOL)
size += cts->cts_cur_text_width; {
break; // TODO: truncating
if (tp->tp_flags & TP_FLAG_ALIGN_BELOW)
len += wp->w_width - (vcol + size) % wp->w_width;
}
cts->cts_cur_text_width += len;
size += len;
} }
if (tp->tp_col - 1 > col) if (tp->tp_col - 1 > col)
break; break;

View File

@ -208,13 +208,16 @@ static buf_T *current_buf = NULL;
text_prop_compare(const void *s1, const void *s2) text_prop_compare(const void *s1, const void *s2)
{ {
int idx1, idx2; int idx1, idx2;
textprop_T *tp1, *tp2;
proptype_T *pt1, *pt2; proptype_T *pt1, *pt2;
colnr_T col1, col2; colnr_T col1, col2;
idx1 = *(int *)s1; idx1 = *(int *)s1;
idx2 = *(int *)s2; idx2 = *(int *)s2;
pt1 = text_prop_type_by_id(current_buf, current_text_props[idx1].tp_type); tp1 = &current_text_props[idx1];
pt2 = text_prop_type_by_id(current_buf, current_text_props[idx2].tp_type); tp2 = &current_text_props[idx2];
pt1 = text_prop_type_by_id(current_buf, tp1->tp_type);
pt2 = text_prop_type_by_id(current_buf, tp2->tp_type);
if (pt1 == pt2) if (pt1 == pt2)
return 0; return 0;
if (pt1 == NULL) if (pt1 == NULL)
@ -223,8 +226,25 @@ text_prop_compare(const void *s1, const void *s2)
return 1; return 1;
if (pt1->pt_priority != pt2->pt_priority) if (pt1->pt_priority != pt2->pt_priority)
return pt1->pt_priority > pt2->pt_priority ? 1 : -1; return pt1->pt_priority > pt2->pt_priority ? 1 : -1;
col1 = current_text_props[idx1].tp_col; col1 = tp1->tp_col;
col2 = current_text_props[idx2].tp_col; col2 = tp2->tp_col;
if (col1 == MAXCOL && col2 == MAXCOL)
{
int flags1 = 0;
int flags2 = 0;
// order on 0: after, 1: right, 2: below
if (tp1->tp_flags & TP_FLAG_ALIGN_RIGHT)
flags1 = 1;
if (tp1->tp_flags & TP_FLAG_ALIGN_BELOW)
flags1 = 2;
if (tp2->tp_flags & TP_FLAG_ALIGN_RIGHT)
flags2 = 1;
if (tp2->tp_flags & TP_FLAG_ALIGN_BELOW)
flags2 = 2;
if (flags1 != flags2)
return flags1 < flags2 ? 1 : -1;
}
return col1 == col2 ? 0 : col1 > col2 ? 1 : -1; return col1 == col2 ? 0 : col1 > col2 ? 1 : -1;
} }
#endif #endif
@ -282,6 +302,7 @@ win_line(
int saved_char_attr = 0; int saved_char_attr = 0;
int n_attr = 0; // chars with special attr int n_attr = 0; // chars with special attr
int n_attr_skip = 0; // chars to skip before using extra_attr
int saved_attr2 = 0; // char_attr saved for n_attr int saved_attr2 = 0; // char_attr saved for n_attr
int n_attr3 = 0; // chars with overruling special attr int n_attr3 = 0; // chars with overruling special attr
int saved_attr3 = 0; // char_attr saved for n_attr3 int saved_attr3 = 0; // char_attr saved for n_attr3
@ -328,6 +349,7 @@ win_line(
int text_prop_attr = 0; int text_prop_attr = 0;
int text_prop_id = 0; // active property ID int text_prop_id = 0; // active property ID
int text_prop_combine = FALSE; int text_prop_combine = FALSE;
int text_prop_follows = FALSE; // another text prop to display
#endif #endif
#ifdef FEAT_SPELL #ifdef FEAT_SPELL
int has_spell = FALSE; // this buffer has spell checking int has_spell = FALSE; // this buffer has spell checking
@ -1472,7 +1494,9 @@ win_line(
# endif # endif
// Add any text property that starts in this column. // Add any text property that starts in this column.
while (text_prop_next < text_prop_count while (text_prop_next < text_prop_count
&& bcol >= text_props[text_prop_next].tp_col - 1) && (text_props[text_prop_next].tp_col == MAXCOL
? *ptr == NUL
: bcol >= text_props[text_prop_next].tp_col - 1))
{ {
if (bcol <= text_props[text_prop_next].tp_col - 1 if (bcol <= text_props[text_prop_next].tp_col - 1
+ text_props[text_prop_next].tp_len) + text_props[text_prop_next].tp_len)
@ -1484,13 +1508,15 @@ win_line(
text_prop_combine = FALSE; text_prop_combine = FALSE;
text_prop_type = NULL; text_prop_type = NULL;
text_prop_id = 0; text_prop_id = 0;
if (text_props_active > 0) if (text_props_active > 0 && n_extra == 0)
{ {
int used_tpi = -1; int used_tpi = -1;
int used_attr = 0; int used_attr = 0;
int other_tpi = -1;
// Sort the properties on priority and/or starting last. // Sort the properties on priority and/or starting last.
// Then combine the attributes, highest priority last. // Then combine the attributes, highest priority last.
text_prop_follows = FALSE;
current_text_props = text_props; current_text_props = text_props;
current_buf = wp->w_buffer; current_buf = wp->w_buffer;
qsort((void *)text_prop_idxs, (size_t)text_props_active, qsort((void *)text_prop_idxs, (size_t)text_props_active,
@ -1511,10 +1537,11 @@ win_line(
hl_combine_attr(text_prop_attr, used_attr); hl_combine_attr(text_prop_attr, used_attr);
text_prop_combine = pt->pt_flags & PT_FLAG_COMBINE; text_prop_combine = pt->pt_flags & PT_FLAG_COMBINE;
text_prop_id = text_props[tpi].tp_id; text_prop_id = text_props[tpi].tp_id;
other_tpi = used_tpi;
used_tpi = tpi; used_tpi = tpi;
} }
} }
if (n_extra == 0 && text_prop_id < 0 && used_tpi >= 0 if (text_prop_id < 0 && used_tpi >= 0
&& -text_prop_id && -text_prop_id
<= wp->w_buffer->b_textprop_text.ga_len) <= wp->w_buffer->b_textprop_text.ga_len)
{ {
@ -1523,6 +1550,11 @@ win_line(
-text_prop_id - 1]; -text_prop_id - 1];
if (p != NULL) if (p != NULL)
{ {
int right = (text_props[used_tpi].tp_flags
& TP_FLAG_ALIGN_RIGHT);
int below = (text_props[used_tpi].tp_flags
& TP_FLAG_ALIGN_BELOW);
p_extra = p; p_extra = p;
c_extra = NUL; c_extra = NUL;
c_final = NUL; c_final = NUL;
@ -1530,6 +1562,33 @@ win_line(
extra_attr = used_attr; extra_attr = used_attr;
n_attr = n_extra; n_attr = n_extra;
text_prop_attr = 0; text_prop_attr = 0;
if (*ptr == NUL)
// don't combine char attr after EOL
text_prop_combine = FALSE;
// TODO: truncation if it doesn't fit
if (right || below)
{
int added = wp->w_width - col;
char_u *l;
// Right-align: fill with spaces
// TODO: count screen columns
if (right)
added -= n_extra;
if (added < 0 || (below && col == 0))
added = 0;
l = alloc(n_extra + added + 1);
if (l != NULL)
{
vim_memset(l, ' ', added);
STRCPY(l + added, p);
vim_free(p_extra_free);
p_extra = p_extra_free = l;
n_extra += added;
n_attr_skip = added;
}
}
// If the cursor is on or after this position, // If the cursor is on or after this position,
// move it forward. // move it forward.
@ -1541,6 +1600,10 @@ win_line(
// reset the ID in the copy to avoid it being used // reset the ID in the copy to avoid it being used
// again // again
text_props[used_tpi].tp_id = -MAXCOL; text_props[used_tpi].tp_id = -MAXCOL;
// If another text prop follows the condition below at
// the last window column must know.
text_prop_follows = other_tpi != -1;
} }
} }
} }
@ -2641,8 +2704,9 @@ win_line(
} }
#endif #endif
// Don't override visual selection highlighting. // Use "extra_attr", but don't override visual selection highlighting.
if (n_attr > 0 // Don't use "extra_attr" until n_attr_skip is zero.
if (n_attr_skip == 0 && n_attr > 0
&& draw_state == WL_LINE && draw_state == WL_LINE
&& !attr_pri) && !attr_pri)
{ {
@ -3188,8 +3252,11 @@ win_line(
char_attr = saved_attr3; char_attr = saved_attr3;
// restore attributes after last 'listchars' or 'number' char // restore attributes after last 'listchars' or 'number' char
if (n_attr > 0 && draw_state == WL_LINE && --n_attr == 0) if (n_attr > 0 && draw_state == WL_LINE
&& n_attr_skip == 0 && --n_attr == 0)
char_attr = saved_attr2; char_attr = saved_attr2;
if (n_attr_skip > 0)
--n_attr_skip;
// At end of screen line and there is more to come: Display the line // At end of screen line and there is more to come: Display the line
// so far. If there is no more to display it is caught above. // so far. If there is no more to display it is caught above.
@ -3202,6 +3269,9 @@ win_line(
|| *ptr != NUL || *ptr != NUL
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
|| filler_todo > 0 || filler_todo > 0
#endif
#ifdef FEAT_PROP_POPUP
|| text_prop_follows
#endif #endif
|| (wp->w_p_list && wp->w_lcs_chars.eol != NUL || (wp->w_p_list && wp->w_lcs_chars.eol != NUL
&& p_extra != at_end_str) && p_extra != at_end_str)
@ -3224,6 +3294,9 @@ win_line(
if ((!wp->w_p_wrap if ((!wp->w_p_wrap
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
&& filler_todo <= 0 && filler_todo <= 0
#endif
#ifdef FEAT_PROP_POPUP
&& !text_prop_follows
#endif #endif
) || lcs_eol_one == -1) ) || lcs_eol_one == -1)
break; break;
@ -3250,6 +3323,9 @@ win_line(
if (screen_cur_row == screen_row - 1 if (screen_cur_row == screen_row - 1
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
&& filler_todo <= 0 && filler_todo <= 0
#endif
#ifdef FEAT_PROP_POPUP
&& !text_prop_follows
#endif #endif
&& wp->w_width == Columns) && wp->w_width == Columns)
{ {

View File

@ -808,7 +808,13 @@ typedef struct textprop_S
#define TP_FLAG_CONT_NEXT 0x1 // property continues in next line #define TP_FLAG_CONT_NEXT 0x1 // property continues in next line
#define TP_FLAG_CONT_PREV 0x2 // property was continued from prev line #define TP_FLAG_CONT_PREV 0x2 // property was continued from prev line
#define TP_VIRTUAL 0x4 // virtual text, uses tp_id
// without these text is placed after the end of the line
#define TP_FLAG_ALIGN_RIGHT 0x10 // virtual text is right-aligned
#define TP_FLAG_ALIGN_BELOW 0x20 // virtual text on next screen line
#define TP_FLAG_WRAP 0x40 // virtual text wraps - when missing
// text is truncated
/* /*
* Structure defining a property type. * Structure defining a property type.
@ -4575,6 +4581,8 @@ typedef struct {
textprop_T *cts_text_props; // text props (allocated) textprop_T *cts_text_props; // text props (allocated)
char cts_has_prop_with_text; // TRUE if if a property inserts text char cts_has_prop_with_text; // TRUE if if a property inserts text
int cts_cur_text_width; // width of current inserted text int cts_cur_text_width; // width of current inserted text
int cts_with_trailing; // include size of trailing props with
// last character
#endif #endif
int cts_vcol; // virtual column at current position int cts_vcol; // virtual column at current position
} chartabsize_T; } chartabsize_T;

View File

@ -0,0 +1,6 @@
>s+0&#ffffff0|o|m|e| |t|e|x|t| |h|e|r|e| |a|n|d| |o|t|h|e|r| |t|e|x|t| |t|h|e|r|e| +0&#ffff4012|A|F|T|E|R| | +0&#ffffff0@10| +0#ffffff16#e000002|R|I|G|H|T|
| +0#0000000#5fd7ff255|B|E|L|O|W| | +0&#ffffff0@52
|~+0#4040ff13&| @58
|~| @58
|~| @58
| +0#0000000&@41|1|,|1| @10|A|l@1|

View File

@ -2213,6 +2213,26 @@ func Test_prop_inserts_text()
call delete('XscriptPropsWithText') call delete('XscriptPropsWithText')
endfunc endfunc
func Test_props_with_text_after()
CheckRunVimInTerminal
let lines =<< trim END
call setline(1, 'some text here and other text there')
call prop_type_add('rightprop', #{highlight: 'ErrorMsg'})
call prop_type_add('afterprop', #{highlight: 'Search'})
call prop_type_add('belowprop', #{highlight: 'DiffAdd'})
call prop_add(1, 0, #{type: 'rightprop', text: ' RIGHT ', text_align: 'right'})
call prop_add(1, 0, #{type: 'afterprop', text: ' AFTER ', text_align: 'after'})
call prop_add(1, 0, #{type: 'belowprop', text: ' BELOW ', text_align: 'below'})
END
call writefile(lines, 'XscriptPropsWithTextAfter')
let buf = RunVimInTerminal('-S XscriptPropsWithTextAfter', #{rows: 6, cols: 60})
call VerifyScreenDump(buf, 'Test_prop_with_text_after_1', {})
call StopVimInTerminal(buf)
call delete('XscriptPropsWithTextAfter')
endfunc
func Test_removed_prop_with_text_cleans_up_array() func Test_removed_prop_with_text_cleans_up_array()
new new
call setline(1, 'some text here') call setline(1, 'some text here')

View File

@ -163,11 +163,6 @@ f_prop_add(typval_T *argvars, typval_T *rettv)
start_lnum = tv_get_number(&argvars[0]); start_lnum = tv_get_number(&argvars[0]);
start_col = tv_get_number(&argvars[1]); start_col = tv_get_number(&argvars[1]);
if (start_col < 1)
{
semsg(_(e_invalid_column_number_nr), (long)start_col);
return;
}
if (argvars[2].v_type != VAR_DICT) if (argvars[2].v_type != VAR_DICT)
{ {
emsg(_(e_dictionary_required)); emsg(_(e_dictionary_required));
@ -190,6 +185,7 @@ prop_add_one(
char_u *type_name, char_u *type_name,
int id, int id,
char_u *text_arg, char_u *text_arg,
int text_flags,
linenr_T start_lnum, linenr_T start_lnum,
linenr_T end_lnum, linenr_T end_lnum,
colnr_T start_col, colnr_T start_col,
@ -256,7 +252,7 @@ prop_add_one(
col = start_col; col = start_col;
else else
col = 1; col = 1;
if (col - 1 > (colnr_T)textlen) if (col - 1 > (colnr_T)textlen && !(col == 0 && text_arg != NULL))
{ {
semsg(_(e_invalid_column_number_nr), (long)start_col); semsg(_(e_invalid_column_number_nr), (long)start_col);
goto theend; goto theend;
@ -271,6 +267,13 @@ prop_add_one(
if (length < 0) if (length < 0)
length = 0; // zero-width property length = 0; // zero-width property
if (text_arg != NULL)
{
length = 1; // text is placed on one character
if (col == 0)
col = MAXCOL; // after the line
}
// Allocate the new line with space for the new property. // Allocate the new line with space for the new property.
newtext = alloc(buf->b_ml.ml_line_len + sizeof(textprop_T)); newtext = alloc(buf->b_ml.ml_line_len + sizeof(textprop_T));
if (newtext == NULL) if (newtext == NULL)
@ -296,7 +299,8 @@ prop_add_one(
tmp_prop.tp_len = length; tmp_prop.tp_len = length;
tmp_prop.tp_id = id; tmp_prop.tp_id = id;
tmp_prop.tp_type = type->pt_id; tmp_prop.tp_type = type->pt_id;
tmp_prop.tp_flags = (lnum > start_lnum ? TP_FLAG_CONT_PREV : 0) tmp_prop.tp_flags = text_flags
| (lnum > start_lnum ? TP_FLAG_CONT_PREV : 0)
| (lnum < end_lnum ? TP_FLAG_CONT_NEXT : 0); | (lnum < end_lnum ? TP_FLAG_CONT_NEXT : 0);
mch_memmove(newprops + i * sizeof(textprop_T), &tmp_prop, mch_memmove(newprops + i * sizeof(textprop_T), &tmp_prop,
sizeof(textprop_T)); sizeof(textprop_T));
@ -390,7 +394,7 @@ f_prop_add_list(typval_T *argvars, typval_T *rettv UNUSED)
emsg(_(e_invalid_argument)); emsg(_(e_invalid_argument));
return; return;
} }
if (prop_add_one(buf, type_name, id, NULL, start_lnum, end_lnum, if (prop_add_one(buf, type_name, id, NULL, 0, start_lnum, end_lnum,
start_col, end_col) == FAIL) start_col, end_col) == FAIL)
return; return;
} }
@ -428,6 +432,7 @@ prop_add_common(
buf_T *buf = default_buf; buf_T *buf = default_buf;
int id = 0; int id = 0;
char_u *text = NULL; char_u *text = NULL;
int flags = 0;
if (dict == NULL || !dict_has_key(dict, "type")) if (dict == NULL || !dict_has_key(dict, "type"))
{ {
@ -483,6 +488,45 @@ prop_add_common(
goto theend; goto theend;
// use a default length of 1 to make multiple props show up // use a default length of 1 to make multiple props show up
end_col = start_col + 1; end_col = start_col + 1;
if (dict_has_key(dict, "text_align"))
{
char_u *p = dict_get_string(dict, "text_align", FALSE);
if (p == NULL)
goto theend;
if (STRCMP(p, "right") == 0)
flags |= TP_FLAG_ALIGN_RIGHT;
else if (STRCMP(p, "below") == 0)
flags |= TP_FLAG_ALIGN_BELOW;
else if (STRCMP(p, "after") != 0)
{
semsg(_(e_invalid_value_for_argument_str_str), "text_align", p);
goto theend;
}
}
if (dict_has_key(dict, "text_wrap"))
{
char_u *p = dict_get_string(dict, "text_wrap", FALSE);
if (p == NULL)
goto theend;
if (STRCMP(p, "wrap") == 0)
flags |= TP_FLAG_WRAP;
else if (STRCMP(p, "truncate") != 0)
{
semsg(_(e_invalid_value_for_argument_str_str), "text_wrap", p);
goto theend;
}
}
}
// Column must be 1 or more for a normal text property; when "text" is
// present zero means it goes after the line.
if (start_col < (text == NULL ? 1 : 0))
{
semsg(_(e_invalid_column_number_nr), (long)start_col);
goto theend;
} }
if (dict_arg != NULL && get_bufnr_from_arg(dict_arg, &buf) == FAIL) if (dict_arg != NULL && get_bufnr_from_arg(dict_arg, &buf) == FAIL)
@ -501,7 +545,7 @@ prop_add_common(
// correctly set. // correctly set.
buf->b_has_textprop = TRUE; // this is never reset buf->b_has_textprop = TRUE; // this is never reset
prop_add_one(buf, type_name, id, text, prop_add_one(buf, type_name, id, text, flags,
start_lnum, end_lnum, start_col, end_col); start_lnum, end_lnum, start_col, end_col);
text = NULL; text = NULL;
@ -1743,17 +1787,27 @@ adjust_prop(
int added, int added,
int flags) int flags)
{ {
proptype_T *pt = text_prop_type_by_id(curbuf, prop->tp_type); proptype_T *pt;
int start_incl = (pt != NULL int start_incl;
&& (pt->pt_flags & PT_FLAG_INS_START_INCL)) int end_incl;
int droppable;
adjustres_T res = {TRUE, FALSE};
// prop after end of the line doesn't move
if (prop->tp_col == MAXCOL)
{
res.dirty = FALSE;
return res;
}
pt = text_prop_type_by_id(curbuf, prop->tp_type);
start_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_START_INCL))
|| (flags & APC_SUBSTITUTE) || (flags & APC_SUBSTITUTE)
|| (prop->tp_flags & TP_FLAG_CONT_PREV); || (prop->tp_flags & TP_FLAG_CONT_PREV);
int end_incl = (pt != NULL end_incl = (pt != NULL && (pt->pt_flags & PT_FLAG_INS_END_INCL))
&& (pt->pt_flags & PT_FLAG_INS_END_INCL))
|| (prop->tp_flags & TP_FLAG_CONT_NEXT); || (prop->tp_flags & TP_FLAG_CONT_NEXT);
// Do not drop zero-width props if they later can increase in size. // do not drop zero-width props if they later can increase in size
int droppable = !(start_incl || end_incl); droppable = !(start_incl || end_incl);
adjustres_T res = {TRUE, FALSE};
if (added > 0) if (added > 0)
{ {

View File

@ -735,6 +735,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
121,
/**/ /**/
120, 120,
/**/ /**/