Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2017-09-03 20:58:39 -07:00
51 changed files with 953 additions and 318 deletions
+59 -18
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}
@@ -2407,6 +2410,7 @@ term_wait({buf} [, {time}]) Number wait for screen to be updated
test_alloc_fail({id}, {countdown}, {repeat})
none make memory allocation fail
test_autochdir() none enable 'autochdir' during startup
test_feedinput() none add key sequence to input buffer
test_garbagecollect_now() none free memory right now for testing
test_ignore_error({expr}) none ignore a specific error
test_null_channel() Channel null value for testing
@@ -4632,18 +4636,20 @@ 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
text use 'errorformat' to extract items from the
text and return the resulting entries. The
value can be a string with one line or a list
with multiple lines. The current quickfix list
is not modified.
title get the list title
winid get the |window-ID| (if opened)
all all of the above quickfix properties
@@ -4671,6 +4677,7 @@ getqflist([{what}]) *getqflist()*
Examples: >
:echo getqflist({'all': 1})
:echo getqflist({'nr': 2, 'title': 1})
:echo getqflist({'lines' : ["F1:10:L10"]})
<
getreg([{regname} [, 1 [, {list}]]]) *getreg()*
@@ -6858,6 +6865,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 +6946,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,22 +7090,24 @@ 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
text use 'errorformat' to extract items from the
text and add the resulting entries to the
quickfix list {nr}. The value can be a string
with one line or a list with multiple lines.
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.
lines use 'errorformat' to parse a list of lines and
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.
@@ -7087,12 +7115,13 @@ 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: >
:call setqflist([], 'r', {'title': 'My search'})
:call setqflist([], 'r', {'nr': 2, 'title': 'Errors'})
:call setqflist([], 'r', {'title': 'My search'})
:call setqflist([], 'r', {'nr': 2, 'title': 'Errors'})
:call setqflist([], 'a', {'id':myid, 'lines':["F1:10:L10"]})
<
Returns zero for success, -1 for failure.
@@ -7723,6 +7752,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): >
@@ -8141,6 +8171,12 @@ term_start({cmd}, {options}) *term_start()*
have "%d" where the buffer number goes,
e.g. "10split|buffer %d"; when not
specified "botright sbuf %d" is used
"eof_chars" Text to send after all buffer lines were
written to the terminal. When not set
CTRL-D is used. For Python use CTRL-Z or
"exit()". For a shell use "exit". A CR
is always added.
{only on MS-Windows}
{only available when compiled with the |+terminal| feature}
@@ -8161,6 +8197,11 @@ test_autochdir() *test_autochdir()*
Set a flag to enable the effect of 'autochdir' before Vim
startup has finished.
test_feedinput({string}) *test_feedinput()*
Characters in {string} are queued for processing as if they
were typed by the user. This uses a low level input buffer.
This function works only when with |+unix| or GUI is running.
test_garbagecollect_now() *test_garbagecollect_now()*
Like garbagecollect(), but executed right away. This must
only be called directly to avoid any structure to exist
+1
View File
@@ -4228,6 +4228,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
+6 -4
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
+15 -5
View File
@@ -133,6 +133,14 @@ Syntax ~
height.
++cols={width} Use {width} for the terminal window
width.
++eof={text} when using [range], text to send after
the last line was written. The default
is to send CTRL-D. A CR is appended.
E.g. for a shell use "++eof=exit" and
for Python "++eof=exit()". Special
codes can be used like with `:map`,
e.g. "<C-Z>" for CTRL-Z.
{only on MS-Windows}
If you want to use more options use the |term_start()|
function.
@@ -141,11 +149,13 @@ When the buffer associated with the terminal is unloaded or wiped out the job
is killed, similar to calling `job_stop(job, "kill")`
So long as the job is running the window behaves like it contains a modified
buffer. Trying to close the window with `CTRL-W :close` or `CTRL-W :hide`
fails, unless "!" is added, in which case the job is ended. The text in the
window is lost. The buffer still exists, but getting it in a window with
`:buffer` will show an
empty buffer.
buffer. Trying to close the window with `CTRL-W :quit` fails. When using
`CTRL-W :quit!` the job is ended. The text in the window is lost. The buffer
still exists, but getting it in a window with `:buffer` will show an empty
buffer.
Trying to close the window with `CTRL-W :close` also fails. Using
`CTRL-W :close!` will close the window and make the buffer hidden.
You can use `CTRL-W :hide` to close the terminal window and make the buffer
hidden, the job keeps running. The `:buffer` command can be used to turn the
+3 -2
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
+10
View File
@@ -76,6 +76,10 @@ endif
# Set to yes to enable terminal support.
TERMINAL=no
ifndef CTAGS
# this assumes ctags is Exuberant ctags
CTAGS = ctags -I INIT+ --fields=+S
endif
# Link against the shared version of libstdc++ by default. Set
# STATIC_STDCPLUS to "yes" to link against static version instead.
@@ -885,6 +889,12 @@ xxd/xxd.exe: xxd/xxd.c
GvimExt/gvimext.dll: GvimExt/gvimext.cpp GvimExt/gvimext.rc GvimExt/gvimext.h
$(MAKE) -C GvimExt -f Make_ming.mak CROSS=$(CROSS) CROSS_COMPILE=$(CROSS_COMPILE) CXX='$(CXX)' STATIC_STDCPLUS=$(STATIC_STDCPLUS)
tags: notags
$(CTAGS) *.c *.cpp *.h if_perl.xs
notags:
-$(DEL) tags
clean:
-$(DEL) $(OUTDIR)$(DIRSLASH)*.o
-$(DEL) $(OUTDIR)$(DIRSLASH)*.res
+3 -2
View File
@@ -344,7 +344,8 @@ FEATURES = HUGE
!endif
!ifndef CTAGS
CTAGS = ctags
# this assumes ctags is Exuberant ctags
CTAGS = ctags -I INIT+ --fields=+S
!endif
!ifndef CSCOPE
@@ -1220,7 +1221,7 @@ GvimExt/gvimext.dll: GvimExt/gvimext.cpp GvimExt/gvimext.rc GvimExt/gvimext.h
tags: notags
$(CTAGS) *.c *.cpp *.h if_perl.xs proto\*.pro
$(CTAGS) *.c *.cpp *.h if_perl.xs
notags:
- if exist tags del tags
+1
View File
@@ -2139,6 +2139,7 @@ test_arglist \
test_autocmd \
test_backspace_opt \
test_breakindent \
test_bufline \
test_bufwintabinfo \
test_cd \
test_cdo \
+17 -3
View File
@@ -7557,20 +7557,34 @@ $as_echo_n "checking --enable-terminal argument... " >&6; }
# Check whether --enable-terminal was given.
if test "${enable_terminal+set}" = set; then :
enableval=$enable_terminal; enable_terminal="yes"
else
enable_terminal="auto"
fi
if test "$enable_terminal" = "yes"; then
if test "$enable_terminal" = "yes" || test "$enable_terminal" = "auto" -a "x$features" = "xhuge" ; then
if test "x$features" = "xtiny" -o "x$features" = "xsmall"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot use terminal emulator with tiny or small features" >&5
$as_echo "cannot use terminal emulator with tiny or small features" >&6; }
enable_terminal="no"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
if test "$enable_terminal" = "auto"; then
enable_terminal="yes"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defaulting to yes" >&5
$as_echo "defaulting to yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
if test "$enable_terminal" = "auto"; then
enable_terminal="no"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: defaulting to no" >&5
$as_echo "defaulting to no" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test "$enable_terminal" = "yes"; then
$as_echo "#define FEAT_TERMINAL 1" >>confdefs.h
+29 -4
View File
@@ -1321,11 +1321,16 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
return;
memcpy((char *)p, (char *)line, len);
for (i = 0; i < len; ++i)
if (p[i] == NL)
p[i] = NUL;
if (channel->ch_write_text_mode)
p[len] = CAR;
else
{
for (i = 0; i < len; ++i)
if (p[i] == NL)
p[i] = NUL;
p[len] = NL;
p[len] = NL;
}
p[len + 1] = NUL;
channel_send(channel, PART_IN, p, len + 1, "write_buf_line");
vim_free(p);
@@ -1438,6 +1443,12 @@ channel_write_in(channel_T *channel)
in_part->ch_buf_top = lnum;
if (lnum > buf->b_ml.ml_line_count || lnum > in_part->ch_buf_bot)
{
#if defined(FEAT_TERMINAL)
/* Send CTRL-D or "eof_chars" to close stdin on MS-Windows. */
if (channel->ch_job != NULL)
term_send_eof(channel);
#endif
/* Writing is done, no longer need the buffer. */
in_part->ch_bufref.br_buf = NULL;
ch_log(channel, "Finished writing all lines to channel");
@@ -4651,6 +4662,20 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "eof_chars") == 0)
{
char_u *p;
if (!(supported2 & JO2_EOF_CHARS))
break;
opt->jo_set2 |= JO2_EOF_CHARS;
p = opt->jo_eof_chars = get_tv_string_chk(item);
if (p == NULL)
{
EMSG2(_(e_invarg2), "term_opencmd");
return FAIL;
}
}
else if (STRCMP(hi->hi_key, "term_rows") == 0)
{
if (!(supported2 & JO2_TERM_ROWS))
+16
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
*/
+14 -4
View File
@@ -2095,16 +2095,26 @@ fi
AC_MSG_CHECKING(--enable-terminal argument)
AC_ARG_ENABLE(terminal,
[ --enable-terminal Enable terminal emulation support.],
[enable_terminal="yes"], )
if test "$enable_terminal" = "yes"; then
[enable_terminal="yes"], [enable_terminal="auto"])
if test "$enable_terminal" = "yes" || test "$enable_terminal" = "auto" -a "x$features" = "xhuge" ; then
if test "x$features" = "xtiny" -o "x$features" = "xsmall"; then
AC_MSG_RESULT([cannot use terminal emulator with tiny or small features])
enable_terminal="no"
else
AC_MSG_RESULT(yes)
if test "$enable_terminal" = "auto"; then
enable_terminal="yes"
AC_MSG_RESULT(defaulting to yes)
else
AC_MSG_RESULT(yes)
fi
fi
else
AC_MSG_RESULT(no)
if test "$enable_terminal" = "auto"; then
enable_terminal="no"
AC_MSG_RESULT(defaulting to no)
else
AC_MSG_RESULT(no)
fi
fi
if test "$enable_terminal" = "yes"; then
AC_DEFINE(FEAT_TERMINAL)
+54 -29
View File
@@ -1660,6 +1660,40 @@ diff_equal_entry(diff_T *dp, int idx1, int idx2)
return TRUE;
}
/*
* 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;
}
/*
* Compare strings "s1" and "s2" according to 'diffopt'.
* Return non-zero when they are different.
@@ -1689,30 +1723,10 @@ diff_cmp(char_u *s1, char_u *s2)
}
else
{
#ifdef FEAT_MBYTE
l = (*mb_ptr2len)(p1);
if (l != (*mb_ptr2len)(p2))
if (!diff_equal_char(p1, p2, &l))
break;
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))))
break;
p1 += l;
p2 += l;
}
else
#endif
{
if (*p1 != *p2 && (!(diff_flags & DIFF_ICASE)
|| TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2)))
break;
++p1;
++p2;
}
p1 += l;
p2 += l;
}
}
@@ -1969,6 +1983,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 +2035,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 +2075,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)
+3 -4
View File
@@ -5196,7 +5196,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 */
@@ -5362,7 +5362,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;
@@ -8222,8 +8222,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;
}
+136 -65
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);
@@ -392,6 +393,7 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv);
static void f_tempname(typval_T *argvars, typval_T *rettv);
static void f_test_alloc_fail(typval_T *argvars, typval_T *rettv);
static void f_test_autochdir(typval_T *argvars, typval_T *rettv);
static void f_test_feedinput(typval_T *argvars, typval_T *rettv);
static void f_test_override(typval_T *argvars, typval_T *rettv);
static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
static void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
@@ -764,6 +766,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},
@@ -849,6 +852,7 @@ static struct fst
#endif
{"test_alloc_fail", 3, 3, f_test_alloc_fail},
{"test_autochdir", 0, 0, f_test_autochdir},
{"test_feedinput", 1, 1, f_test_feedinput},
{"test_garbagecollect_now", 0, 0, f_test_garbagecollect_now},
{"test_ignore_error", 1, 1, f_test_ignore_error},
#ifdef FEAT_JOB_CHANNEL
@@ -9894,6 +9898,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
*/
@@ -10048,72 +10161,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);
@@ -11870,6 +11920,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;
@@ -12492,6 +12546,23 @@ f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
#endif
}
/*
* "test_feedinput()"
*/
static void
f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
{
#ifdef USE_INPUT_BUF
char_u *val = get_tv_string_chk(&argvars[0]);
if (val != NULL)
{
trash_input_buf();
add_to_input_buf_csi(val, (int)STRLEN(val));
}
#endif
}
/*
* "test_disable({name}, {val})" function
*/
+6 -1
View File
@@ -2098,11 +2098,16 @@ viminfo_filename(char_u *file)
else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL)
{
#ifdef VIMINFO_FILE2
/* don't use $HOME when not defined (turned into "c:/"!). */
# ifdef VMS
if (mch_getenv((char_u *)"SYS$LOGIN") == NULL)
# else
# ifdef MSWIN
/* Use $VIM only if $HOME is the default "C:/". */
if (STRCMP(vim_getenv((char_u *)"HOME", NULL), "C:/") == 0
&& mch_getenv((char_u *)"HOME") == NULL)
# else
if (mch_getenv((char_u *)"HOME") == NULL)
# endif
# endif
{
/* don't use $VIM when not available. */
+5
View File
@@ -2413,6 +2413,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))
@@ -2422,6 +2423,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;
+3 -2
View File
@@ -143,8 +143,9 @@
# define DRAW_ITALIC 0x10 /* draw italic text */
#endif
#define DRAW_CURSOR 0x20 /* drawing block cursor (win32) */
#define DRAW_WIDE 0x40 /* drawing wide char (MacVim) */
#define DRAW_COMP 0x80 /* drawing composing char (MacVim) */
#define DRAW_STRIKE 0x40 /* strikethrough */
#define DRAW_WIDE 0x80 /* drawing wide char (MacVim) */
#define DRAW_COMP 0x100 /* drawing composing char (MacVim) */
/* For our own tearoff menu item */
#define TEAR_STRING "-->Detach"
+29 -10
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,
+5
View File
@@ -3909,6 +3909,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)
+12
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)
{
+10
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);
+1 -1
View File
@@ -993,7 +993,7 @@ static VALUE vim_message(VALUE self UNUSED, VALUE str)
if (RSTRING_LEN(str) > 0)
{
/* Only do this when the string isn't empty, alloc(0) causes trouble. */
buff = ALLOCA_N(char, RSTRING_LEN(str));
buff = ALLOCA_N(char, RSTRING_LEN(str) + 1);
strcpy(buff, RSTRING_PTR(str));
p = strchr(buff, '\n');
if (p) *p = '\0';
+14 -10
View File
@@ -2,7 +2,7 @@
* iscygpty.c -- part of ptycheck
* https://github.com/k-takata/ptycheck
*
* Copyright (c) 2015-2016 K.Takata
* Copyright (c) 2015-2017 K.Takata
*
* You can redistribute it and/or modify it under the terms of either
* the MIT license (as described below) or the Vim license.
@@ -27,6 +27,8 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifdef _WIN32
#include <ctype.h>
#include <io.h>
#include <wchar.h>
@@ -60,19 +62,19 @@
//#define USE_DYNFILEID
#ifdef USE_DYNFILEID
typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)(
HANDLE hFile,
HANDLE hFile,
FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
LPVOID lpFileInformation,
DWORD dwBufferSize
LPVOID lpFileInformation,
DWORD dwBufferSize
);
static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL;
# ifndef USE_FILEEXTD
static BOOL WINAPI stub_GetFileInformationByHandleEx(
HANDLE hFile,
HANDLE hFile,
FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
LPVOID lpFileInformation,
DWORD dwBufferSize
LPVOID lpFileInformation,
DWORD dwBufferSize
)
{
return FALSE;
@@ -111,7 +113,7 @@ int is_cygpty(int fd)
return 0;
#else
HANDLE h;
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * (MAX_PATH - 1);
FILE_NAME_INFO *nameinfo;
WCHAR *p = NULL;
@@ -125,7 +127,7 @@ int is_cygpty(int fd)
if (GetFileType(h) != FILE_TYPE_PIPE) {
return 0;
}
nameinfo = malloc(size);
nameinfo = malloc(size + sizeof(WCHAR));
if (nameinfo == NULL) {
return 0;
}
@@ -178,4 +180,6 @@ int is_cygpty_used(void)
return ret;
}
/* vi:set ts=8 sts=4 sw=4 noet: */
#endif /* _WIN32 */
/* vim: set ts=4 sw=4: */
+6 -1
View File
@@ -2,7 +2,7 @@
* iscygpty.h -- part of ptycheck
* https://github.com/k-takata/ptycheck
*
* Copyright (c) 2015-2016 K.Takata
* Copyright (c) 2015-2017 K.Takata
*
* You can redistribute it and/or modify it under the terms of either
* the MIT license (as described below) or the Vim license.
@@ -30,7 +30,12 @@
#ifndef _ISCYGPTY_H
#define _ISCYGPTY_H
#ifdef _WIN32
int is_cygpty(int fd);
int is_cygpty_used(void);
#else
#define is_cygpty(fd) 0
#define is_cygpty_used() 0
#endif
#endif /* _ISCYGPTY_H */
+2 -4
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))
+16 -4
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)
{
+2
View File
@@ -3317,8 +3317,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)
+11 -1
View File
@@ -2282,6 +2282,7 @@ vim_is_xterm(char_u *name)
|| STRNICMP(name, "kterm", 5) == 0
|| STRNICMP(name, "mlterm", 6) == 0
|| STRNICMP(name, "rxvt", 4) == 0
|| STRNICMP(name, "screen.xterm", 12) == 0
|| STRCMP(name, "builtin_xterm") == 0);
}
@@ -4099,8 +4100,17 @@ mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
++*argc;
while (*p != NUL && (inquote || (*p != ' ' && *p != TAB)))
{
if (*p == '"')
if (p[0] == '"')
inquote = !inquote;
else if (p[0] == '\\' && p[1] != NUL)
{
/* First pass: skip over "\ " and "\"".
* Second pass: Remove the backslash. */
if (i == 1)
mch_memmove(p, p + 1, STRLEN(p));
else
++p;
}
++p;
}
if (*p == NUL)
+2
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);
+1
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);
+1
View File
@@ -16,6 +16,7 @@ int term_update_window(win_T *wp);
int term_is_finished(buf_T *buf);
int term_show_buffer(buf_T *buf);
void term_change_in_curbuf(void);
void term_send_eof(channel_T *ch);
int term_get_attr(buf_T *buf, linenr_T lnum, int col);
char_u *term_get_status_text(term_T *term);
int set_ref_in_term(int copyID);
+40 -21
View File
@@ -4643,36 +4643,48 @@ enum {
* Parse text from 'di' and return the quickfix list items
*/
static int
qf_get_list_from_text(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 string and list values are supported */
if ((di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
|| (di->di_tv.v_type == VAR_LIST
&& di->di_tv.vval.v_list != NULL))
/* Only a List value is supported */
if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL)
{
/* 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;
qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
if (qi != NULL)
{
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)
{
list_T *l = list_alloc();
if (l != NULL)
{
(void)get_errorlist(qi, NULL, 0, l);
dict_add_list(retdict, "items", l);
status = OK;
}
(void)get_errorlist(qi, NULL, 0, l);
qf_free(qi, 0);
}
free(qi);
}
dict_add_list(retdict, "items", l);
status = OK;
}
return status;
@@ -4692,8 +4704,8 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
dictitem_T *di;
int flags = QF_GETLIST_NONE;
if ((di = dict_find(what, (char_u *)"text", -1)) != NULL)
return qf_get_list_from_text(di, retdict);
if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
return qf_get_list_from_lines(what, di, retdict);
if (wp != NULL)
qi = GET_LOC_LIST(wp);
@@ -4963,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;
@@ -5040,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)
@@ -5052,16 +5066,21 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
}
}
if ((di = dict_find(what, (char_u *)"text", -1)) != NULL)
if ((di = dict_find(what, (char_u *)"efm", -1)) != NULL)
{
/* Only string and list values are supported */
if ((di->di_tv.v_type == VAR_STRING && di->di_tv.vval.v_string != NULL)
|| (di->di_tv.v_type == VAR_LIST
&& di->di_tv.vval.v_list != 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 */
if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL)
{
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;
}
+11 -2
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
@@ -8098,6 +8098,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
@@ -8222,6 +8224,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);
+3 -3
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. */
+4 -1
View File
@@ -1635,6 +1635,7 @@ struct channel_S {
int ch_last_msg_id; /* ID of the last message */
chanpart_T ch_part[PART_COUNT]; /* info for socket, out, err and in */
int ch_write_text_mode; /* write buffer lines with CR, not NL */
char *ch_hostname; /* only for socket, allocated */
int ch_port; /* only for socket */
@@ -1716,7 +1717,8 @@ struct channel_S {
#define JO2_CURWIN 0x0200 /* "curwin" */
#define JO2_HIDDEN 0x0400 /* "hidden" */
#define JO2_TERM_OPENCMD 0x0800 /* "term_opencmd" */
#define JO2_ALL 0x0FFF
#define JO2_EOF_CHARS 0x1000 /* "eof_chars" */
#define JO2_ALL 0x1FFF
#define JO_MODE_ALL (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
#define JO_CB_ALL \
@@ -1782,6 +1784,7 @@ typedef struct
char_u *jo_term_name;
char_u *jo_term_opencmd;
int jo_term_finish;
char_u *jo_eof_chars;
#endif
} jobopt_T;
+4 -2
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);
@@ -9952,6 +9952,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;
+33 -11
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]"},
@@ -1601,6 +1607,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"},
@@ -4502,6 +4509,8 @@ check_termcode(
/* eat it when at least one digit and ending in 'c' */
if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
{
int version = col;
LOG_TR("Received CRV response");
crv_status = STATUS_GOT;
# ifdef FEAT_AUTOCMD
@@ -4514,10 +4523,11 @@ check_termcode(
switch_to_8bit();
/* rxvt sends its version number: "20703" is 2.7.3.
* Screen sends 40500.
* Ignore it for when the user has set 'term' to xterm,
* even though it's an rxvt. */
if (col > 20000)
col = 0;
if (version > 20000)
version = 0;
if (tp[1 + (tp[0] != CSI)] == '>' && semicols == 2)
{
@@ -4528,19 +4538,19 @@ check_termcode(
if (!option_was_set((char_u *)"ttym"))
{
# ifdef TTYM_SGR
if (col >= 277)
if (version >= 277)
set_option_value((char_u *)"ttym", 0L,
(char_u *)"sgr", 0);
else
# endif
/* if xterm version >= 95 use mouse dragging */
if (col >= 95)
if (version >= 95)
set_option_value((char_u *)"ttym", 0L,
(char_u *)"xterm2", 0);
}
/* if xterm version >= 141 try to get termcap codes */
if (col >= 141)
if (version >= 141)
{
LOG_TR("Enable checking for XT codes");
check_for_codes = TRUE;
@@ -4549,7 +4559,7 @@ check_termcode(
}
/* libvterm sends 0;100;0 */
if (col == 100
if (version == 100
&& STRNCMP(tp + extra - 2, "0;100;0c", 8) == 0)
{
/* If run from Vim $COLORS is set to the number of
@@ -4564,14 +4574,26 @@ check_termcode(
* compatible. */
# ifdef MACOS
/* Mac Terminal.app sends 1;95;0 */
if (col == 95
if (version == 95
&& STRNCMP(tp + extra - 2, "1;95;0c", 7) == 0)
is_not_xterm = TRUE;
# endif
/* Gnome Terminal.app sends 1;3801;0 or 1;4402;0,
* assuming any version number over 3000 is not an
* xterm. */
if (col >= 3000)
/* Gnome terminal sends 1;3801;0 or 1;4402;0.
* xfce4-terminal sends 1;2802;0.
* screen sends 83;40500;0
* Assuming any version number over 2800 is not an
* xterm (without the limit for rxvt and screen). */
if (col >= 2800)
is_not_xterm = TRUE;
/* PuTTY sends 0;136;0 */
if (version == 136
&& STRNCMP(tp + extra - 2, "0;136;0c", 8) == 0)
is_not_xterm = TRUE;
/* Konsole sends 0;115;0 */
if (version == 115
&& STRNCMP(tp + extra - 2, "0;115;0c", 8) == 0)
is_not_xterm = TRUE;
/* Only request the cursor style if t_SH and t_RS are
+4
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) */
+79 -32
View File
@@ -39,7 +39,6 @@
*
* TODO:
* - ":term NONE" does not work in MS-Windows.
* - test for writing lines to terminal job does not work on MS-Windows
* - implement term_setsize()
* - add test for giving error for invalid 'termsize' value.
* - support minimal size when 'termsize' is "rows*cols".
@@ -48,16 +47,6 @@
* - GUI: when 'confirm' is set and trying to exit Vim, dialog offers to save
* changes to "!shell".
* (justrajdeep, 2017 Aug 22)
* - command argument with spaces doesn't work #1999
* :terminal ls dir\ with\ spaces
* - implement job options when starting a terminal. Allow:
* "in_io", "in_top", "in_bot", "in_name", "in_buf"
"out_io", "out_name", "out_buf", "out_modifiable", "out_msg"
"err_io", "err_name", "err_buf", "err_modifiable", "err_msg"
* Check that something is connected to the terminal.
* Test: "cat" reading from a file or buffer
* "ls" writing stdout to a file or buffer
* shell writing stderr to a file or buffer
* - For the GUI fill termios with default values, perhaps like pangoterm:
* http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
* - if the job in the terminal does not support the mouse, we can use the
@@ -110,6 +99,7 @@ struct terminal_S {
int tl_channel_closed;
int tl_finish; /* 'c' for ++close, 'o' for ++open */
char_u *tl_opencmd;
char_u *tl_eof_chars;
#ifdef WIN3264
void *tl_winpty_config;
@@ -218,16 +208,6 @@ init_job_options(jobopt_T *opt)
opt->jo_out_mode = MODE_RAW;
opt->jo_err_mode = MODE_RAW;
opt->jo_set = JO_MODE | JO_OUT_MODE | JO_ERR_MODE;
opt->jo_io[PART_OUT] = JIO_BUFFER;
opt->jo_io[PART_ERR] = JIO_BUFFER;
opt->jo_set |= JO_OUT_IO + JO_ERR_IO;
opt->jo_modifiable[PART_OUT] = 0;
opt->jo_modifiable[PART_ERR] = 0;
opt->jo_set |= JO_OUT_MODIFIABLE + JO_ERR_MODIFIABLE;
opt->jo_set |= JO_OUT_BUF + JO_ERR_BUF;
}
/*
@@ -236,8 +216,24 @@ init_job_options(jobopt_T *opt)
static void
setup_job_options(jobopt_T *opt, int rows, int cols)
{
opt->jo_io_buf[PART_OUT] = curbuf->b_fnum;
opt->jo_io_buf[PART_ERR] = curbuf->b_fnum;
if (!(opt->jo_set & JO_OUT_IO))
{
/* Connect stdout to the terminal. */
opt->jo_io[PART_OUT] = JIO_BUFFER;
opt->jo_io_buf[PART_OUT] = curbuf->b_fnum;
opt->jo_modifiable[PART_OUT] = 0;
opt->jo_set |= JO_OUT_IO + JO_OUT_BUF + JO_OUT_MODIFIABLE;
}
if (!(opt->jo_set & JO_ERR_IO))
{
/* Connect stderr to the terminal. */
opt->jo_io[PART_ERR] = JIO_BUFFER;
opt->jo_io_buf[PART_ERR] = curbuf->b_fnum;
opt->jo_modifiable[PART_ERR] = 0;
opt->jo_set |= JO_ERR_IO + JO_ERR_BUF + JO_ERR_MODIFIABLE;
}
opt->jo_pty = TRUE;
if ((opt->jo_set2 & JO2_TERM_ROWS) == 0)
opt->jo_term_rows = rows;
@@ -257,6 +253,15 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
if (check_restricted() || check_secure())
return;
if ((opt->jo_set & (JO_IN_IO + JO_OUT_IO + JO_ERR_IO))
== (JO_IN_IO + JO_OUT_IO + JO_ERR_IO)
|| (!(opt->jo_set & JO_OUT_IO) && (opt->jo_set & JO_OUT_BUF))
|| (!(opt->jo_set & JO_ERR_IO) && (opt->jo_set & JO_ERR_BUF)))
{
EMSG(_(e_invarg));
return;
}
term = (term_T *)alloc_clear(sizeof(term_T));
if (term == NULL)
return;
@@ -389,6 +394,9 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
if (opt->jo_term_opencmd != NULL)
term->tl_opencmd = vim_strsave(opt->jo_term_opencmd);
if (opt->jo_eof_chars != NULL)
term->tl_eof_chars = vim_strsave(opt->jo_eof_chars);
set_string_option_direct((char_u *)"buftype", -1,
(char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0);
@@ -490,6 +498,20 @@ ex_terminal(exarg_T *eap)
opt.jo_term_cols = atoi((char *)ep + 1);
p = skiptowhite(cmd);
}
else if ((int)(p - cmd) == 3 && STRNICMP(cmd, "eof", 3) == 0
&& ep != NULL)
{
char_u *buf = NULL;
char_u *keys;
p = skiptowhite(cmd);
*p = NUL;
keys = replace_termcodes(ep + 1, &buf, TRUE, TRUE, TRUE);
opt.jo_set2 |= JO2_EOF_CHARS;
opt.jo_eof_chars = vim_strsave(keys);
vim_free(buf);
*p = ' ';
}
else
{
if (*p)
@@ -570,6 +592,7 @@ free_terminal(buf_T *buf)
vim_free(term->tl_title);
vim_free(term->tl_status_text);
vim_free(term->tl_opencmd);
vim_free(term->tl_eof_chars);
vim_free(term->tl_cursor_color);
vim_free(term);
buf->b_term = NULL;
@@ -1721,7 +1744,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;
@@ -2437,7 +2460,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},
};
@@ -2819,14 +2842,13 @@ f_term_start(typval_T *argvars, typval_T *rettv)
jobopt_T opt;
init_job_options(&opt);
/* TODO: allow more job options */
if (argvars[1].v_type != VAR_UNKNOWN
&& get_job_options(&argvars[1], &opt,
JO_TIMEOUT_ALL + JO_STOPONEXIT
+ JO_EXIT_CB + JO_CLOSE_CALLBACK,
+ JO_EXIT_CB + JO_CLOSE_CALLBACK + JO_OUT_IO,
JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN + JO2_TERM_OPENCMD
+ JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
+ JO2_CWD + JO2_ENV) == FAIL)
+ JO2_CWD + JO2_ENV + JO2_EOF_CHARS) == FAIL)
return;
if (opt.jo_vertical)
@@ -2895,6 +2917,32 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
}
}
/*
* Called when a channel has sent all the lines to a terminal.
* Send a CTRL-D to mark the end of the text.
*/
void
term_send_eof(channel_T *ch)
{
term_T *term;
for (term = first_term; term != NULL; term = term->tl_next)
if (term->tl_job == ch->ch_job)
{
if (term->tl_eof_chars != NULL)
{
channel_send(ch, PART_IN, term->tl_eof_chars,
(int)STRLEN(term->tl_eof_chars), NULL);
channel_send(ch, PART_IN, (char_u *)"\r", 1, NULL);
}
# ifdef WIN3264
else
/* Default: CTRL-D */
channel_send(ch, PART_IN, (char_u *)"\004\r", 2, NULL);
# endif
}
}
# if defined(WIN3264) || defined(PROTO)
/**************************************
@@ -3065,8 +3113,6 @@ term_and_job_init(
if (job == NULL)
goto failed;
/* TODO: when all lines are written and the fd is closed, the command
* doesn't get EOF and hangs. */
if (opt->jo_set & JO_IN_BUF)
job->jv_in_buf = buflist_findnr(opt->jo_io_buf[PART_IN]);
@@ -3088,6 +3134,9 @@ term_and_job_init(
GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL));
/* Write lines with CR instead of NL. */
channel->ch_write_text_mode = TRUE;
jo = CreateJobObject(NULL, NULL);
if (jo == NULL)
goto failed;
@@ -3193,7 +3242,6 @@ terminal_enabled(void)
return dyn_winpty_init(FALSE) == OK;
}
# else
/**************************************
@@ -3214,7 +3262,6 @@ term_and_job_init(
{
create_vterm(term, term->tl_rows, term->tl_cols);
/* TODO: if the command is "NONE" only create a pty. */
term->tl_job = job_start(argvar, opt);
if (term->tl_job != NULL)
++term->tl_job->jv_refcount;
+3
View File
@@ -21,6 +21,9 @@ if 1
let $XAUTHORITY = $HOME . '/.Xauthority'
endif
" Avoid storing shell history.
let $HISTFILE = ""
" Make sure $HOME does not get read or written.
" It must exist, gnome tries to create $HOME/.gnome2
let $HOME = getcwd() . '/XfakeHOME'
+1
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
+26
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
+22 -2
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
+6 -2
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&
+49 -28
View File
@@ -2299,27 +2299,39 @@ func Xsetexpr_tests(cchar)
call s:setup_commands(a:cchar)
let t = ["File1:10:Line10", "File1:20:Line20"]
call g:Xsetlist([], ' ', {'text' : t})
call g:Xsetlist([], 'a', {'text' : "File1:30:Line30"})
call g:Xsetlist([], ' ', {'lines' : t})
call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
let l = g:Xgetlist()
call assert_equal(3, len(l))
call assert_equal(20, l[1].lnum)
call assert_equal('Line30', l[2].text)
call g:Xsetlist([], 'r', {'text' : "File2:5:Line5"})
call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
let l = g:Xgetlist()
call assert_equal(1, len(l))
call assert_equal('Line5', l[0].text)
call assert_equal(-1, g:Xsetlist([], 'a', {'text' : 10}))
call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
call g:Xsetlist([], 'f')
" Add entries to multiple lists
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : ["File1:10:Line10"]})
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : ["File2:20:Line20"]})
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : ["File1:15:Line15"]})
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : ["File2:25:Line25"]})
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
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()
@@ -2334,10 +2346,10 @@ func Xmultidirstack_tests(cchar)
call g:Xsetlist([], 'f')
Xexpr "" | Xexpr ""
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "Entering dir 'Xone/a'"})
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "Entering dir 'Xtwo/a'"})
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "one.txt:3:one one one"})
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "two.txt:5:two two two"})
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
let l1 = g:Xgetlist({'nr':1, 'items':1})
let l2 = g:Xgetlist({'nr':2, 'items':1})
@@ -2371,10 +2383,10 @@ func Xmultifilestack_tests(cchar)
call g:Xsetlist([], 'f')
Xexpr "" | Xexpr ""
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "[one.txt]"})
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "[two.txt]"})
call g:Xsetlist([], 'a', {'nr' : 1, 'text' : "(3,5) one one one"})
call g:Xsetlist([], 'a', {'nr' : 2, 'text' : "(5,9) two two two"})
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
let l1 = g:Xgetlist({'nr':1, 'items':1})
let l2 = g:Xgetlist({'nr':2, 'items':1})
@@ -2523,28 +2535,37 @@ endfunc
" Test for getting the quickfix list items from some text without modifying
" the quickfix stack
func XgetListFromText(cchar)
func XgetListFromLines(cchar)
call s:setup_commands(a:cchar)
call g:Xsetlist([], 'f')
let l = g:Xgetlist({'text' : "File1:10:Line10"}).items
call assert_equal(1, len(l))
call assert_equal('Line10', l[0].text)
let l = g:Xgetlist({'text' : ["File2:20:Line20", "File2:30:Line30"]}).items
let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
call assert_equal(2, len(l))
call assert_equal(30, l[1].lnum)
call assert_equal({}, g:Xgetlist({'text' : 10}))
call assert_equal({}, g:Xgetlist({'text' : []}))
call assert_equal({}, g:Xgetlist({'lines' : 10}))
call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
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
func Test_get_list_from_text()
call XgetListFromText('c')
call XgetListFromText('l')
func Test_get_list_from_lines()
call XgetListFromLines('c')
call XgetListFromLines('l')
endfunc
" Tests for the quickfix list id
@@ -2567,7 +2588,7 @@ func Xqfid_tests(cchar)
call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
call g:Xsetlist([], 'a', {'id':start_id+1, 'text':'F1:10:L10'})
call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
+101 -18
View File
@@ -164,10 +164,8 @@ func Test_terminal_scrape_123()
call term_wait(1234)
call term_wait(buf)
if has('win32')
" TODO: this should not be needed
sleep 100m
endif
let g:buf = buf
call WaitFor('len(term_scrape(g:buf, 1)) > 0')
call Check_123(buf)
" Must still work after the job ended.
@@ -293,6 +291,8 @@ func Test_terminal_size()
let size = term_getsize('')
bwipe!
call assert_equal([7, 27], size)
call delete('Xtext')
endfunc
func Test_terminal_curwin()
@@ -325,7 +325,7 @@ func Test_terminal_curwin()
split dummy
bwipe!
call delete('Xtext')
endfunc
func Test_finish_open_close()
@@ -458,14 +458,16 @@ endfunction
func Test_terminal_noblock()
let g:buf = term_start(&shell)
if has('mac')
" The shell or something else has a problem dealing with more than 1000
" characters at the same time.
let len = 1000
else
let len = 5000
endif
for c in ['a','b','c','d','e','f','g','h','i','j','k']
call term_sendkeys(g:buf, 'echo ' . repeat(c, 5000) . "\<cr>")
if has('mac')
" TODO: this should not be needed, but without it sending keys blocks
" after 8000 chars or so.
sleep 100m
endif
call term_sendkeys(g:buf, 'echo ' . repeat(c, len) . "\<cr>")
endfor
call term_sendkeys(g:buf, "echo done\<cr>")
@@ -489,25 +491,48 @@ func Test_terminal_noblock()
endfunc
func Test_terminal_write_stdin()
" Todo: make this work on all systems.
if !has('unix')
return
if !executable('wc')
throw 'skipped: wc command not available'
endif
new
call setline(1, ['one', 'two', 'three'])
%term wc
call WaitFor('getline(1) != ""')
let nrs = split(getline(1))
call WaitFor('getline("$") =~ "3"')
let nrs = split(getline('$'))
call assert_equal(['3', '3', '14'], nrs)
bwipe
new
call setline(1, ['one', 'two', 'three', 'four'])
2,3term wc
call WaitFor('getline(1) != ""')
let nrs = split(getline(1))
call WaitFor('getline("$") =~ "2"')
let nrs = split(getline('$'))
call assert_equal(['2', '2', '10'], nrs)
bwipe
if executable('python')
new
call setline(1, ['print("hello")'])
1term ++eof=exit() python
" MS-Windows echoes the input, Unix doesn't.
call WaitFor('getline("$") =~ "exit" || getline(1) =~ "hello"')
if getline(1) =~ 'hello'
call assert_equal('hello', getline(1))
else
call assert_equal('hello', getline(line('$') - 1))
endif
bwipe
if has('win32')
new
call setline(1, ['print("hello")'])
1term ++eof=<C-Z> python
call WaitFor('getline("$") =~ "Z"')
call assert_equal('hello', getline(line('$') - 1))
bwipe
endif
endif
bwipe!
endfunc
@@ -530,3 +555,61 @@ func Test_terminal_no_cmd()
call assert_equal('look here', term_getline(buf, 1))
bwipe!
endfunc
func Test_terminal_special_chars()
" this file name only works on Unix
if !has('unix')
return
endif
call mkdir('Xdir with spaces')
call writefile(['x'], 'Xdir with spaces/quoted"file')
term ls Xdir\ with\ spaces/quoted\"file
call WaitFor('term_getline("", 1) =~ "quoted"')
call assert_match('quoted"file', term_getline('', 1))
call term_wait('')
call delete('Xdir with spaces', 'rf')
bwipe
endfunc
func Test_terminal_wrong_options()
call assert_fails('call term_start(&shell, {
\ "in_io": "file",
\ "in_name": "xxx",
\ "out_io": "file",
\ "out_name": "xxx",
\ "err_io": "file",
\ "err_name": "xxx"
\ })', 'E474:')
call assert_fails('call term_start(&shell, {
\ "out_buf": bufnr("%")
\ })', 'E474:')
call assert_fails('call term_start(&shell, {
\ "err_buf": bufnr("%")
\ })', 'E474:')
endfunc
func Test_terminal_redir_file()
let cmd = Get_cat_123_cmd()
let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
call term_wait(buf)
call WaitFor('len(readfile("Xfile")) > 0')
call assert_match('123', readfile('Xfile')[0])
call delete('Xfile')
if has('unix')
let buf = term_start('xyzabc', {'err_io': 'file', 'err_name': 'Xfile'})
call term_wait(buf)
call WaitFor('len(readfile("Xfile")) > 0')
call assert_match('executing job failed', readfile('Xfile')[0])
call delete('Xfile')
call writefile(['one line'], 'Xfile')
let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xfile'})
call term_wait(buf)
call WaitFor('term_getline(' . buf . ', 1) == "one line"')
call assert_equal('one line', term_getline(buf, 1))
bwipe
call delete('Xfile')
endif
endfunc
+19
View File
@@ -206,5 +206,24 @@ func Test_timer_errors()
call assert_equal(3, g:call_count)
endfunc
func FeedAndPeek(timer)
call test_feedinput('a')
call getchar(1)
endfunc
func Interrupt(timer)
call test_feedinput("\<C-C>")
endfunc
func Test_peek_and_get_char()
if !has('unix') && !has('gui_running')
return
endif
call timer_start(0, 'FeedAndPeek')
let intr = timer_start(100, 'Interrupt')
let c = getchar()
call assert_equal(char2nr('a'), c)
call timer_stop(intr)
endfunc
" vim: shiftwidth=2 sts=2 expandtab
-15
View File
@@ -1671,11 +1671,6 @@ set_input_buf(char_u *p)
}
}
#if defined(FEAT_GUI) \
|| defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE) \
|| defined(FEAT_XCLIPBOARD) || defined(VMS) \
|| defined(FEAT_CLIENTSERVER) \
|| defined(PROTO)
/*
* Add the given bytes to the input buffer
* Special keys start with CSI. A real CSI must have been translated to
@@ -1696,15 +1691,7 @@ add_to_input_buf(char_u *s, int len)
while (len--)
inbuf[inbufcount++] = *s++;
}
#endif
#if ((defined(FEAT_XIM) || defined(FEAT_DND)) && defined(FEAT_GUI_GTK)) \
|| defined(FEAT_GUI_MSWIN) \
|| defined(FEAT_GUI_MAC) \
|| (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) \
|| (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
|| defined(FEAT_MENU))) \
|| defined(PROTO)
/*
* Add "str[len]" to the input buffer while escaping CSI bytes.
*/
@@ -1726,7 +1713,6 @@ add_to_input_buf_csi(char_u *str, int len)
}
}
}
#endif
#if defined(FEAT_HANGULIN) || defined(PROTO)
void
@@ -1764,7 +1750,6 @@ trash_input_buf(void)
/*
* Read as much data from the input buffer as possible up to maxlen, and store
* it in buf.
* Note: this function used to be Read() in unix.c
*/
int
read_from_input_buf(char_u *buf, long maxlen)
+52
View File
@@ -784,6 +784,58 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1052,
/**/
1051,
/**/
1050,
/**/
1049,
/**/
1048,
/**/
1047,
/**/
1046,
/**/
1045,
/**/
1044,
/**/
1043,
/**/
1042,
/**/
1041,
/**/
1040,
/**/
1039,
/**/
1038,
/**/
1037,
/**/
1036,
/**/
1035,
/**/
1034,
/**/
1033,
/**/
1032,
/**/
1031,
/**/
1030,
/**/
1029,
/**/
1028,
/**/
1027,
/**/
1026,
/**/
+3 -7
View File
@@ -436,13 +436,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.
@@ -683,7 +678,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