Compare commits

...

9 Commits

Author SHA1 Message Date
dada6d2a8e patch 8.0.1036: ++eof argument for terminal only available on MS-Windows
Problem:    ++eof argument for terminal only available on MS-Windows.
Solution:   Also support ++eof on Unix.  Add a test.
2017-09-02 17:18:35 +02:00
ef68e4fa52 patch 8.0.1035: sending buffer lines to terminal doesn't work on MS-Windows
Problem:    Sending buffer lines to terminal doesn't work on MS-Windows.
Solution:   Use CR instead of NL after every line.  Make the EOF text work
            properly.  Add the ++eof argument to :terminal.
2017-09-02 16:28:36 +02:00
3346cc4ffb patch 8.0.1034: sending buffer lines to terminal doesn't work on MS-Windows
Problem:    Sending buffer lines to terminal doesn't work on MS-Windows.
Solution:   Send CTRL-D to mark the end of the text. (Yasuhiro Matsumoto,
            closes #2043) Add the "eof_chars" option.
2017-09-02 14:54:21 +02:00
995e4afcfe patch 8.0.1033: detecting background color does not work in screen
Problem:    Detecting background color does not work in screen, even when it
            is working like an xterm.
Solution:   Make "screen.xterm" use termcap entries like an xterm. (Lubomir
            Rintel, closes #2048)  When termresponse version is huge also
            recognize as not being an xterm.
2017-09-01 20:24:03 +02:00
9ac9dfa9e2 patch 8.0.1032: "make tags" doesn't work well on MS-Windows
Problem:    "make tags" doesn't work well on MS-Windows.
Solution:   Add or fix tags target. (Ken Takata)
2017-09-01 18:41:26 +02:00
2c809b7c7d patch 8.0.1031: "text" argument for getqflist() is confusing
Problem:    "text" argument for getqflist() is confusing. (Lcd47)
Solution:   Use "lines" instead. (Yegappan Lakshmanan)
2017-09-01 18:34:02 +02:00
9e8dcf9d6f patch 8.0.1030: MS-Windows: wrong size computation in is_cygpty()
Problem:    MS-Windows: wrong size computation in is_cygpty().
Solution:   Compute the size properly. (Ken Takata)
2017-08-31 21:35:45 +02:00
da73253a0b patch 8.0.1029: return value of getqflist() is inconsistent
Problem:    Return value of getqflist() is inconsistent.  (Lcd47)
Solution:   Always return an "items" entry.
2017-08-31 20:58:02 +02:00
3d593c2dc9 patch 8.0.1028: MS-Windows: viminfo uses $VIM/_viminfo if $HOME not set
Problem:    MS-Windows: viminfo uses $VIM/_viminfo if $HOME not set. (Yongwei
            Wu)
Solution:   Use vim_getenv() but check it's returning the default "C:/".
2017-08-31 20:42:18 +02:00
17 changed files with 260 additions and 103 deletions

View File

@ -4636,14 +4636,13 @@ getqflist([{what}]) *getqflist()*
|quickfix-ID|; zero means the id for the
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
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 +4670,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()*
@ -7071,13 +7071,12 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
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.
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
the last quickfix list
@ -7093,6 +7092,7 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
Examples: >
: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.
@ -8141,6 +8141,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}

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

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

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

View File

@ -1300,11 +1300,16 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
return;
memcpy((char *)p, (char *)line, len);
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 + 1] = NUL;
channel_send(channel, PART_IN, p, len + 1, "write_buf_line");
vim_free(p);
@ -1417,6 +1422,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");
@ -4626,6 +4637,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))

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. */

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>
@ -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: */

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 */

View File

@ -2280,6 +2280,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);
}

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);

View File

@ -4643,16 +4643,19 @@ 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(dictitem_T *di, dict_T *retdict)
{
int status = FAIL;
qf_info_T *qi;
/* 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)
{
list_T *l = list_alloc();
if (l == NULL)
return FAIL;
qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
if (qi != NULL)
{
@ -4661,18 +4664,14 @@ qf_get_list_from_text(dictitem_T *di, dict_T *retdict)
if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, p_efm,
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;
}
qf_free(qi, 0);
}
free(qi);
}
dict_add_list(retdict, "items", l);
status = OK;
}
return status;
@ -4692,8 +4691,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(di, retdict);
if (wp != NULL)
qi = GET_LOC_LIST(wp);
@ -5052,12 +5051,10 @@ 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 *)"lines", -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))
/* 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);

View File

@ -1632,6 +1632,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 */
@ -1713,7 +1714,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 \
@ -1779,6 +1781,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;

View File

@ -4496,6 +4496,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
@ -4508,10 +4510,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)
{
@ -4522,19 +4525,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;
@ -4543,7 +4546,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
@ -4558,24 +4561,25 @@ 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 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. */
* xterm (without the limit for rxvt and screen). */
if (col >= 2800)
is_not_xterm = TRUE;
/* PuTTY sends 0;136;0 */
if (col == 136
if (version == 136
&& STRNCMP(tp + extra - 2, "0;136;0c", 8) == 0)
is_not_xterm = TRUE;
/* Konsole sends 0;115;0 */
if (col == 115
if (version == 115
&& STRNCMP(tp + extra - 2, "0;115;0c", 8) == 0)
is_not_xterm = TRUE;

View File

@ -110,6 +110,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;
@ -389,6 +390,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 +494,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 +588,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;
@ -2821,7 +2840,7 @@ f_term_start(typval_T *argvars, typval_T *rettv)
+ JO_EXIT_CB + JO_CLOSE_CALLBACK,
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)
@ -2890,6 +2909,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)
/**************************************
@ -3060,8 +3105,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]);
@ -3083,6 +3126,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;
@ -3188,7 +3234,6 @@ terminal_enabled(void)
return dyn_winpty_init(FALSE) == OK;
}
# else
/**************************************

View File

@ -2299,25 +2299,26 @@ 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)
endfunc
@ -2334,10 +2335,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 +2372,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 +2524,26 @@ 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)
" 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 +2566,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'}))

View File

@ -489,25 +489,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

View File

@ -769,6 +769,24 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1036,
/**/
1035,
/**/
1034,
/**/
1033,
/**/
1032,
/**/
1031,
/**/
1030,
/**/
1029,
/**/
1028,
/**/
1027,
/**/