Compare commits

..

8 Commits

Author SHA1 Message Date
Bram Moolenaar
2254a8ad0c patch 8.0.1044: warning for uninitialized variable
Problem:    Warning for uninitialized variable. (John Marriott)
Solution:   Initialize ind_pre.
2017-09-03 14:03:43 +02:00
Bram Moolenaar
4ec86ddd77 patch 8.0.1043: warning for uninitialized variable
Problem:    Warning for uninitialized variable. (John Marriott)
Solution:   Move code to check indent inside "if".
2017-09-02 23:28:54 +02:00
Bram Moolenaar
9f45ccd1bf patch 8.0.1042: without the syntax feature highlighting doesn't work
Problem:    Without the syntax feature highlighting doesn't work.
Solution:   Always use unsigned short to store attributes.
2017-09-02 20:40:35 +02:00
Bram Moolenaar
e2e69e4813 patch 8.0.1041: bogus characters when indenting during visual-block append
Problem:    Bogus characters appear when indenting kicks in while doing a
            visual-block append.
Solution:   Recompute when indenting is done. (Christian Brabandt)
2017-09-02 20:30:35 +02:00
Bram Moolenaar
3653822546 patch 8.0.1040: cannot use another error format in getqflist()
Problem:    Cannot use another error format in getqflist().
Solution:   Add the "efm" argument to getqflist(). (Yegappan Lakshmanan)
2017-09-02 19:51:44 +02:00
Bram Moolenaar
b31cf2bb0b patch 8.0.1039: cannot change a line in not current buffer
Problem:    Cannot change a line in a buffer other than the current one.
Solution:   Add setbufline(). (Yasuhiro Matsumoto, Ozaki Kiichi, closes #1953)
2017-09-02 19:45:19 +02:00
Bram Moolenaar
cf4b00c856 patch 8.0.1038: strike-through text not supported
Problem:    Strike-through text not supported.
Solution:   Add support for the "strikethrough" attribute. (Christian
            Brabandt, Ken Takata)
2017-09-02 18:33:56 +02:00
Bram Moolenaar
da22b8cc8b patch 8.0.1037: "icase" of 'diffopt' is not used for highlighting
Problem:    "icase" of 'diffopt' is not used for highlighting differences.
Solution:   Also use "icase". (Rick Howe)
2017-09-02 18:01:50 +02:00
34 changed files with 473 additions and 131 deletions

View File

@@ -2316,6 +2316,9 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]])
server2client({clientid}, {string})
Number send reply string
serverlist() String get a list of available servers
setbufline( {expr}, {lnum}, {line})
Number set line {lnum} to {line} in buffer
{expr}
setbufvar({expr}, {varname}, {val})
none set {varname} in buffer {expr} to {val}
setcharsearch({dict}) Dict set character search from {dict}
@@ -4632,16 +4635,19 @@ getqflist([{what}]) *getqflist()*
returns only the items listed in {what} as a dictionary. The
following string items are supported in {what}:
context get the context stored with |setqflist()|
efm errorformat to use when parsing "lines". If
not present, then the 'erroformat' option
value is used.
id get information for the quickfix list with
|quickfix-ID|; zero means the id for the
current list or the list specifed by 'nr'
current list or the list specifed by "nr"
items quickfix list entries
lines use 'errorformat' to extract items from a list
of lines and return the resulting entries.
Only a |List| type is accepted. The current
quickfix list is not modified.
nr get information for this quickfix list; zero
means the current quickfix list and '$' means
means the current quickfix list and "$" means
the last quickfix list
title get the list title
winid get the |window-ID| (if opened)
@@ -6858,6 +6864,19 @@ serverlist() *serverlist()*
Example: >
:echo serverlist()
<
setbufline({expr}, {lnum}, {text}) *setbufline()*
Set line {lnum} to {text} in buffer {expr}. To insert
lines use |append()|.
For the use of {expr}, see |bufname()| above.
{lnum} is used like with |setline()|.
This works like |setline()| for the specified buffer.
On success 0 is returned, on failure 1 is returned.
If {expr} is not a valid buffer or {lnum} is not valid, an
error message is given.
setbufvar({expr}, {varname}, {val}) *setbufvar()*
Set option or local variable {varname} in buffer {expr} to
{val}.
@@ -6926,13 +6945,19 @@ setfperm({fname}, {mode}) *setfperm()* *chmod*
setline({lnum}, {text}) *setline()*
Set line {lnum} of the current buffer to {text}. To insert
lines use |append()|.
lines use |append()|. To set lines in another buffer use
|setbufline()|.
{lnum} is used like with |getline()|.
When {lnum} is just below the last line the {text} will be
added as a new line.
If this succeeds, 0 is returned. If this fails (most likely
because {lnum} is invalid) 1 is returned. Example: >
because {lnum} is invalid) 1 is returned.
Example: >
:call setline(5, strftime("%c"))
< When {text} is a |List| then line {lnum} and following lines
will be set to the items in the list. Example: >
:call setline(5, ['aaa', 'bbb', 'ccc'])
@@ -7064,13 +7089,16 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
is created. The new quickfix list is added after the current
quickfix list in the stack and all the following lists are
freed. To add a new quickfix list at the end of the stack,
set "nr" in {what} to '$'.
set "nr" in {what} to "$".
If the optional {what} dictionary argument is supplied, then
only the items listed in {what} are set. The first {list}
argument is ignored. The following items can be specified in
{what}:
context any Vim type can be stored as a context
efm errorformat to use when parsing text from
"lines". If this is not present, then the
'errorformat' option value is used.
id quickfix list identifier |quickfix-ID|
items list of quickfix entries. Same as the {list}
argument.
@@ -7078,7 +7106,7 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
add the resulting entries to the quickfix list
{nr} or {id}. Only a |List| value is supported.
nr list number in the quickfix stack; zero
means the current quickfix list and '$' means
means the current quickfix list and "$" means
the last quickfix list
title quickfix list title text
Unsupported keys in {what} are ignored.
@@ -7086,7 +7114,7 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
is modified. When creating a new quickfix list, "nr" can be
set to a value one greater than the quickfix stack size.
When modifying a quickfix list, to guarantee that the correct
list is modified, 'id' should be used instead of 'nr' to
list is modified, "id" should be used instead of "nr" to
specify the list.
Examples: >
@@ -7723,6 +7751,7 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
"standout" "1" if standout
"underline" "1" if underlined
"undercurl" "1" if undercurled
"strike" "1" if strikethrough
Example (echoes the color of the syntax item under the
cursor): >

View File

@@ -4105,6 +4105,7 @@ A jump table for the options with a short description can be found at |Q_op|.
s standout (termcap entry "so" and "se")
u underline (termcap entry "us" and "ue")
c undercurl (termcap entry "Cs" and "Ce")
t strikethrough (termcap entry "Ts" and "Te")
n no highlighting
- no highlighting
: use a highlight group

View File

@@ -4699,13 +4699,14 @@ the same syntax file on all terminals, and use the optimal highlighting.
*bold* *underline* *undercurl*
*inverse* *italic* *standout*
*nocombine*
*nocombine* *strikethrough*
term={attr-list} *attr-list* *highlight-term* *E418*
attr-list is a comma separated list (without spaces) of the
following items (in any order):
bold
underline
undercurl not always available
strikethrough not always available
reverse
inverse same as reverse
italic
@@ -4716,8 +4717,8 @@ term={attr-list} *attr-list* *highlight-term* *E418*
Note that "bold" can be used here and by using a bold font. They
have the same effect.
"undercurl" is a curly underline. When "undercurl" is not possible
then "underline" is used. In general "undercurl" is only available in
the GUI. The color is set with |highlight-guisp|.
then "underline" is used. In general "undercurl" and "strikethrough"
is only available in the GUI. The color is set with |highlight-guisp|.
start={term-list} *highlight-start* *E422*
stop={term-list} *term-list* *highlight-stop*
@@ -4882,7 +4883,8 @@ guifg={color-name} *highlight-guifg*
guibg={color-name} *highlight-guibg*
guisp={color-name} *highlight-guisp*
These give the foreground (guifg), background (guibg) and special
(guisp) color to use in the GUI. "guisp" is used for undercurl.
(guisp) color to use in the GUI. "guisp" is used for undercurl and
strikethrough.
There are a few special names:
NONE no color (transparent)
bg use normal background color

View File

@@ -314,8 +314,8 @@ Visual-block Insert *v_b_I*
With a blockwise selection, I{string}<ESC> will insert {string} at the start
of block on every line of the block, provided that the line extends into the
block. Thus lines that are short will remain unmodified. TABs are split to
retain visual columns.
See |v_b_I_example|.
retain visual columns. Works only for adding text to a line, not for
deletions. See |v_b_I_example|.
Visual-block Append *v_b_A*
With a blockwise selection, A{string}<ESC> will append {string} to the end of
@@ -331,6 +331,7 @@ See |v_b_A_example|.
Note: "I" and "A" behave differently for lines that don't extend into the
selected block. This was done intentionally, so that you can do it the way
you want.
Works only for adding text to a line, not for deletions.
Visual-block change *v_b_c*
All selected text in the block will be replaced by the same text string. When

View File

@@ -2122,6 +2122,7 @@ test_arglist \
test_autocmd \
test_backspace_opt \
test_breakindent \
test_bufline \
test_bufwintabinfo \
test_cd \
test_cdo \

View File

@@ -1535,6 +1535,22 @@ skipwhite(char_u *q)
return p;
}
/*
* getwhitecols: return the number of whitespace
* columns (bytes) at the start of a given line
*/
int
getwhitecols_curline()
{
return getwhitecols(ml_get_curline());
}
int
getwhitecols(char_u *p)
{
return skipwhite(p) - p;
}
/*
* skip over digits
*/

View File

@@ -1949,6 +1949,40 @@ diffopt_horizontal(void)
return (diff_flags & DIFF_HORIZONTAL) != 0;
}
/*
* Compare the characters at "p1" and "p2". If they are equal (possibly
* ignoring case) return TRUE and set "len" to the number of bytes.
*/
static int
diff_equal_char(char_u *p1, char_u *p2, int *len)
{
#ifdef FEAT_MBYTE
int l = (*mb_ptr2len)(p1);
if (l != (*mb_ptr2len)(p2))
return FALSE;
if (l > 1)
{
if (STRNCMP(p1, p2, l) != 0
&& (!enc_utf8
|| !(diff_flags & DIFF_ICASE)
|| utf_fold(utf_ptr2char(p1))
!= utf_fold(utf_ptr2char(p2))))
return FALSE;
*len = l;
}
else
#endif
{
if ((*p1 != *p2)
&& (!(diff_flags & DIFF_ICASE)
|| TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2)))
return FALSE;
*len = 1;
}
return TRUE;
}
/*
* Find the difference within a changed line.
* Returns TRUE if the line was added, no other buffer has it.
@@ -1969,6 +2003,10 @@ diff_find_change(
int idx;
int off;
int added = TRUE;
#ifdef FEAT_MBYTE
char_u *p1, *p2;
int l;
#endif
/* Make a copy of the line, the next ml_get() will invalidate it. */
line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE));
@@ -2017,10 +2055,11 @@ diff_find_change(
}
else
{
if (line_org[si_org] != line_new[si_new])
if (!diff_equal_char(line_org + si_org, line_new + si_new,
&l))
break;
++si_org;
++si_new;
si_org += l;
si_new += l;
}
}
#ifdef FEAT_MBYTE
@@ -2056,10 +2095,16 @@ diff_find_change(
}
else
{
if (line_org[ei_org] != line_new[ei_new])
p1 = line_org + ei_org;
p2 = line_new + ei_new;
#ifdef FEAT_MBYTE
p1 -= (*mb_head_off)(line_org, p1);
p2 -= (*mb_head_off)(line_new, p2);
#endif
if (!diff_equal_char(p1, p2, &l))
break;
--ei_org;
--ei_new;
ei_org -= l;
ei_new -= l;
}
}
if (*endp < ei_org)

View File

@@ -5182,7 +5182,7 @@ ins_complete(int c, int enable_pum)
* first non_blank in the line, if it is not a wordchar
* include it to get a better pattern, but then we don't
* want the "\\<" prefix, check it bellow */
compl_col = (colnr_T)(skipwhite(line) - line);
compl_col = (colnr_T)getwhitecols(line);
compl_startpos.col = compl_col;
compl_startpos.lnum = curwin->w_cursor.lnum;
compl_cont_status &= ~CONT_SOL; /* clear SOL if present */
@@ -5348,7 +5348,7 @@ ins_complete(int c, int enable_pum)
}
else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
{
compl_col = (colnr_T)(skipwhite(line) - line);
compl_col = (colnr_T)getwhitecols(line);
compl_length = (int)curs_col - (int)compl_col;
if (compl_length < 0) /* cursor in indent: empty pattern */
compl_length = 0;
@@ -8208,8 +8208,7 @@ in_cinkeys(
{
/* "0=word": Check if there are only blanks before the
* word. */
line = ml_get_curline();
if ((int)(skipwhite(line) - line) !=
if (getwhitecols(line) !=
(int)(curwin->w_cursor.col - (p - look)))
match = FALSE;
}

View File

@@ -328,6 +328,7 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
static void f_searchpos(typval_T *argvars, typval_T *rettv);
static void f_server2client(typval_T *argvars, typval_T *rettv);
static void f_serverlist(typval_T *argvars, typval_T *rettv);
static void f_setbufline(typval_T *argvars, typval_T *rettv);
static void f_setbufvar(typval_T *argvars, typval_T *rettv);
static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
static void f_setcmdpos(typval_T *argvars, typval_T *rettv);
@@ -764,6 +765,7 @@ static struct fst
{"searchpos", 1, 4, f_searchpos},
{"server2client", 2, 2, f_server2client},
{"serverlist", 0, 0, f_serverlist},
{"setbufline", 3, 3, f_setbufline},
{"setbufvar", 3, 3, f_setbufvar},
{"setcharsearch", 1, 1, f_setcharsearch},
{"setcmdpos", 1, 1, f_setcmdpos},
@@ -9867,6 +9869,115 @@ f_serverlist(typval_T *argvars UNUSED, typval_T *rettv)
rettv->vval.v_string = r;
}
/*
* Set line or list of lines in buffer "buf".
*/
static void
set_buffer_lines(buf_T *buf, linenr_T lnum, typval_T *lines, typval_T *rettv)
{
char_u *line = NULL;
list_T *l = NULL;
listitem_T *li = NULL;
long added = 0;
linenr_T lcount;
buf_T *curbuf_save;
int is_curbuf = buf == curbuf;
if (buf == NULL || buf->b_ml.ml_mfp == NULL || lnum < 1)
{
rettv->vval.v_number = 1; /* FAIL */
return;
}
curbuf_save = curbuf;
curbuf = buf;
lcount = curbuf->b_ml.ml_line_count;
if (lines->v_type == VAR_LIST)
{
l = lines->vval.v_list;
li = l->lv_first;
}
else
line = get_tv_string_chk(lines);
/* default result is zero == OK */
for (;;)
{
if (l != NULL)
{
/* list argument, get next string */
if (li == NULL)
break;
line = get_tv_string_chk(&li->li_tv);
li = li->li_next;
}
rettv->vval.v_number = 1; /* FAIL */
if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
break;
/* When coming here from Insert mode, sync undo, so that this can be
* undone separately from what was previously inserted. */
if (u_sync_once == 2)
{
u_sync_once = 1; /* notify that u_sync() was called */
u_sync(TRUE);
}
if (lnum <= curbuf->b_ml.ml_line_count)
{
/* existing line, replace it */
if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
{
changed_bytes(lnum, 0);
if (is_curbuf && lnum == curwin->w_cursor.lnum)
check_cursor_col();
rettv->vval.v_number = 0; /* OK */
}
}
else if (added > 0 || u_save(lnum - 1, lnum) == OK)
{
/* lnum is one past the last line, append the line */
++added;
if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
rettv->vval.v_number = 0; /* OK */
}
if (l == NULL) /* only one string argument */
break;
++lnum;
}
if (added > 0)
appended_lines_mark(lcount, added);
curbuf = curbuf_save;
}
/*
* "setbufline()" function
*/
static void
f_setbufline(argvars, rettv)
typval_T *argvars;
typval_T *rettv;
{
linenr_T lnum;
buf_T *buf;
buf = get_buf_tv(&argvars[0], FALSE);
if (buf == NULL)
rettv->vval.v_number = 1; /* FAIL */
else
{
lnum = get_tv_lnum_buf(&argvars[1], buf);
set_buffer_lines(buf, lnum, &argvars[2], rettv);
}
}
/*
* "setbufvar()" function
*/
@@ -10021,72 +10132,9 @@ f_setfperm(typval_T *argvars, typval_T *rettv)
static void
f_setline(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
char_u *line = NULL;
list_T *l = NULL;
listitem_T *li = NULL;
long added = 0;
linenr_T lcount = curbuf->b_ml.ml_line_count;
linenr_T lnum = get_tv_lnum(&argvars[0]);
lnum = get_tv_lnum(&argvars[0]);
if (argvars[1].v_type == VAR_LIST)
{
l = argvars[1].vval.v_list;
li = l->lv_first;
}
else
line = get_tv_string_chk(&argvars[1]);
/* default result is zero == OK */
for (;;)
{
if (l != NULL)
{
/* list argument, get next string */
if (li == NULL)
break;
line = get_tv_string_chk(&li->li_tv);
li = li->li_next;
}
rettv->vval.v_number = 1; /* FAIL */
if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
break;
/* When coming here from Insert mode, sync undo, so that this can be
* undone separately from what was previously inserted. */
if (u_sync_once == 2)
{
u_sync_once = 1; /* notify that u_sync() was called */
u_sync(TRUE);
}
if (lnum <= curbuf->b_ml.ml_line_count)
{
/* existing line, replace it */
if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
{
changed_bytes(lnum, 0);
if (lnum == curwin->w_cursor.lnum)
check_cursor_col();
rettv->vval.v_number = 0; /* OK */
}
}
else if (added > 0 || u_save(lnum - 1, lnum) == OK)
{
/* lnum is one past the last line, append the line */
++added;
if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
rettv->vval.v_number = 0; /* OK */
}
if (l == NULL) /* only one string argument */
break;
++lnum;
}
if (added > 0)
appended_lines_mark(lcount, added);
set_buffer_lines(curbuf, lnum, &argvars[1], rettv);
}
static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *what_arg, typval_T *rettv);
@@ -11843,6 +11891,10 @@ f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
case 's':
if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */
p = highlight_color(id, what, modec);
/* strikeout */
else if (TOLOWER_ASC(what[1]) == 't' &&
TOLOWER_ASC(what[2]) == 'r')
p = highlight_has_attr(id, HL_STRIKETHROUGH, modec);
else /* standout */
p = highlight_has_attr(id, HL_STANDOUT, modec);
break;

View File

@@ -2396,6 +2396,7 @@ gui_outstr_nowrap(
/* Do we underline the text? */
if (hl_mask_todo & HL_UNDERLINE)
draw_flags |= DRAW_UNDERL;
#else
/* Do we underline the text? */
if ((hl_mask_todo & HL_UNDERLINE) || (hl_mask_todo & HL_ITALIC))
@@ -2405,6 +2406,10 @@ gui_outstr_nowrap(
if (hl_mask_todo & HL_UNDERCURL)
draw_flags |= DRAW_UNDERC;
/* Do we strikethrough the text? */
if (hl_mask_todo & HL_STRIKETHROUGH)
draw_flags |= DRAW_STRIKE;
/* Do we draw transparently? */
if (flags & GUI_MON_TRS_CURSOR)
draw_flags |= DRAW_TRANSP;

View File

@@ -142,6 +142,7 @@
# define DRAW_ITALIC 0x10 /* draw italic text */
#endif
#define DRAW_CURSOR 0x20 /* drawing block cursor (win32) */
#define DRAW_STRIKE 0x40 /* strikethrough */
/* For our own tearoff menu item */
#define TEAR_STRING "-->Detach"

View File

@@ -5908,6 +5908,27 @@ draw_under(int flags, int row, int col, int cells)
#endif
}
/* Draw a strikethrough line */
if (flags & DRAW_STRIKE)
{
#if GTK_CHECK_VERSION(3,0,0)
cairo_set_line_width(cr, 1.0);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
cairo_set_source_rgba(cr,
gui.spcolor->red, gui.spcolor->green, gui.spcolor->blue,
gui.spcolor->alpha);
cairo_move_to(cr, FILL_X(col), y + 1 - gui.char_height/2 + 0.5);
cairo_line_to(cr, FILL_X(col + cells), y + 1 - gui.char_height/2 + 0.5);
cairo_stroke(cr);
#else
gdk_gc_set_foreground(gui.text_gc, gui.spcolor);
gdk_draw_line(gui.drawarea->window, gui.text_gc,
FILL_X(col), y + 1 - gui.char_height/2,
FILL_X(col + cells), y + 1 - gui.char_height/2);
gdk_gc_set_foreground(gui.text_gc, gui.fgcolor);
#endif
}
/* Underline: draw a line at the bottom of the character cell. */
if (flags & DRAW_UNDERL)
{
@@ -5916,16 +5937,14 @@ draw_under(int flags, int row, int col, int cells)
if (p_linespace > 1)
y -= p_linespace - 1;
#if GTK_CHECK_VERSION(3,0,0)
{
cairo_set_line_width(cr, 1.0);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
cairo_set_source_rgba(cr,
gui.fgcolor->red, gui.fgcolor->green, gui.fgcolor->blue,
gui.fgcolor->alpha);
cairo_move_to(cr, FILL_X(col), y + 0.5);
cairo_line_to(cr, FILL_X(col + cells), y + 0.5);
cairo_stroke(cr);
}
cairo_set_line_width(cr, 1.0);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
cairo_set_source_rgba(cr,
gui.fgcolor->red, gui.fgcolor->green, gui.fgcolor->blue,
gui.fgcolor->alpha);
cairo_move_to(cr, FILL_X(col), y + 0.5);
cairo_line_to(cr, FILL_X(col + cells), y + 0.5);
cairo_stroke(cr);
#else
gdk_draw_line(gui.drawarea->window, gui.text_gc,
FILL_X(col), y,

View File

@@ -3899,6 +3899,11 @@ draw_string_QD(int row, int col, char_u *s, int len, int flags)
MoveTo(FILL_X(col), FILL_Y(row + 1) - 1);
LineTo(FILL_X(col + len) - 1, FILL_Y(row + 1) - 1);
}
if (flags & DRAW_STRIKE)
{
MoveTo(FILL_X(col), FILL_Y(row + 1) - gui.char_height/2);
LineTo(FILL_X(col + len) - 1, FILL_Y(row + 1) - gui.char_height/2);
}
}
if (flags & DRAW_UNDERC)

View File

@@ -6427,6 +6427,18 @@ gui_mch_draw_string(
DeleteObject(SelectObject(s_hdc, old_pen));
}
/* Strikethrough */
if (flags & DRAW_STRIKE)
{
hpen = CreatePen(PS_SOLID, 1, gui.currSpColor);
old_pen = SelectObject(s_hdc, hpen);
y = FILL_Y(row + 1) - gui.char_height/2;
MoveToEx(s_hdc, FILL_X(col), y, NULL);
/* Note: LineTo() excludes the last pixel in the line. */
LineTo(s_hdc, FILL_X(col + len), y);
DeleteObject(SelectObject(s_hdc, old_pen));
}
/* Undercurl */
if (flags & DRAW_UNDERC)
{

View File

@@ -2542,6 +2542,16 @@ gui_mch_draw_string(
y, FILL_X(col + cells) - 1, y);
}
if (flags & DRAW_STRIKE)
{
int y = FILL_Y(row + 1) - gui.char_height/2;
XSetForeground(gui.dpy, gui.text_gc, prev_sp_color);
XDrawLine(gui.dpy, gui.wid, gui.text_gc, FILL_X(col),
y, FILL_X(col + cells) - 1, y);
XSetForeground(gui.dpy, gui.text_gc, prev_fg_color);
}
#ifdef FEAT_XFONTSET
if (current_fontset != NULL)
XSetClipMask(gui.dpy, gui.text_gc, None);

View File

@@ -1589,8 +1589,7 @@ open_line(
&& curbuf->b_p_ai)
{
fixthisline(get_lisp_indent);
p = ml_get_curline();
ai_col = (colnr_T)(skipwhite(p) - p);
ai_col = (colnr_T)getwhitecols_curline();
}
#endif
#ifdef FEAT_CINDENT
@@ -1608,8 +1607,7 @@ open_line(
: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum)))
{
do_c_expr_indent();
p = ml_get_curline();
ai_col = (colnr_T)(skipwhite(p) - p);
ai_col = (colnr_T)getwhitecols_curline();
}
#endif
#if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT))

View File

@@ -2507,6 +2507,7 @@ op_insert(oparg_T *oap, long count1)
{
long ins_len, pre_textlen = 0;
char_u *firstline, *ins_text;
colnr_T ind_pre = 0, ind_post;
struct block_def bd;
int i;
pos_T t1;
@@ -2541,7 +2542,10 @@ op_insert(oparg_T *oap, long count1)
#endif
/* Get the info about the block before entering the text */
block_prep(oap, &bd, oap->start.lnum, TRUE);
/* Get indent information */
ind_pre = (colnr_T)getwhitecols_curline();
firstline = ml_get(oap->start.lnum) + bd.textcol;
if (oap->op_type == OP_APPEND)
firstline += bd.textlen;
pre_textlen = (long)STRLEN(firstline);
@@ -2603,6 +2607,15 @@ op_insert(oparg_T *oap, long count1)
{
struct block_def bd2;
/* If indent kicked in, the firstline might have changed
* but only do that, if the indent actually increased. */
ind_post = (colnr_T)getwhitecols_curline();
if (curbuf->b_op_start.col > ind_pre && ind_post > ind_pre)
{
bd.textcol += ind_post - ind_pre;
bd.start_vcol += ind_post - ind_pre;
}
/* The user may have moved the cursor before inserting something, try
* to adjust the block for that. */
if (oap->start.lnum == curbuf->b_op_start_orig.lnum && !bd.is_MAX)
@@ -2754,7 +2767,7 @@ op_change(oparg_T *oap)
# endif
firstline = ml_get(oap->start.lnum);
pre_textlen = (long)STRLEN(firstline);
pre_indent = (long)(skipwhite(firstline) - firstline);
pre_indent = (long)getwhitecols(firstline);
bd.textcol = curwin->w_cursor.col;
}
#endif
@@ -2779,7 +2792,7 @@ op_change(oparg_T *oap)
firstline = ml_get(oap->start.lnum);
if (bd.textcol > (colnr_T)pre_indent)
{
long new_indent = (long)(skipwhite(firstline) - firstline);
long new_indent = (long)getwhitecols(firstline);
pre_textlen += new_indent - pre_indent;
bd.textcol += new_indent - pre_indent;
@@ -5065,8 +5078,7 @@ format_lines(
#endif
if (second_indent > 0) /* the "leader" for FO_Q_SECOND */
{
char_u *p = ml_get_curline();
int indent = (int)(skipwhite(p) - p);
int indent = getwhitecols_curline();
if (indent > 0)
{

View File

@@ -3216,8 +3216,10 @@ static struct vimoption options[] =
p_term("t_so", T_SO)
p_term("t_SR", T_CSR)
p_term("t_sr", T_SR)
p_term("t_Te", T_STE)
p_term("t_te", T_TE)
p_term("t_ti", T_TI)
p_term("t_Ts", T_STS)
p_term("t_ts", T_TS)
p_term("t_u7", T_U7)
p_term("t_ue", T_UE)

View File

@@ -35,6 +35,8 @@ colnr_T getvcol_nolist(pos_T *posp);
void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end);
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right);
char_u *skipwhite(char_u *q);
int getwhitecols_curline(void);
int getwhitecols(char_u *p);
char_u *skipdigits(char_u *q);
char_u *skipbin(char_u *q);
char_u *skiphex(char_u *q);

View File

@@ -1,4 +1,5 @@
/* misc1.c */
int get_whitespace_line_start(linenr_T lnum);
int get_indent(void);
int get_indent_lnum(linenr_T lnum);
int get_indent_buf(buf_T *buf, linenr_T lnum);

View File

@@ -4643,16 +4643,29 @@ enum {
* Parse text from 'di' and return the quickfix list items
*/
static int
qf_get_list_from_lines(dictitem_T *di, dict_T *retdict)
qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
{
int status = FAIL;
qf_info_T *qi;
char_u *errorformat = p_efm;
dictitem_T *efm_di;
list_T *l;
/* Only a List value is supported */
if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL)
{
list_T *l = list_alloc();
/* If errorformat is supplied then use it, otherwise use the 'efm'
* option setting
*/
if ((efm_di = dict_find(what, (char_u *)"efm", -1)) != NULL)
{
if (efm_di->di_tv.v_type != VAR_STRING ||
efm_di->di_tv.vval.v_string == NULL)
return FAIL;
errorformat = efm_di->di_tv.vval.v_string;
}
l = list_alloc();
if (l == NULL)
return FAIL;
@@ -4662,7 +4675,7 @@ qf_get_list_from_lines(dictitem_T *di, dict_T *retdict)
vim_memset(qi, 0, (size_t)(sizeof(qf_info_T)));
qi->qf_refcount++;
if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, p_efm,
if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
TRUE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0)
{
(void)get_errorlist(qi, NULL, 0, l);
@@ -4692,7 +4705,7 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
int flags = QF_GETLIST_NONE;
if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
return qf_get_list_from_lines(di, retdict);
return qf_get_list_from_lines(what, di, retdict);
if (wp != NULL)
qi = GET_LOC_LIST(wp);
@@ -4962,6 +4975,7 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
int retval = FAIL;
int qf_idx;
int newlist = FALSE;
char_u *errorformat = p_efm;
if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
newlist = TRUE;
@@ -5039,6 +5053,7 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
retval = OK;
}
}
if ((di = dict_find(what, (char_u *)"items", -1)) != NULL)
{
if (di->di_tv.v_type == VAR_LIST)
@@ -5051,6 +5066,13 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
}
}
if ((di = dict_find(what, (char_u *)"efm", -1)) != NULL)
{
if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL)
return FAIL;
errorformat = di->di_tv.vval.v_string;
}
if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
{
/* Only a List value is supported */
@@ -5058,7 +5080,7 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
{
if (action == 'r')
qf_free_items(qi, qf_idx);
if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, p_efm,
if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat,
FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0)
retval = OK;
}

View File

@@ -235,7 +235,7 @@ redraw_later_clear(void)
else
#endif
/* Use attributes that is very unlikely to appear in text. */
screen_attr = HL_BOLD | HL_UNDERLINE | HL_INVERSE;
screen_attr = HL_BOLD | HL_UNDERLINE | HL_INVERSE | HL_STRIKETHROUGH;
}
/*
@@ -3463,7 +3463,7 @@ win_line(
{
/* For checking first word with a capital skip white space. */
if (cap_col == 0)
cap_col = (int)(skipwhite(line) - line);
cap_col = getwhitecols(line);
/* To be able to spell-check over line boundaries copy the end of the
* current line into nextline[]. Above the start of the next line was
@@ -8086,6 +8086,8 @@ screen_start_highlight(int attr)
out_str(T_CZH);
if ((attr & HL_INVERSE) && T_MR != NULL) /* inverse (reverse) */
out_str(T_MR);
if ((attr & HL_STRIKETHROUGH) && T_STS != NULL) /* strike */
out_str(T_STS);
/*
* Output the color or start string after bold etc., in case the
@@ -8210,6 +8212,13 @@ screen_stop_highlight(void)
else
out_str(T_CZR);
}
if (screen_attr & HL_STRIKETHROUGH)
{
if (STRCMP(T_STE, T_ME) == 0)
do_ME = TRUE;
else
out_str(T_STE);
}
if (do_ME || (screen_attr & (HL_BOLD | HL_INVERSE)))
out_str(T_ME);

View File

@@ -1625,11 +1625,11 @@ spell_move_to(
/* For checking first word with a capital skip white space. */
if (capcol == 0)
capcol = (int)(skipwhite(line) - line);
capcol = getwhitecols(line);
else if (curline && wp == curwin)
{
/* For spellbadword(): check if first word needs a capital. */
col = (int)(skipwhite(line) - line);
col = getwhitecols(line);
if (check_need_cap(lnum, col))
capcol = col;
@@ -3593,7 +3593,7 @@ check_need_cap(linenr_T lnum, colnr_T col)
line = ml_get_curline();
endcol = 0;
if ((int)(skipwhite(line) - line) >= (int)col)
if (getwhitecols(line) >= (int)col)
{
/* At start of line, check if previous line is empty or sentence
* ends there. */

View File

@@ -86,9 +86,9 @@ static int include_link = 0; /* when 2 include "link" and "clear" */
*/
static char *(hl_name_table[]) =
{"bold", "standout", "underline", "undercurl",
"italic", "reverse", "inverse", "nocombine", "NONE"};
"italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"};
static int hl_attr_table[] =
{HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, 0};
{HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0};
#define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? attr_b : (attr_a)) | (attr_b))
static int get_attr_entry(garray_T *table, attrentry_T *aep);
@@ -9951,6 +9951,8 @@ highlight_changed(void)
break;
case 'c': attr |= HL_UNDERCURL;
break;
case 't': attr |= HL_STRIKETHROUGH;
break;
case ':': ++p; /* highlight group name */
if (attr || *p == NUL) /* no combinations */
return FAIL;

View File

@@ -217,6 +217,8 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_US, IF_EB("\033|8h", ESC_STR "|8h")}, /* HL_UNDERLINE */
{(int)KS_UCE, IF_EB("\033|8C", ESC_STR "|8C")}, /* HL_UNDERCURL */
{(int)KS_UCS, IF_EB("\033|8c", ESC_STR "|8c")}, /* HL_UNDERCURL */
{(int)KS_STE, IF_EB("\033|4C", ESC_STR "|4C")}, /* HL_STRIKETHROUGH */
{(int)KS_STS, IF_EB("\033|4c", ESC_STR "|4c")}, /* HL_STRIKETHROUGH */
{(int)KS_CZR, IF_EB("\033|4H", ESC_STR "|4H")}, /* HL_ITALIC */
{(int)KS_CZH, IF_EB("\033|4h", ESC_STR "|4h")}, /* HL_ITALIC */
{(int)KS_VB, IF_EB("\033|f", ESC_STR "|f")},
@@ -831,6 +833,8 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_MD, IF_EB("\033[1m", ESC_STR "[1m")},
{(int)KS_UE, IF_EB("\033[m", ESC_STR "[m")},
{(int)KS_US, IF_EB("\033[4m", ESC_STR "[4m")},
{(int)KS_STE, IF_EB("\033[29m", ESC_STR "[29m")},
{(int)KS_STS, IF_EB("\033[9m", ESC_STR "[9m")},
{(int)KS_MS, "y"},
{(int)KS_UT, "y"},
{(int)KS_LE, "\b"},
@@ -1151,6 +1155,8 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_US, "[US]"},
{(int)KS_UCE, "[UCE]"},
{(int)KS_UCS, "[UCS]"},
{(int)KS_STE, "[STE]"},
{(int)KS_STS, "[STS]"},
{(int)KS_MS, "[MS]"},
{(int)KS_UT, "[UT]"},
{(int)KS_XN, "[XN]"},
@@ -1595,6 +1601,7 @@ set_termname(char_u *term)
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
{KS_STE,"Te"}, {KS_STS,"Ts"},
{KS_CM, "cm"}, {KS_SR, "sr"},
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},

View File

@@ -55,6 +55,8 @@ enum SpecialKey
KS_US, /* underscore (underline) mode */
KS_UCE, /* exit undercurl mode */
KS_UCS, /* undercurl mode */
KS_STE, /* exit strikethrough mode */
KS_STS, /* strikethrough mode */
KS_MS, /* save to move cur in reverse mode */
KS_CM, /* cursor motion */
KS_SR, /* scroll reverse (backward) */
@@ -149,6 +151,8 @@ extern char_u *(term_strings[]); /* current terminal strings */
#define T_US (TERM_STR(KS_US)) /* underscore (underline) mode */
#define T_UCE (TERM_STR(KS_UCE)) /* exit undercurl mode */
#define T_UCS (TERM_STR(KS_UCS)) /* undercurl mode */
#define T_STE (TERM_STR(KS_STE)) /* exit strikethrough mode */
#define T_STS (TERM_STR(KS_STS)) /* strikethrough mode */
#define T_MS (TERM_STR(KS_MS)) /* save to move cur in reverse mode */
#define T_CM (TERM_STR(KS_CM)) /* cursor motion */
#define T_SR (TERM_STR(KS_SR)) /* scroll reverse (backward) */

View File

@@ -1735,7 +1735,7 @@ cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
if (cellattrs.italic)
attr |= HL_ITALIC;
if (cellattrs.strike)
attr |= HL_STANDOUT;
attr |= HL_STRIKETHROUGH;
if (cellattrs.reverse)
attr |= HL_INVERSE;
@@ -2451,7 +2451,7 @@ f_term_getattr(typval_T *argvars, typval_T *rettv)
{"bold", HL_BOLD},
{"italic", HL_ITALIC},
{"underline", HL_UNDERLINE},
{"strike", HL_STANDOUT},
{"strike", HL_STRIKETHROUGH},
{"reverse", HL_INVERSE},
};

View File

@@ -3,6 +3,7 @@
set belloff=all
source test_assign.vim
source test_bufline.vim
source test_cd.vim
source test_changedtick.vim
source test_cursor_func.vim

View File

@@ -0,0 +1,26 @@
" Tests for setbufline() and getbufline()
func Test_setbufline_getbufline()
new
let b = bufnr('%')
hide
call assert_equal(0, setbufline(b, 1, ['foo', 'bar']))
call assert_equal(['foo'], getbufline(b, 1))
call assert_equal(['bar'], getbufline(b, 2))
call assert_equal(['foo', 'bar'], getbufline(b, 1, 2))
exe "bd!" b
call assert_equal([], getbufline(b, 1, 2))
split Xtest
call setline(1, ['a', 'b', 'c'])
let b = bufnr('%')
wincmd w
call assert_equal(1, setbufline(b, 5, ['x']))
call assert_equal(1, setbufline(1234, 1, ['x']))
call assert_equal(0, setbufline(b, 4, ['d', 'e']))
call assert_equal(['c'], getbufline(b, 3))
call assert_equal(['d'], getbufline(b, 4))
call assert_equal(['e'], getbufline(b, 5))
call assert_equal([], getbufline(b, 6))
exe "bwipe! " . b
endfunc

View File

@@ -71,7 +71,7 @@ func Test_cino_extern_c()
bwipe!
endfunc
func! Test_cindent_rawstring()
func Test_cindent_rawstring()
new
setl cindent
call feedkeys("i" .
@@ -81,5 +81,25 @@ func! Test_cindent_rawstring()
\ "statement;\<Esc>", "x")
call assert_equal("\tstatement;", getline(line('.')))
bw!
endfunction
endfunc
func Test_cindent_expr()
new
func! MyIndentFunction()
return v:lnum == 1 ? shiftwidth() : 0
endfunc
setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction()
call setline(1, ['var_a = something()', 'b = something()'])
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
call assert_equal([' var_a = something();', 'b = something();'], getline(1, '$'))
%d
call setline(1, [' var_a = something()', ' b = something()'])
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$'))
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -280,13 +280,13 @@ func Test_diffopt_icase()
set diffopt=icase,foldcolumn:0
e one
call setline(1, ['One', 'Two', 'Three', 'Four'])
call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve'])
redraw
let normattr = screenattr(1, 1)
diffthis
botright vert new two
call setline(1, ['one', 'TWO', 'Three ', 'Four'])
call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE'])
diffthis
redraw
@@ -295,6 +295,10 @@ func Test_diffopt_icase()
call assert_notequal(normattr, screenattr(3, 1))
call assert_equal(normattr, screenattr(4, 1))
let dtextattr = screenattr(5, 3)
call assert_notequal(dtextattr, screenattr(5, 1))
call assert_notequal(dtextattr, screenattr(5, 5))
diffoff!
%bwipe!
set diffopt&

View File

@@ -2321,6 +2321,17 @@ func Xsetexpr_tests(cchar)
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
" Adding entries using a custom efm
set efm&
call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
\ 'lines' : ["F1#10#L10", "F2#20#L20"]})
call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
\ 'lines' : ['F1:10:L10']}))
endfunc
func Test_setexpr()
@@ -2537,6 +2548,17 @@ func XgetListFromLines(cchar)
call assert_equal([], g:Xgetlist({'lines' : []}).items)
call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
" Parse text using a custom efm
set efm&
let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
call assert_equal('Line30', l[0].text)
let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
call assert_equal('File3:30:Line30', l[0].text)
let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
call assert_equal({}, l)
call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
" Make sure that the quickfix stack is not modified
call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
endfunc

View File

@@ -769,6 +769,22 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1044,
/**/
1043,
/**/
1042,
/**/
1041,
/**/
1040,
/**/
1039,
/**/
1038,
/**/
1037,
/**/
1036,
/**/

View File

@@ -435,13 +435,8 @@ typedef off_t off_T;
* The characters and attributes cached for the screen.
*/
typedef char_u schar_T;
#ifdef FEAT_SYN_HL
typedef unsigned short sattr_T;
# define MAX_TYPENR 65535
#else
typedef unsigned char sattr_T;
# define MAX_TYPENR 255
#endif
#define MAX_TYPENR 65535
/*
* The u8char_T can hold one decoded UTF-8 character.
@@ -681,7 +676,8 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
#define HL_UNDERCURL 0x10
#define HL_STANDOUT 0x20
#define HL_NOCOMBINE 0x40
#define HL_ALL 0x7f
#define HL_STRIKETHROUGH 0x80
#define HL_ALL 0xff
/* special attribute addition: Put message in history */
#define MSG_HIST 0x1000