Compare commits

...

14 Commits

Author SHA1 Message Date
4bebc9a056 patch 8.0.1024: folds lost when session file has a buffer in two windows
Problem:    Manual folds are lost when a session file has the same buffer in
            two windows. (Jeansen)
Solution:   Use ":edit" only once. (Christian Brabandt, closes #1958)
2017-08-30 21:07:38 +02:00
a539f4f1ae patch 8.0.1023: it is not easy to identify a quickfix list
Problem:    It is not easy to identify a quickfix list.
Solution:   Add the "id" field. (Yegappan Lakshmanan)
2017-08-30 20:33:55 +02:00
1a333bc44a patch 8.0.1022: test 80 is old style
Problem:    Test 80 is old style.
Solution:   Turn it into a new style test. (Yegappan Lakshmanan)
2017-08-30 20:21:58 +02:00
dc5471d482 patch 8.0.1021: older Gnome terminal still echoes t_RC
Problem:    Older Gnome terminal still echoes t_RC. (Fracois Ingelrest)
Solution:   Check for version > 3000 instead of 4000.
2017-08-30 18:59:03 +02:00
0f0f230012 patch 8.0.1020: when a timer calls getchar(1) input is overwritten
Problem:    When a timer calls getchar(1) input is overwritten.
Solution:   Increment tb_change_cnt in inchar(). (closes #1940)
2017-08-30 18:52:56 +02:00
d41babef89 patch 8.0.1019: pasting in virtual edit happens in the wrong place
Problem:    Pasting in virtual edit happens in the wrong place.
Solution:   Do not adjust coladd when after the end of the line (closes #2015)
2017-08-30 17:01:35 +02:00
4ad3b2b588 patch 8.0.1018: warnings from 64-bit compiler
Problem:    Warnings from 64-bit compiler. (Christian Brabandt)
Solution:   Add type casts.
2017-08-30 15:57:33 +02:00
dde6034111 patch 8.0.1017: test for MS-Windows $HOME always passes
Problem:    Test for MS-Windows $HOME always passes.
Solution:   Rename the test function.  Make the test pass.
2017-08-30 14:55:42 +02:00
f3af54eeb1 patch 8.0.1016: gnome terminal echoes t_RC
Problem:    Gnome terminal echoes t_RC.
Solution:   Detect Gnome terminal by the version string.  Add v: variables for
            all the term responses.
2017-08-30 14:53:06 +02:00
97a80e440a patch 8.0.1015: missing update to terminal test
Problem:    Missing update to terminal test.
Solution:   Add the changes to the test.
2017-08-30 13:31:49 +02:00
b47a2597e6 patch 8.0.1014: old compiler doesn't know uint32_t
Problem:    Old compiler doesn't know uint32_t. Warning for using NULL instead
            of NUL.
Solution:   Use UINT32_T.  Use NUL instead of NULL.
2017-08-30 13:22:28 +02:00
e561a7e2fa patch 8.0.1013: terminal window behaves different from a buffer with changes
Problem:    A terminal window with a running job behaves different from a
            window containing a changed buffer.
Solution:   Do not set 'bufhidden' to "hide".  Fix that a buffer where a
            terminal used to run is listed as "[Scratch]".
2017-08-29 22:44:59 +02:00
48340b62e8 patch 8.0.1012: MS-Windows: problem with $HOME when is was set internally
Problem:    MS-Windows: Problem with $HOME when is was set internally.
Solution:   Only use the $HOME default internally. (Yasuhiro Matsumoto, closes
            #2013)
2017-08-29 22:08:53 +02:00
97f65fafdb patch 8.0.1011: terminal test fails with Athena and Motif
Problem:    Terminal test fails with Athena and Motif.
Solution:   Ignore the error for the input context. (Kazunobu Kuriyama)
2017-08-29 20:42:07 +02:00
26 changed files with 682 additions and 490 deletions

View File

@ -1902,6 +1902,26 @@ v:termresponse The escape sequence returned by the terminal for the |t_RV|
always 95 or bigger). Pc is always zero. always 95 or bigger). Pc is always zero.
{only when compiled with |+termresponse| feature} {only when compiled with |+termresponse| feature}
*v:termblinkresp*
v:termblinkresp The escape sequence returned by the terminal for the |t_RC|
termcap entry. This is used to find out whether the terminal
cursor is blinking. This is used by |term_getcursor()|.
*v:termstyleresp*
v:termstyleresp The escape sequence returned by the terminal for the |t_RS|
termcap entry. This is used to find out what the shape of the
cursor is. This is used by |term_getcursor()|.
*v:termrgbresp*
v:termrgbresp The escape sequence returned by the terminal for the |t_RB|
termcap entry. This is used to find out what the terminal
background color is, see 'background'.
*v:termu7resp*
v:termu7resp The escape sequence returned by the terminal for the |t_u7|
termcap entry. This is used to find out what the terminal
does with ambiguous width characters, see 'ambiwidth'.
*v:testing* *testing-variable* *v:testing* *testing-variable*
v:testing Must be set before using `test_garbagecollect_now()`. v:testing Must be set before using `test_garbagecollect_now()`.
Also, when set certain error messages won't be shown for 2 Also, when set certain error messages won't be shown for 2
@ -4612,6 +4632,9 @@ getqflist([{what}]) *getqflist()*
returns only the items listed in {what} as a dictionary. The returns only the items listed in {what} as a dictionary. The
following string items are supported in {what}: following string items are supported in {what}:
context get the context stored with |setqflist()| context get the context stored with |setqflist()|
id get information for the quickfix list with
|quickfix-ID|; zero means the id for the
current list or the list specifed by 'nr'
items quickfix list entries items quickfix list entries
nr get information for this quickfix list; zero nr get information for this quickfix list; zero
means the current quickfix list and '$' means means the current quickfix list and '$' means
@ -4626,6 +4649,8 @@ getqflist([{what}]) *getqflist()*
all all of the above quickfix properties all all of the above quickfix properties
Non-string items in {what} are ignored. Non-string items in {what} are ignored.
If "nr" is not present then the current quickfix list is used. If "nr" is not present then the current quickfix list is used.
If both "nr" and a non-zero "id" are specified, then the list
specified by "id" is used.
To get the number of lists in the quickfix stack, set 'nr' to To get the number of lists in the quickfix stack, set 'nr' to
'$' in {what}. The 'nr' value in the returned dictionary '$' in {what}. The 'nr' value in the returned dictionary
contains the quickfix stack size. contains the quickfix stack size.
@ -4637,6 +4662,7 @@ getqflist([{what}]) *getqflist()*
The returned dictionary contains the following entries: The returned dictionary contains the following entries:
context context information stored with |setqflist()| context context information stored with |setqflist()|
id quickfix list ID |quickfix-ID|
items quickfix list entries items quickfix list entries
nr quickfix list number nr quickfix list number
title quickfix list title text title quickfix list title text
@ -7049,6 +7075,7 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
text and add the resulting entries to the text and add the resulting entries to the
quickfix list {nr}. The value can be a string quickfix list {nr}. The value can be a string
with one line or a list with multiple lines. with one line or a list with multiple lines.
id quickfix list identifier |quickfix-ID|
items list of quickfix entries. Same as the {list} items list of quickfix entries. Same as the {list}
argument. argument.
nr list number in the quickfix stack; zero nr list number in the quickfix stack; zero
@ -7059,6 +7086,9 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
If the "nr" item is not present, then the current quickfix list If the "nr" item is not present, then the current quickfix list
is modified. When creating a new quickfix list, "nr" can be is modified. When creating a new quickfix list, "nr" can be
set to a value one greater than the quickfix stack size. 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
specify the list.
Examples: > Examples: >
:call setqflist([], 'r', {'title': 'My search'}) :call setqflist([], 'r', {'title': 'My search'})

View File

@ -1,4 +1,4 @@
*terminal.txt* For Vim version 8.0. Last change: 2017 Aug 26 *terminal.txt* For Vim version 8.0. Last change: 2017 Aug 29
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -140,11 +140,17 @@ Syntax ~
When the buffer associated with the terminal is unloaded or wiped out the job When the buffer associated with the terminal is unloaded or wiped out the job
is killed, similar to calling `job_stop(job, "kill")` is killed, similar to calling `job_stop(job, "kill")`
By default the 'bufhidden' option of the buffer will be set to "hide". So long as the job is running the window behaves like it contains a modified
So long as the job is running: If the window is closed the buffer becomes buffer. Trying to close the window with `CTRL-W :close` or `CTRL-W :hide`
hidden. The command will not be stopped. The `:buffer` command can be used fails, unless "!" is added, in which case the job is ended. The text in the
to turn the current window into a terminal window. If there are unsaved window is lost. The buffer still exists, but getting it in a window with
changes this fails, use ! to force, as usual. `:buffer` will show an
empty buffer.
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
current window into a terminal window. If there are unsaved changes this
fails, use ! to force, as usual.
To have a background job run without a window, and open the window when it's To have a background job run without a window, and open the window when it's
done, use options like this: > done, use options like this: >

View File

@ -2100,17 +2100,17 @@ test1 \
test_listchars \ test_listchars \
test_search_mbyte \ test_search_mbyte \
test_wordcount \ test_wordcount \
test3 test4 test5 test6 test7 test8 test9 \ test3 test4 test5 test7 test8 \
test11 test12 test14 test15 test17 test18 test19 \ test11 test12 test14 test15 test17 test19 \
test20 test21 test22 test25 test27 test28 test29 \ test20 test25 test28 test29 \
test30 test31 test32 test33 test34 test36 test37 test38 test39 \ test30 test31 test32 test33 test34 test36 test37 test38 test39 \
test40 test41 test42 test43 test44 test45 test48 test49 \ test40 test41 test42 test43 test44 test45 test48 test49 \
test50 test51 test52 test53 test54 test55 test56 test57 test59 \ test50 test52 test53 test54 test55 test56 test57 test59 \
test60 test64 test66 test68 test69 \ test60 test64 test66 test68 test69 \
test70 test72 test73 test74 test77 test78 test79 \ test70 test72 test73 test77 test78 test79 \
test80 test83 test84 test85 test86 test87 test88 \ test83 test85 test86 test87 test88 \
test91 test94 test95 test98 test99 \ test94 test95 test99 \
test100 test101 test103 test104 test107 test108: test108:
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE) cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
# Run individual NEW style test, assuming that Vim was already compiled. # Run individual NEW style test, assuming that Vim was already compiled.
@ -2278,6 +2278,7 @@ test_arglist \
test_visual \ test_visual \
test_window_cmd \ test_window_cmd \
test_window_id \ test_window_id \
test_windows_home \
test_writefile \ test_writefile \
test_alot_latin \ test_alot_latin \
test_alot_utf8 \ test_alot_utf8 \

View File

@ -5825,8 +5825,8 @@ buf_spname(buf_T *buf)
if (buf->b_term != NULL) if (buf->b_term != NULL)
return term_get_status_text(buf->b_term); return term_get_status_text(buf->b_term);
#endif #endif
if (buf->b_sfname != NULL) if (buf->b_fname != NULL)
return buf->b_sfname; return buf->b_fname;
return (char_u *)_("[Scratch]"); return (char_u *)_("[Scratch]");
} }

View File

@ -187,6 +187,10 @@ static struct vimvar
{VV_NAME("t_none", VAR_NUMBER), VV_RO}, {VV_NAME("t_none", VAR_NUMBER), VV_RO},
{VV_NAME("t_job", VAR_NUMBER), VV_RO}, {VV_NAME("t_job", VAR_NUMBER), VV_RO},
{VV_NAME("t_channel", VAR_NUMBER), VV_RO}, {VV_NAME("t_channel", VAR_NUMBER), VV_RO},
{VV_NAME("termrgbresp", VAR_STRING), VV_RO},
{VV_NAME("termu7resp", VAR_STRING), VV_RO},
{VV_NAME("termstyleresp", VAR_STRING), VV_RO},
{VV_NAME("termblinkresp", VAR_STRING), VV_RO},
}; };
/* shorthand */ /* shorthand */

View File

@ -11099,7 +11099,7 @@ static int ses_do_frame(frame_T *fr);
static int ses_do_win(win_T *wp); static int ses_do_win(win_T *wp);
static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp); static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp);
static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp); static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp);
static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp); static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp, int add_eol);
/* /*
* Write openfile commands for the current buffers to an .exrc file. * Write openfile commands for the current buffers to an .exrc file.
@ -11195,7 +11195,7 @@ makeopens(
{ {
if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L
: buf->b_wininfo->wi_fpos.lnum) < 0 : buf->b_wininfo->wi_fpos.lnum) < 0
|| ses_fname(fd, buf, &ssop_flags) == FAIL) || ses_fname(fd, buf, &ssop_flags, TRUE) == FAIL)
return FAIL; return FAIL;
} }
} }
@ -11289,7 +11289,8 @@ makeopens(
) )
{ {
if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0 if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
|| ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL) || ses_fname(fd, wp->w_buffer, &ssop_flags, TRUE)
== FAIL)
return FAIL; return FAIL;
need_tabnew = FALSE; need_tabnew = FALSE;
if (!wp->w_arg_idx_invalid) if (!wp->w_arg_idx_invalid)
@ -11636,9 +11637,20 @@ put_view(
/* /*
* Editing a file in this buffer: use ":edit file". * Editing a file in this buffer: use ":edit file".
* This may have side effects! (e.g., compressed or network file). * This may have side effects! (e.g., compressed or network file).
*
* Note, if a buffer for that file already exists, use :badd to
* edit that buffer, to not lose folding information (:edit resets
* folds in other buffers)
*/ */
if (fputs("edit ", fd) < 0 if (fputs("if bufexists('", fd) < 0
|| ses_fname(fd, wp->w_buffer, flagp) == FAIL) || ses_fname(fd, wp->w_buffer, flagp, FALSE) == FAIL
|| fputs("') | buffer ", fd) < 0
|| ses_fname(fd, wp->w_buffer, flagp, FALSE) == FAIL
|| fputs(" | else | edit ", fd) < 0
|| ses_fname(fd, wp->w_buffer, flagp, FALSE) == FAIL
|| fputs(" | endif", fd) < 0
||
put_eol(fd) == FAIL)
return FAIL; return FAIL;
} }
else else
@ -11651,7 +11663,7 @@ put_view(
{ {
/* The buffer does have a name, but it's not a file name. */ /* The buffer does have a name, but it's not a file name. */
if (fputs("file ", fd) < 0 if (fputs("file ", fd) < 0
|| ses_fname(fd, wp->w_buffer, flagp) == FAIL) || ses_fname(fd, wp->w_buffer, flagp, TRUE) == FAIL)
return FAIL; return FAIL;
} }
#endif #endif
@ -11823,11 +11835,11 @@ ses_arglist(
/* /*
* Write a buffer name to the session file. * Write a buffer name to the session file.
* Also ends the line. * Also ends the line, if "add_eol" is TRUE.
* Returns FAIL if writing fails. * Returns FAIL if writing fails.
*/ */
static int static int
ses_fname(FILE *fd, buf_T *buf, unsigned *flagp) ses_fname(FILE *fd, buf_T *buf, unsigned *flagp, int add_eol)
{ {
char_u *name; char_u *name;
@ -11846,7 +11858,8 @@ ses_fname(FILE *fd, buf_T *buf, unsigned *flagp)
name = buf->b_sfname; name = buf->b_sfname;
else else
name = buf->b_ffname; name = buf->b_ffname;
if (ses_put_fname(fd, name, flagp) == FAIL || put_eol(fd) == FAIL) if (ses_put_fname(fd, name, flagp) == FAIL
|| (add_eol && put_eol(fd) == FAIL))
return FAIL; return FAIL;
return OK; return OK;
} }

View File

@ -125,7 +125,7 @@ static int vgetorpeek(int);
static void map_free(mapblock_T **); static void map_free(mapblock_T **);
static void validate_maphash(void); static void validate_maphash(void);
static void showmap(mapblock_T *mp, int local); static void showmap(mapblock_T *mp, int local);
static int inchar(char_u *buf, int maxlen, long wait_time, int tb_change_cnt); static int inchar(char_u *buf, int maxlen, long wait_time);
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
static char_u *eval_map_expr(char_u *str, int c); static char_u *eval_map_expr(char_u *str, int c);
#endif #endif
@ -462,8 +462,7 @@ flush_buffers(int flush_typeahead)
* of an escape sequence. * of an escape sequence.
* In an xterm we get one char at a time and we have to get them all. * In an xterm we get one char at a time and we have to get them all.
*/ */
while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L, while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L) != 0)
typebuf.tb_change_cnt) != 0)
; ;
typebuf.tb_off = MAXMAPLEN; typebuf.tb_off = MAXMAPLEN;
typebuf.tb_len = 0; typebuf.tb_len = 0;
@ -2046,8 +2045,7 @@ vgetorpeek(int advance)
if (got_int) if (got_int)
{ {
/* flush all input */ /* flush all input */
c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L, c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L);
typebuf.tb_change_cnt);
/* /*
* If inchar() returns TRUE (script file was active) or we * If inchar() returns TRUE (script file was active) or we
* are inside a mapping, get out of insert mode. * are inside a mapping, get out of insert mode.
@ -2610,8 +2608,7 @@ vgetorpeek(int advance)
&& (p_timeout && (p_timeout
|| (keylen == KEYLEN_PART_KEY && p_ttimeout)) || (keylen == KEYLEN_PART_KEY && p_ttimeout))
&& (c = inchar(typebuf.tb_buf + typebuf.tb_off && (c = inchar(typebuf.tb_buf + typebuf.tb_off
+ typebuf.tb_len, 3, 25L, + typebuf.tb_len, 3, 25L)) == 0)
typebuf.tb_change_cnt)) == 0)
{ {
colnr_T col = 0, vcol; colnr_T col = 0, vcol;
char_u *ptr; char_u *ptr;
@ -2848,7 +2845,7 @@ vgetorpeek(int advance)
? -1L ? -1L
: ((keylen == KEYLEN_PART_KEY && p_ttm >= 0) : ((keylen == KEYLEN_PART_KEY && p_ttm >= 0)
? p_ttm ? p_ttm
: p_tm)), typebuf.tb_change_cnt); : p_tm)));
#ifdef FEAT_CMDL_INFO #ifdef FEAT_CMDL_INFO
if (i != 0) if (i != 0)
@ -2954,12 +2951,12 @@ vgetorpeek(int advance)
inchar( inchar(
char_u *buf, char_u *buf,
int maxlen, int maxlen,
long wait_time, /* milli seconds */ long wait_time) /* milli seconds */
int tb_change_cnt)
{ {
int len = 0; /* init for GCC */ int len = 0; /* init for GCC */
int retesc = FALSE; /* return ESC with gotint */ int retesc = FALSE; /* return ESC with gotint */
int script_char; int script_char;
int tb_change_cnt = typebuf.tb_change_cnt;
if (wait_time == -1L || wait_time > 100L) /* flush output before waiting */ if (wait_time == -1L || wait_time > 100L) /* flush output before waiting */
{ {
@ -3065,9 +3062,17 @@ inchar(
len = ui_inchar(buf, maxlen / 3, wait_time, tb_change_cnt); len = ui_inchar(buf, maxlen / 3, wait_time, tb_change_cnt);
} }
/* If the typebuf was changed further down, it is like nothing was added by
* this call. */
if (typebuf_changed(tb_change_cnt)) if (typebuf_changed(tb_change_cnt))
return 0; return 0;
/* Note the change in the typeahead buffer, this matters for when
* vgetorpeek() is called recursively, e.g. using getchar(1) in a timer
* function. */
if (len > 0 && ++typebuf.tb_change_cnt == 0)
typebuf.tb_change_cnt = 1;
return fix_input_buffer(buf, len); return fix_input_buffer(buf, len);
} }

View File

@ -1400,7 +1400,7 @@ static struct interval ambiguous[] =
* utf_char2cells() with different argument type for libvterm. * utf_char2cells() with different argument type for libvterm.
*/ */
int int
utf_uint2cells(uint32_t c) utf_uint2cells(UINT32_T c)
{ {
return utf_char2cells((int)c); return utf_char2cells((int)c);
} }
@ -2312,7 +2312,7 @@ utf_char2bytes(int c, char_u *buf)
* utf_iscomposing() with different argument type for libvterm. * utf_iscomposing() with different argument type for libvterm.
*/ */
int int
utf_iscomposing_uint(uint32_t c) utf_iscomposing_uint(UINT32_T c)
{ {
return utf_iscomposing((int)c); return utf_iscomposing((int)c);
} }

View File

@ -3750,10 +3750,33 @@ init_homedir(void)
var = mch_getenv((char_u *)"HOME"); var = mch_getenv((char_u *)"HOME");
#endif #endif
if (var != NULL && *var == NUL) /* empty is same as not set */
var = NULL;
#ifdef WIN3264 #ifdef WIN3264
/*
* Typically, $HOME is not defined on Windows, unless the user has
* specifically defined it for Vim's sake. However, on Windows NT
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
* each user. Try constructing $HOME from these.
*/
if (var == NULL || *var == NUL)
{
char_u *homedrive, *homepath;
homedrive = mch_getenv((char_u *)"HOMEDRIVE");
homepath = mch_getenv((char_u *)"HOMEPATH");
if (homepath == NULL || *homepath == NUL)
homepath = (char_u *)"\\";
if (homedrive != NULL
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
{
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
if (NameBuff[0] != NUL)
var = NameBuff;
}
}
if (var == NULL)
var = mch_getenv((char_u *)"USERPROFILE");
/* /*
* Weird but true: $HOME may contain an indirect reference to another * Weird but true: $HOME may contain an indirect reference to another
* variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set * variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set
@ -3774,40 +3797,14 @@ init_homedir(void)
{ {
vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1); vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1);
var = NameBuff; var = NameBuff;
/* Also set $HOME, it's needed for _viminfo. */
vim_setenv((char_u *)"HOME", NameBuff);
} }
} }
} }
/* if (var != NULL && *var == NUL) /* empty is same as not set */
* Typically, $HOME is not defined on Windows, unless the user has var = NULL;
* specifically defined it for Vim's sake. However, on Windows NT
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
* each user. Try constructing $HOME from these.
*/
if (var == NULL)
{
char_u *homedrive, *homepath;
homedrive = mch_getenv((char_u *)"HOMEDRIVE"); # ifdef FEAT_MBYTE
homepath = mch_getenv((char_u *)"HOMEPATH");
if (homepath == NULL || *homepath == NUL)
homepath = (char_u *)"\\";
if (homedrive != NULL
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
{
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
if (NameBuff[0] != NUL)
{
var = NameBuff;
/* Also set $HOME, it's needed for _viminfo. */
vim_setenv((char_u *)"HOME", NameBuff);
}
}
}
# if defined(FEAT_MBYTE)
if (enc_utf8 && var != NULL) if (enc_utf8 && var != NULL)
{ {
int len; int len;
@ -3823,9 +3820,7 @@ init_homedir(void)
} }
} }
# endif # endif
#endif
#if defined(MSWIN)
/* /*
* Default home dir is C:/ * Default home dir is C:/
* Best assumption we can make in such a situation. * Best assumption we can make in such a situation.
@ -3833,6 +3828,7 @@ init_homedir(void)
if (var == NULL) if (var == NULL)
var = (char_u *)"C:/"; var = (char_u *)"C:/";
#endif #endif
if (var != NULL) if (var != NULL)
{ {
#ifdef UNIX #ifdef UNIX
@ -4661,6 +4657,10 @@ home_replace(
homedir_env_orig = homedir_env = mch_getenv((char_u *)"SYS$LOGIN"); homedir_env_orig = homedir_env = mch_getenv((char_u *)"SYS$LOGIN");
#else #else
homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME"); homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME");
#endif
#ifdef WIN3264
if (homedir_env == NULL)
homedir_env_orig = homedir_env = mch_getenv((char_u *)"USERPROFILE");
#endif #endif
/* Empty is the same as not set. */ /* Empty is the same as not set. */
if (homedir_env != NULL && *homedir_env == NUL) if (homedir_env != NULL && *homedir_env == NUL)

View File

@ -607,11 +607,14 @@ check_cursor_col_win(win_T *win)
if (oldcoladd > win->w_cursor.col) if (oldcoladd > win->w_cursor.col)
{ {
win->w_cursor.coladd = oldcoladd - win->w_cursor.col; win->w_cursor.coladd = oldcoladd - win->w_cursor.col;
if (win->w_cursor.col < len && win->w_cursor.coladd > 0)
/* Make sure that coladd is not more than the char width.
* Not for the last character, coladd is then used when the cursor
* is actually after the last character. */
if (win->w_cursor.col + 1 < len && win->w_cursor.coladd > 0)
{ {
int cs, ce; int cs, ce;
/* check that coladd is not more than the char width */
getvcol(win, &win->w_cursor, &cs, NULL, &ce); getvcol(win, &win->w_cursor, &cs, NULL, &ce);
if (win->w_cursor.coladd > ce - cs) if (win->w_cursor.coladd > ce - cs)
win->w_cursor.coladd = ce - cs; win->w_cursor.coladd = ce - cs;

View File

@ -10,7 +10,7 @@ int latin_char2len(int c);
int latin_char2bytes(int c, char_u *buf); int latin_char2bytes(int c, char_u *buf);
int latin_ptr2len(char_u *p); int latin_ptr2len(char_u *p);
int latin_ptr2len_len(char_u *p, int size); int latin_ptr2len_len(char_u *p, int size);
int utf_uint2cells(uint32_t c); int utf_uint2cells(UINT32_T c);
int utf_char2cells(int c); int utf_char2cells(int c);
int latin_ptr2cells(char_u *p); int latin_ptr2cells(char_u *p);
int utf_ptr2cells(char_u *p); int utf_ptr2cells(char_u *p);
@ -38,7 +38,7 @@ int utfc_ptr2len(char_u *p);
int utfc_ptr2len_len(char_u *p, int size); int utfc_ptr2len_len(char_u *p, int size);
int utf_char2len(int c); int utf_char2len(int c);
int utf_char2bytes(int c, char_u *buf); int utf_char2bytes(int c, char_u *buf);
int utf_iscomposing_uint(uint32_t c); int utf_iscomposing_uint(UINT32_T c);
int utf_iscomposing(int c); int utf_iscomposing(int c);
int utf_printable(int c); int utf_printable(int c);
int utf_class(int c); int utf_class(int c);

View File

@ -58,6 +58,7 @@ struct qfline_S
*/ */
typedef struct qf_list_S typedef struct qf_list_S
{ {
int_u qf_id; /* Unique identifier for this list */
qfline_T *qf_start; /* pointer to the first error */ qfline_T *qf_start; /* pointer to the first error */
qfline_T *qf_last; /* pointer to the last error */ qfline_T *qf_last; /* pointer to the last error */
qfline_T *qf_ptr; /* pointer to the current error */ qfline_T *qf_ptr; /* pointer to the current error */
@ -96,6 +97,7 @@ struct qf_info_S
}; };
static qf_info_T ql_info; /* global quickfix list */ static qf_info_T ql_info; /* global quickfix list */
static int_u last_qf_id = 0; /* Last used quickfix list id */
#define FMT_PATTERNS 10 /* maximum number of % recognized */ #define FMT_PATTERNS 10 /* maximum number of % recognized */
@ -1399,6 +1401,7 @@ qf_new_list(qf_info_T *qi, char_u *qf_title)
qi->qf_curlist = qi->qf_listcount++; qi->qf_curlist = qi->qf_listcount++;
vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T))); vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
qf_store_title(qi, qi->qf_curlist, qf_title); qf_store_title(qi, qi->qf_curlist, qf_title);
qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id;
} }
/* /*
@ -1672,6 +1675,9 @@ copy_loclist(win_T *from, win_T *to)
to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */ to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */
/* Assign a new ID for the location list */
to_qfl->qf_id = ++last_qf_id;
/* When no valid entries are present in the list, qf_ptr points to /* When no valid entries are present in the list, qf_ptr points to
* the first item in the list */ * the first item in the list */
if (to_qfl->qf_nonevalid) if (to_qfl->qf_nonevalid)
@ -2808,6 +2814,7 @@ qf_free(qf_info_T *qi, int idx)
qfl->qf_title = NULL; qfl->qf_title = NULL;
free_tv(qfl->qf_ctx); free_tv(qfl->qf_ctx);
qfl->qf_ctx = NULL; qfl->qf_ctx = NULL;
qfl->qf_id = 0;
} }
/* /*
@ -4628,6 +4635,7 @@ enum {
QF_GETLIST_NR = 0x4, QF_GETLIST_NR = 0x4,
QF_GETLIST_WINID = 0x8, QF_GETLIST_WINID = 0x8,
QF_GETLIST_CONTEXT = 0x10, QF_GETLIST_CONTEXT = 0x10,
QF_GETLIST_ID = 0x20,
QF_GETLIST_ALL = 0xFF QF_GETLIST_ALL = 0xFF
}; };
@ -4688,17 +4696,17 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
return qf_get_list_from_text(di, retdict); return qf_get_list_from_text(di, retdict);
if (wp != NULL) if (wp != NULL)
{
qi = GET_LOC_LIST(wp); qi = GET_LOC_LIST(wp);
if (qi == NULL)
{ /* List is not present or is empty */
/* If querying for the size of the location list, return 0 */ if (qi == NULL || qi->qf_listcount == 0)
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL) {
&& (di->di_tv.v_type == VAR_STRING) /* If querying for the size of the list, return 0 */
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0)) if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
return dict_add_nr_str(retdict, "nr", 0, NULL); && (di->di_tv.v_type == VAR_STRING)
return FAIL; && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
} return dict_add_nr_str(retdict, "nr", 0, NULL);
return FAIL;
} }
qf_idx = qi->qf_curlist; /* default is the current list */ qf_idx = qi->qf_curlist; /* default is the current list */
@ -4714,41 +4722,52 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (qf_idx < 0 || qf_idx >= qi->qf_listcount) if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
return FAIL; return FAIL;
} }
else if (qi->qf_listcount == 0) /* stack is empty */
return FAIL;
flags |= QF_GETLIST_NR;
} }
else if ((di->di_tv.v_type == VAR_STRING) else if ((di->di_tv.v_type == VAR_STRING)
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0)) && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
{
/* Get the last quickfix list number */ /* Get the last quickfix list number */
if (qi->qf_listcount > 0) qf_idx = qi->qf_listcount - 1;
qf_idx = qi->qf_listcount - 1; else
else return FAIL;
qf_idx = -1; /* Quickfix stack is empty */ flags |= QF_GETLIST_NR;
flags |= QF_GETLIST_NR; }
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
{
/* Look for a list with the specified id */
if (di->di_tv.v_type == VAR_NUMBER)
{
/* For zero, use the current list or the list specifed by 'nr' */
if (di->di_tv.vval.v_number != 0)
{
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
{
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
break;
}
if (qf_idx == qi->qf_listcount)
return FAIL; /* List not found */
}
flags |= QF_GETLIST_ID;
} }
else else
return FAIL; return FAIL;
} }
if (qf_idx != -1) if (dict_find(what, (char_u *)"all", -1) != NULL)
{ flags |= QF_GETLIST_ALL;
if (dict_find(what, (char_u *)"all", -1) != NULL)
flags |= QF_GETLIST_ALL;
if (dict_find(what, (char_u *)"title", -1) != NULL) if (dict_find(what, (char_u *)"title", -1) != NULL)
flags |= QF_GETLIST_TITLE; flags |= QF_GETLIST_TITLE;
if (dict_find(what, (char_u *)"winid", -1) != NULL) if (dict_find(what, (char_u *)"winid", -1) != NULL)
flags |= QF_GETLIST_WINID; flags |= QF_GETLIST_WINID;
if (dict_find(what, (char_u *)"context", -1) != NULL) if (dict_find(what, (char_u *)"context", -1) != NULL)
flags |= QF_GETLIST_CONTEXT; flags |= QF_GETLIST_CONTEXT;
if (dict_find(what, (char_u *)"items", -1) != NULL) if (dict_find(what, (char_u *)"items", -1) != NULL)
flags |= QF_GETLIST_ITEMS; flags |= QF_GETLIST_ITEMS;
}
if (flags & QF_GETLIST_TITLE) if (flags & QF_GETLIST_TITLE)
{ {
@ -4798,6 +4817,10 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)""); status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
} }
if ((status == OK) && (flags & QF_GETLIST_ID))
status = dict_add_nr_str(retdict, "id", qi->qf_lists[qf_idx].qf_id,
NULL);
return status; return status;
} }
@ -4983,6 +5006,21 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
return FAIL; return FAIL;
} }
if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
{
/* Use the quickfix/location list with the specified id */
if (di->di_tv.v_type == VAR_NUMBER)
{
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
break;
if (qf_idx == qi->qf_listcount)
return FAIL; /* List not found */
}
else
return FAIL;
}
if (newlist) if (newlist)
{ {
qi->qf_curlist = qf_idx; qi->qf_curlist = qf_idx;

View File

@ -1369,9 +1369,7 @@ static int need_gather = FALSE; /* need to fill termleader[] */
static char_u termleader[256 + 1]; /* for check_termcode() */ static char_u termleader[256 + 1]; /* for check_termcode() */
#ifdef FEAT_TERMRESPONSE #ifdef FEAT_TERMRESPONSE
static int check_for_codes = FALSE; /* check for key code response */ static int check_for_codes = FALSE; /* check for key code response */
# ifdef MACOS static int is_not_xterm = FALSE; /* recognized not-really-xterm */
static int is_terminal_app = FALSE; /* recognized Terminal.app */
# endif
#endif #endif
static struct builtin_term * static struct builtin_term *
@ -3506,13 +3504,10 @@ may_req_ambiguous_char_width(void)
/* /*
* Similar to requesting the version string: Request the terminal background * Similar to requesting the version string: Request the terminal background
* color when it is the right moment. * color when it is the right moment.
* Also request the cursor shape, if possible.
*/ */
void void
may_req_bg_color(void) may_req_bg_color(void)
{ {
int did_one = FALSE;
if (can_get_termresponse() && starting == 0) if (can_get_termresponse() && starting == 0)
{ {
/* Only request background if t_RB is set and 'background' wasn't /* Only request background if t_RB is set and 'background' wasn't
@ -3524,20 +3519,7 @@ may_req_bg_color(void)
LOG_TR("Sending BG request"); LOG_TR("Sending BG request");
out_str(T_RBG); out_str(T_RBG);
rbg_status = STATUS_SENT; rbg_status = STATUS_SENT;
did_one = TRUE;
}
/* Only request cursor blinking mode if t_RC is set. */
if (rbm_status == STATUS_GET && *T_CRC != NUL)
{
LOG_TR("Sending BC request");
out_str(T_CRC);
rbm_status = STATUS_SENT;
did_one = TRUE;
}
if (did_one)
{
/* check for the characters now, otherwise they might be eaten by /* check for the characters now, otherwise they might be eaten by
* get_keystroke() */ * get_keystroke() */
out_flush(); out_flush();
@ -4505,6 +4487,9 @@ check_termcode(
key_name[0] = (int)KS_EXTRA; key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE; key_name[1] = (int)KE_IGNORE;
slen = i + 1; slen = i + 1;
# ifdef FEAT_EVAL
set_vim_var_string(VV_TERMU7RESP, tp, slen);
# endif
} }
else else
#endif #endif
@ -4530,6 +4515,8 @@ check_termcode(
if (tp[1 + (tp[0] != CSI)] == '>' && semicols == 2) if (tp[1 + (tp[0] != CSI)] == '>' && semicols == 2)
{ {
int need_flush = FALSE;
/* Only set 'ttymouse' automatically if it was not set /* Only set 'ttymouse' automatically if it was not set
* by the user already. */ * by the user already. */
if (!option_was_set((char_u *)"ttym")) if (!option_was_set((char_u *)"ttym"))
@ -4566,35 +4553,54 @@ check_termcode(
may_adjust_color_count(256); may_adjust_color_count(256);
} }
/* Detect terminals that set $TERM to something like
* "xterm-256colors" but are not fully xterm
* compatible. */
# ifdef MACOS # ifdef MACOS
/* Mac Terminal.app sends 1;95;0 */ /* Mac Terminal.app sends 1;95;0 */
if (col == 95 if (col == 95
&& STRNCMP(tp + extra - 2, "1;95;0c", 7) == 0) && STRNCMP(tp + extra - 2, "1;95;0c", 7) == 0)
{ is_not_xterm = TRUE;
/* Terminal.app sets $TERM to "xterm-256colors",
* but it's not fully xterm compatible. */
is_terminal_app = TRUE;
}
# endif # 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)
is_not_xterm = TRUE;
/* Only request the cursor style if t_SH and t_RS are /* Only request the cursor style if t_SH and t_RS are
* set. Not for Terminal.app, it can't handle t_RS, it * set. Not for Terminal.app, it can't handle t_RS, it
* echoes the characters to the screen. */ * echoes the characters to the screen. */
if (rcs_status == STATUS_GET if (rcs_status == STATUS_GET
# ifdef MACOS && !is_not_xterm
&& !is_terminal_app
# endif
&& *T_CSH != NUL && *T_CSH != NUL
&& *T_CRS != NUL) && *T_CRS != NUL)
{ {
LOG_TR("Sending cursor style request"); LOG_TR("Sending cursor style request");
out_str(T_CRS); out_str(T_CRS);
rcs_status = STATUS_SENT; rcs_status = STATUS_SENT;
out_flush(); need_flush = TRUE;
} }
/* Only request the cursor blink mode if t_RC set. Not
* for Gnome terminal, it can't handle t_RC, it
* echoes the characters to the screen. */
if (rbm_status == STATUS_GET
&& !is_not_xterm
&& *T_CRC != NUL)
{
LOG_TR("Sending cursor blink mode request");
out_str(T_CRC);
rbm_status = STATUS_SENT;
need_flush = TRUE;
}
if (need_flush)
out_flush();
} }
slen = i + 1;
# ifdef FEAT_EVAL # ifdef FEAT_EVAL
set_vim_var_string(VV_TERMRESPONSE, tp, i + 1); set_vim_var_string(VV_TERMRESPONSE, tp, slen);
# endif # endif
# ifdef FEAT_AUTOCMD # ifdef FEAT_AUTOCMD
apply_autocmds(EVENT_TERMRESPONSE, apply_autocmds(EVENT_TERMRESPONSE,
@ -4602,7 +4608,6 @@ check_termcode(
# endif # endif
key_name[0] = (int)KS_EXTRA; key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE; key_name[1] = (int)KE_IGNORE;
slen = i + 1;
} }
/* Check blinking cursor from xterm: /* Check blinking cursor from xterm:
@ -4626,6 +4631,9 @@ check_termcode(
key_name[0] = (int)KS_EXTRA; key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE; key_name[1] = (int)KE_IGNORE;
slen = i + 1; slen = i + 1;
# ifdef FEAT_EVAL
set_vim_var_string(VV_TERMBLINKRESP, tp, slen);
# endif
} }
/* /*
@ -4714,6 +4722,9 @@ check_termcode(
/* Sometimes the 0x07 is followed by 0x18, unclear /* Sometimes the 0x07 is followed by 0x18, unclear
* when this happens. */ * when this happens. */
++slen; ++slen;
# ifdef FEAT_EVAL
set_vim_var_string(VV_TERMRGBRESP, tp, slen);
# endif
break; break;
} }
if (i == len) if (i == len)
@ -4788,6 +4799,9 @@ check_termcode(
key_name[0] = (int)KS_EXTRA; key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE; key_name[1] = (int)KE_IGNORE;
slen = i + 1 + (tp[i] == ESC); slen = i + 1 + (tp[i] == ESC);
# ifdef FEAT_EVAL
set_vim_var_string(VV_TERMSTYLERESP, tp, slen);
# endif
} }
} }

View File

@ -44,10 +44,7 @@
* - add test for giving error for invalid 'termsize' value. * - add test for giving error for invalid 'termsize' value.
* - support minimal size when 'termsize' is "rows*cols". * - support minimal size when 'termsize' is "rows*cols".
* - support minimal size when 'termsize' is empty? * - support minimal size when 'termsize' is empty?
* - do not set bufhidden to "hide"? works like a buffer with changes.
* document that CTRL-W :hide can be used.
* - GUI: when using tabs, focus in terminal, click on tab does not work. * - GUI: when using tabs, focus in terminal, click on tab does not work.
* - When $HOME was set by Vim (MS-Windows), do not pass it to the job.
* - GUI: when 'confirm' is set and trying to exit Vim, dialog offers to save * - GUI: when 'confirm' is set and trying to exit Vim, dialog offers to save
* changes to "!shell". * changes to "!shell".
* (justrajdeep, 2017 Aug 22) * (justrajdeep, 2017 Aug 22)
@ -399,10 +396,6 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
* the job finished. */ * the job finished. */
curbuf->b_p_ma = FALSE; curbuf->b_p_ma = FALSE;
/* Set 'bufhidden' to "hide": allow closing the window. */
set_string_option_direct((char_u *)"bufhidden", -1,
(char_u *)"hide", OPT_FREE|OPT_LOCAL, 0);
set_term_and_win_size(term); set_term_and_win_size(term);
setup_job_options(opt, term->tl_rows, term->tl_cols); setup_job_options(opt, term->tl_rows, term->tl_cols);
@ -1288,8 +1281,8 @@ term_paste_register(int prev_c UNUSED)
WCHAR *ret = NULL; WCHAR *ret = NULL;
int length = 0; int length = 0;
MultiByteToWideChar_alloc(enc_codepage, 0, (char*)s, STRLEN(s), MultiByteToWideChar_alloc(enc_codepage, 0, (char *)s,
&ret, &length); (int)STRLEN(s), &ret, &length);
if (ret != NULL) if (ret != NULL)
{ {
WideCharToMultiByte_alloc(CP_UTF8, 0, WideCharToMultiByte_alloc(CP_UTF8, 0,
@ -1299,7 +1292,7 @@ term_paste_register(int prev_c UNUSED)
} }
#endif #endif
channel_send(curbuf->b_term->tl_job->jv_channel, PART_IN, channel_send(curbuf->b_term->tl_job->jv_channel, PART_IN,
s, STRLEN(s), NULL); s, (int)STRLEN(s), NULL);
#ifdef WIN3264 #ifdef WIN3264
if (tmp != s) if (tmp != s)
vim_free(s); vim_free(s);
@ -1858,7 +1851,7 @@ handle_settermprop(
int length = 0; int length = 0;
MultiByteToWideChar_alloc(CP_UTF8, 0, MultiByteToWideChar_alloc(CP_UTF8, 0,
(char*)value->string, STRLEN(value->string), (char*)value->string, (int)STRLEN(value->string),
&ret, &length); &ret, &length);
if (ret != NULL) if (ret != NULL)
{ {

View File

@ -50,7 +50,6 @@ SCRIPTS_ALL = \
test70.out \ test70.out \
test73.out \ test73.out \
test79.out \ test79.out \
test80.out \
test88.out \ test88.out \
test94.out \ test94.out \
test95.out \ test95.out \
@ -205,7 +204,8 @@ NEW_TESTS = test_arabic.res \
test_writefile.res \ test_writefile.res \
test_alot_latin.res \ test_alot_latin.res \
test_alot_utf8.res \ test_alot_utf8.res \
test_alot.res test_alot.res \
test_windows_home.res
# Explicit dependencies. # Explicit dependencies.

View File

@ -86,7 +86,7 @@ SCRIPT = test1.out test3.out test4.out test5.out \
test64.out \ test64.out \
test66.out test68.out test69.out \ test66.out test68.out test69.out \
test72.out \ test72.out \
test77a.out test78.out test79.out test80.out \ test77a.out test78.out test79.out \
test88.out \ test88.out \
test94.out \ test94.out \
test95.out test99.out \ test95.out test99.out \

View File

@ -1,201 +0,0 @@
Test for *sub-replace-special* and *sub-replace-expression* on substitute().
Test for submatch() on substitute().
Test for *:s%* on :substitute.
STARTTEST
:so small.vim
ENDTEST
TEST_1:
STARTTEST
:set magic
:set cpo&
:$put =\"\n\nTEST_1:\"
:$put =substitute('A', 'A', '&&', '')
:$put =substitute('B', 'B', '\&', '')
:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '')
:$put =substitute('D', 'D', 'd', '')
:$put =substitute('E', 'E', '~', '')
:$put =substitute('F', 'F', '\~', '')
:$put =substitute('G', 'G', '\ugg', '')
:$put =substitute('H', 'H', '\Uh\Eh', '')
:$put =substitute('I', 'I', '\lII', '')
:$put =substitute('J', 'J', '\LJ\EJ', '')
:$put =substitute('K', 'K', '\Uk\ek', '')
:$put =substitute('lLl', 'L', '
', '')
:$put =substitute('mMm', 'M', '\r', '')
:$put =substitute('nNn', 'N', '\
', '')
:$put =substitute('oOo', 'O', '\n', '')
:$put =substitute('pPp', 'P', '\b', '')
:$put =substitute('qQq', 'Q', '\t', '')
:$put =substitute('rRr', 'R', '\\', '')
:$put =substitute('sSs', 'S', '\c', '')
:$put =substitute('uUu', 'U', \"\n\", '')
:$put =substitute('vVv', 'V', \"\b\", '')
:$put =substitute('wWw', 'W', \"\\\", '')
:$put =substitute('xXx', 'X', \"\r\", '')
:$put =substitute('Y', 'Y', '\L\uyYy\l\EY', '')
:$put =substitute('Z', 'Z', '\U\lZzZ\u\Ez', '')
/^TEST_2
ENDTEST
TEST_2:
STARTTEST
:set nomagic
:set cpo&
:$put =\"\n\nTEST_2:\"
:$put =substitute('A', 'A', '&&', '')
:$put =substitute('B', 'B', '\&', '')
:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '')
:$put =substitute('D', 'D', 'd', '')
:$put =substitute('E', 'E', '~', '')
:$put =substitute('F', 'F', '\~', '')
:$put =substitute('G', 'G', '\ugg', '')
:$put =substitute('H', 'H', '\Uh\Eh', '')
:$put =substitute('I', 'I', '\lII', '')
:$put =substitute('J', 'J', '\LJ\EJ', '')
:$put =substitute('K', 'K', '\Uk\ek', '')
:$put =substitute('lLl', 'L', '
', '')
:$put =substitute('mMm', 'M', '\r', '')
:$put =substitute('nNn', 'N', '\
', '')
:$put =substitute('oOo', 'O', '\n', '')
:$put =substitute('pPp', 'P', '\b', '')
:$put =substitute('qQq', 'Q', '\t', '')
:$put =substitute('rRr', 'R', '\\', '')
:$put =substitute('sSs', 'S', '\c', '')
:$put =substitute('tTt', 'T', \"\r\", '')
:$put =substitute('uUu', 'U', \"\n\", '')
:$put =substitute('vVv', 'V', \"\b\", '')
:$put =substitute('wWw', 'W', \"\\\", '')
:$put =substitute('X', 'X', '\L\uxXx\l\EX', '')
:$put =substitute('Y', 'Y', '\U\lYyY\u\Ey', '')
/^TEST_3
ENDTEST
TEST_3:
STARTTEST
:set magic&
:set cpo&
:$put =\"\n\nTEST_3:\"
:let y = substitute('aAa', 'A', '\="\\"', '') | $put =y
:let y = substitute('bBb', 'B', '\="\\\\"', '') | $put =y
:let y = substitute('cCc', 'C', '\="
"', '') | $put =y
:let y = substitute('dDd', 'D', '\="\\
"', '') | $put =y
:let y = substitute('eEe', 'E', '\="\\\\
"', '') | $put =y
:let y = substitute('fFf', 'F', '\="\\r"', '') | $put =y
:let y = substitute('jJj', 'J', '\="\\n"', '') | $put =y
:let y = substitute('kKk', 'K', '\="\r"', '') | $put =y
:let y = substitute('lLl', 'L', '\="\n"', '') | $put =y
/^TEST_4
ENDTEST
TEST_4:
STARTTEST
:set magic&
:set cpo&
:$put =\"\n\nTEST_4:\"
:let y = substitute('aAa', 'A', '\=substitute(submatch(0), ".", "\\", "")', '') | $put =y
:let y = substitute('bBb', 'B', '\=substitute(submatch(0), ".", "\\\\", "")', '') | $put =y
:let y = substitute('cCc', 'C', '\=substitute(submatch(0), ".", "
", "")', '') | $put =y
:let y = substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\
", "")', '') | $put =y
:let y = substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\
", "")', '') | $put =y
:let y = substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', '') | $put =y
:let y = substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', '') | $put =y
:let y = substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', '') | $put =y
:let y = substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', '') | $put =y
/^TEST_5
ENDTEST
TEST_5:
STARTTEST
:set magic&
:set cpo&
:$put =\"\n\nTEST_5:\"
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)', '')
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')
/^TEST_6
ENDTEST
TEST_6:
STARTTEST
:set magic&
:$put =\"\n\nTEST_6:\"
:set cpo+=/
:$put =substitute('A', 'A', 'a', '')
:$put =substitute('B', 'B', '%', '')
:set cpo-=/
:$put =substitute('C', 'C', 'c', '')
:$put =substitute('D', 'D', '%', '')
/^TEST_7
ENDTEST
TEST_7:
STARTTEST
:set magic&
:set cpo&
:$put =\"\n\nTEST_7:\"
:$put =substitute('A
A', 'A.', '\=submatch(0)', '')
:$put =substitute(\"B\nB\", 'B.', '\=submatch(0)', '')
:$put =substitute(\"B\nB\", 'B.', '\=string(submatch(0, 1))', '')
:$put =substitute('-bb', '\zeb', 'a', 'g')
:$put =substitute('-bb', '\ze', 'c', 'g')
/^TEST_8
ENDTEST
TEST_8:
STARTTEST
:set magic&
:set cpo&
:$put =\"\n\nTEST_8:\"
:$put =',,X'
:s/\(^\|,\)\ze\(,\|X\)/\1N/g
:$put =',,Y'
:s/\(^\|,\)\ze\(,\|Y\)/\1N/gc
a:$put =',,Z'
:s/\(^\|,\)\ze\(,\|Z\)/\1N/gc
yy/^TEST_9:
ENDTEST
TEST_9:
STARTTEST
:set magic&
:set cpo&
:$put =\"\n\nTEST_9:\"
:$put ='xxx'
:s/x/X/gc
yyq/^TEST_10:
ENDTEST
TEST_10:
STARTTEST
:set magic&
:set cpo&
:$put =\"\n\nTEST_10:\"
:let y = substitute('123', '\zs', 'a', 'g') | $put =y
:let y = substitute('123', '\zs.', 'a', 'g') | $put =y
:let y = substitute('123', '.\zs', 'a', 'g') | $put =y
:let y = substitute('123', '\ze', 'a', 'g') | $put =y
:let y = substitute('123', '\ze.', 'a', 'g') | $put =y
:let y = substitute('123', '.\ze', 'a', 'g') | $put =y
:let y = substitute('123', '1\|\ze', 'a', 'g') | $put =y

View File

@ -1,131 +0,0 @@
Results of test72:
TEST_1:
AA
&
C123456789987654321
d
~
~
Gg
Hh
iI
jJ
Kk
l
l
m
m
n
n
o
o
pp
q q
r\r
scs
u
u
vv
w\w
x
x
YyyY
zZZz
TEST_2:
AA
&
C123456789987654321
d
~
~
Gg
Hh
iI
jJ
Kk
l
l
m
m
n
n
o
o
pp
q q
r\r
scs
t
t
u
u
vv
w\w
XxxX
yYYy
TEST_3:
a\a
b\\b
c
c
d\
d
e\\
e
f\rf
j\nj
k
k
l
l
TEST_4:
a\a
b\b
c
c
d
d
e\
e
f
f
j
j
k
k
l
l
TEST_5:
A123456789987654321
[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
TEST_6:
a
%
c
%
TEST_7:
A
A
B
B
['B
']B
-abab
c-cbcbc
TEST_8:

View File

@ -121,5 +121,36 @@ func Test_mksession_arglist()
argdel * argdel *
endfunc endfunc
func Test_mksession_one_buffer_two_windows()
edit Xtest1
new Xtest2
split
mksession! Xtest_mks.out
let lines = readfile('Xtest_mks.out')
let count1 = 0
let count2 = 0
let count2buf = 0
for line in lines
if line =~ 'edit \f*Xtest1$'
let count1 += 1
endif
if line =~ 'edit \f\{-}Xtest2'
let count2 += 1
endif
if line =~ 'buffer \f\{-}Xtest2'
let count2buf += 1
endif
endfor
call assert_equal(1, count1, 'Xtest1 count')
call assert_equal(2, count2, 'Xtest2 count')
call assert_equal(2, count2buf, 'Xtest2 buffer count')
close
bwipe!
!cp Xtest_mks.out /tmp
call delete('Xtest_mks.out')
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -1897,8 +1897,9 @@ func Xproperty_tests(cchar)
call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
let l1=g:Xgetlist({'nr':1,'all':1}) let l1=g:Xgetlist({'nr':1,'all':1})
let l2=g:Xgetlist({'nr':2,'all':1}) let l2=g:Xgetlist({'nr':2,'all':1})
let l1.nr=2 let save_id = l1.id
let l2.nr=1 let l1.id=l2.id
let l2.id=save_id
call g:Xsetlist([], 'r', l1) call g:Xsetlist([], 'r', l1)
call g:Xsetlist([], 'r', l2) call g:Xsetlist([], 'r', l2)
let newl1=g:Xgetlist({'nr':1,'all':1}) let newl1=g:Xgetlist({'nr':1,'all':1})
@ -2545,3 +2546,38 @@ func Test_get_list_from_text()
call XgetListFromText('c') call XgetListFromText('c')
call XgetListFromText('l') call XgetListFromText('l')
endfunc endfunc
" Tests for the quickfix list id
func Xqfid_tests(cchar)
call s:setup_commands(a:cchar)
call g:Xsetlist([], 'f')
call assert_equal({}, g:Xgetlist({'id':0}))
Xexpr ''
let start_id = g:Xgetlist({'id' : 0}).id
Xexpr '' | Xexpr ''
Xolder
call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
call assert_equal({}, g:Xgetlist({'id':0, 'nr':99}))
call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
call assert_equal({}, g:Xgetlist({'id':99, 'nr':0}))
call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0}))
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 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'}))
let qfid = g:Xgetlist({'id':0, 'nr':0})
call g:Xsetlist([], 'f')
call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0}))
endfunc
func Test_qf_id()
call Xqfid_tests('c')
call Xqfid_tests('l')
endfunc

View File

@ -114,3 +114,183 @@ func Test_substitute_repeat()
call feedkeys("Qsc\<CR>y", 'tx') call feedkeys("Qsc\<CR>y", 'tx')
bwipe! bwipe!
endfunc endfunc
" Test for *sub-replace-special* and *sub-replace-expression* on substitute().
func Test_sub_replace_1()
" Run the tests with 'magic' on
set magic
set cpo&
call assert_equal('AA', substitute('A', 'A', '&&', ''))
call assert_equal('&', substitute('B', 'B', '\&', ''))
call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
call assert_equal('d', substitute('D', 'D', 'd', ''))
call assert_equal('~', substitute('E', 'E', '~', ''))
call assert_equal('~', substitute('F', 'F', '\~', ''))
call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
call assert_equal('iI', substitute('I', 'I', '\lII', ''))
call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
call assert_equal("l\<C-V>\<C-M>l",
\ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
call assert_equal("n\<C-V>\<C-M>n",
\ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
call assert_equal("w\\w", substitute('wWw', 'W', "\\", ''))
call assert_equal("x\<C-M>x", substitute('xXx', 'X', "\r", ''))
call assert_equal("YyyY", substitute('Y', 'Y', '\L\uyYy\l\EY', ''))
call assert_equal("zZZz", substitute('Z', 'Z', '\U\lZzZ\u\Ez', ''))
endfunc
func Test_sub_replace_2()
" Run the tests with 'magic' off
set nomagic
set cpo&
call assert_equal('AA', substitute('A', 'A', '&&', ''))
call assert_equal('&', substitute('B', 'B', '\&', ''))
call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
call assert_equal('d', substitute('D', 'D', 'd', ''))
call assert_equal('~', substitute('E', 'E', '~', ''))
call assert_equal('~', substitute('F', 'F', '\~', ''))
call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
call assert_equal('iI', substitute('I', 'I', '\lII', ''))
call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
call assert_equal("l\<C-V>\<C-M>l",
\ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
call assert_equal("n\<C-V>\<C-M>n",
\ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
call assert_equal("t\<C-M>t", substitute('tTt', 'T', "\r", ''))
call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
call assert_equal('w\w', substitute('wWw', 'W', "\\", ''))
call assert_equal('XxxX', substitute('X', 'X', '\L\uxXx\l\EX', ''))
call assert_equal('yYYy', substitute('Y', 'Y', '\U\lYyY\u\Ey', ''))
endfunc
func Test_sub_replace_3()
set magic&
set cpo&
call assert_equal('a\a', substitute('aAa', 'A', '\="\\"', ''))
call assert_equal('b\\b', substitute('bBb', 'B', '\="\\\\"', ''))
call assert_equal("c\rc", substitute('cCc', 'C', "\\=\"\r\"", ''))
call assert_equal("d\\\rd", substitute('dDd', 'D', "\\=\"\\\\\r\"", ''))
call assert_equal("e\\\\\re", substitute('eEe', 'E', "\\=\"\\\\\\\\\r\"", ''))
call assert_equal('f\rf', substitute('fFf', 'F', '\="\\r"', ''))
call assert_equal('j\nj', substitute('jJj', 'J', '\="\\n"', ''))
call assert_equal("k\<C-M>k", substitute('kKk', 'K', '\="\r"', ''))
call assert_equal("l\nl", substitute('lLl', 'L', '\="\n"', ''))
endfunc
" Test for submatch() on substitute().
func Test_sub_replace_4()
set magic&
set cpo&
call assert_equal('a\a', substitute('aAa', 'A',
\ '\=substitute(submatch(0), ".", "\\", "")', ''))
call assert_equal('b\b', substitute('bBb', 'B',
\ '\=substitute(submatch(0), ".", "\\\\", "")', ''))
call assert_equal("c\<C-V>\<C-M>c", substitute('cCc', 'C', '\=substitute(submatch(0), ".", "\<C-V>\<C-M>", "")', ''))
call assert_equal("d\<C-V>\<C-M>d", substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\\<C-V>\<C-M>", "")', ''))
call assert_equal("e\\\<C-V>\<C-M>e", substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\\<C-V>\<C-M>", "")', ''))
call assert_equal("f\<C-M>f", substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', ''))
call assert_equal("j\nj", substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', ''))
call assert_equal("k\rk", substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', ''))
call assert_equal("l\nl", substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', ''))
endfunc
func Test_sub_replace_5()
set magic&
set cpo&
call assert_equal('A123456789987654321', substitute('A123456789',
\ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
\ '\=submatch(0) . submatch(9) . submatch(8) . ' .
\ 'submatch(7) . submatch(6) . submatch(5) . ' .
\ 'submatch(4) . submatch(3) . submatch(2) . submatch(1)',
\ ''))
call assert_equal("[['A123456789'], ['9'], ['8'], ['7'], ['6'], " .
\ "['5'], ['4'], ['3'], ['2'], ['1']]",
\ substitute('A123456789',
\ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
\ '\=string([submatch(0, 1), submatch(9, 1), ' .
\ 'submatch(8, 1), submatch(7, 1), submatch(6, 1), ' .
\ 'submatch(5, 1), submatch(4, 1), submatch(3, 1), ' .
\ 'submatch(2, 1), submatch(1, 1)])',
\ ''))
endfunc
func Test_sub_replace_6()
set magic&
set cpo+=/
call assert_equal('a', substitute('A', 'A', 'a', ''))
call assert_equal('%', substitute('B', 'B', '%', ''))
set cpo-=/
call assert_equal('c', substitute('C', 'C', 'c', ''))
call assert_equal('%', substitute('D', 'D', '%', ''))
endfunc
func Test_sub_replace_7()
set magic&
set cpo&
call assert_equal('AA', substitute('AA', 'A.', '\=submatch(0)', ''))
call assert_equal("B\nB", substitute("B\nB", 'B.', '\=submatch(0)', ''))
call assert_equal("['B\n']B", substitute("B\nB", 'B.', '\=string(submatch(0, 1))', ''))
call assert_equal('-abab', substitute('-bb', '\zeb', 'a', 'g'))
call assert_equal('c-cbcbc', substitute('-bb', '\ze', 'c', 'g'))
endfunc
" Test for *:s%* on :substitute.
func Test_sub_replace_8()
new
set magic&
set cpo&
$put =',,X'
s/\(^\|,\)\ze\(,\|X\)/\1N/g
call assert_equal('N,,NX', getline("$"))
$put =',,Y'
let cmd = ':s/\(^\|,\)\ze\(,\|Y\)/\1N/gc'
call feedkeys(cmd . "\<CR>a", "xt")
call assert_equal('N,,NY', getline("$"))
:$put =',,Z'
let cmd = ':s/\(^\|,\)\ze\(,\|Z\)/\1N/gc'
call feedkeys(cmd . "\<CR>yy", "xt")
call assert_equal('N,,NZ', getline("$"))
enew! | close
endfunc
func Test_sub_replace_9()
new
set magic&
set cpo&
$put ='xxx'
call feedkeys(":s/x/X/gc\<CR>yyq", "xt")
call assert_equal('XXx', getline("$"))
enew! | close
endfunc
func Test_sub_replace_10()
set magic&
set cpo&
call assert_equal('a1a2a3a', substitute('123', '\zs', 'a', 'g'))
call assert_equal('aaa', substitute('123', '\zs.', 'a', 'g'))
call assert_equal('1a2a3a', substitute('123', '.\zs', 'a', 'g'))
call assert_equal('a1a2a3a', substitute('123', '\ze', 'a', 'g'))
call assert_equal('a1a2a3', substitute('123', '\ze.', 'a', 'g'))
call assert_equal('aaa', substitute('123', '.\ze', 'a', 'g'))
call assert_equal('aa2a3a', substitute('123', '1\|\ze', 'a', 'g'))
call assert_equal('1aaa', substitute('123', '1\zs\|[23]', 'a', 'g'))
endfunc

View File

@ -84,6 +84,7 @@ endfunc
func Test_terminal_hide_buffer() func Test_terminal_hide_buffer()
let buf = Run_shell_in_terminal({}) let buf = Run_shell_in_terminal({})
setlocal bufhidden=hide
quit quit
for nr in range(1, winnr('$')) for nr in range(1, winnr('$'))
call assert_notequal(winbufnr(nr), buf) call assert_notequal(winbufnr(nr), buf)
@ -356,13 +357,13 @@ func Test_finish_open_close()
call assert_equal(1, winnr('$')) call assert_equal(1, winnr('$'))
exe 'terminal ++open ' . cmd exe 'terminal ++open ' . cmd
close close!
call WaitFor("winnr('$') == 2", waittime) call WaitFor("winnr('$') == 2", waittime)
call assert_equal(2, winnr('$')) call assert_equal(2, winnr('$'))
bwipe bwipe
call term_start(cmd, {'term_finish': 'open'}) call term_start(cmd, {'term_finish': 'open'})
close close!
call WaitFor("winnr('$') == 2", waittime) call WaitFor("winnr('$') == 2", waittime)
call assert_equal(2, winnr('$')) call assert_equal(2, winnr('$'))
bwipe bwipe
@ -385,7 +386,7 @@ func Test_finish_open_close()
call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:') call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:')
call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d'}) call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d'})
close close!
call WaitFor("winnr('$') == 2", waittime) call WaitFor("winnr('$') == 2", waittime)
call assert_equal(2, winnr('$')) call assert_equal(2, winnr('$'))
call assert_equal(4, winheight(0)) call assert_equal(4, winheight(0))
@ -429,6 +430,10 @@ func Test_zz_terminal_in_gui()
if !CanRunGui() if !CanRunGui()
return return
endif endif
" Ignore the "failed to create input context" error.
call test_ignore_error('E285:')
gui -f gui -f
call assert_equal(1, winnr('$')) call assert_equal(1, winnr('$'))

View File

@ -1,7 +1,7 @@
" Tests for 'virtualedit'. " Tests for 'virtualedit'.
func Test_yank_move_change() func Test_yank_move_change()
split new
call setline(1, [ call setline(1, [
\ "func foo() error {", \ "func foo() error {",
\ "\tif n, err := bar();", \ "\tif n, err := bar();",
@ -29,3 +29,15 @@ func Test_yank_move_change()
set virtualedit= set virtualedit=
set ts=8 set ts=8
endfunc endfunc
func Test_paste_end_of_line()
new
set virtualedit=all
call setline(1, ['456', '123'])
normal! gg0"ay$
exe "normal! 2G$lllA\<C-O>:normal! \"agP\r"
call assert_equal('123456', getline(2))
bwipe!
set virtualedit=
endfunc

View File

@ -0,0 +1,121 @@
" Test for $HOME on Windows.
if !has('win32')
finish
endif
let s:env = {}
func s:restore_env()
for i in keys(s:env)
exe 'let ' . i . '=s:env["' . i . '"]'
endfor
endfunc
func s:save_env(...)
for i in a:000
exe 'let s:env["' . i . '"]=' . i
endfor
endfunc
func s:unlet_env(...)
for i in a:000
exe 'let ' . i . '=""'
endfor
endfunc
func CheckHomeIsMissingFromSubprocessEnvironment()
silent! let out = system('set')
let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
call assert_equal(0, len(env))
endfunc
func CheckHomeIsInSubprocessEnvironment(exp)
silent! let out = system('set')
let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '')
call assert_equal(a:exp, home)
endfunc
func CheckHome(exp, ...)
call assert_equal(a:exp, $HOME)
call assert_equal(a:exp, expand('~', ':p'))
if !a:0
call CheckHomeIsMissingFromSubprocessEnvironment()
else
call CheckHomeIsInSubprocessEnvironment(a:1)
endif
endfunc
func Test_WindowsHome()
command! -nargs=* SaveEnv call <SID>save_env(<f-args>)
command! -nargs=* RestoreEnv call <SID>restore_env()
command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>)
set noshellslash
let save_home = $HOME
SaveEnv $USERPROFILE $HOMEDRIVE $HOMEPATH
try
" Normal behavior: use $HOMEDRIVE and $HOMEPATH, ignore $USERPROFILE
let $USERPROFILE = 'unused'
let $HOMEDRIVE = 'C:'
let $HOMEPATH = '\foobar'
let $HOME = '' " Force recomputing "homedir"
call CheckHome('C:\foobar')
" Same, but with $HOMEPATH not set
UnletEnv $HOMEPATH
let $HOME = '' " Force recomputing "homedir"
call CheckHome('C:\')
" Use $USERPROFILE if $HOMEPATH and $HOMEDRIVE are empty
UnletEnv $HOMEDRIVE $HOMEPATH
let $USERPROFILE = 'C:\foo'
let $HOME = '' " Force recomputing "homedir"
call CheckHome('C:\foo')
" If $HOME is set the others don't matter
let $HOME = 'C:\bar'
let $USERPROFILE = 'unused'
let $HOMEDRIVE = 'unused'
let $HOMEPATH = 'unused'
call CheckHome('C:\bar', 'C:\bar')
" If $HOME contains %USERPROFILE% it is expanded
let $USERPROFILE = 'C:\foo'
let $HOME = '%USERPROFILE%\bar'
let $HOMEDRIVE = 'unused'
let $HOMEPATH = 'unused'
call CheckHome('C:\foo\bar', '%USERPROFILE%\bar')
" Invalid $HOME is kept
let $USERPROFILE = 'C:\foo'
let $HOME = '%USERPROFILE'
let $HOMEDRIVE = 'unused'
let $HOMEPATH = 'unused'
call CheckHome('%USERPROFILE', '%USERPROFILE')
" %USERPROFILE% not at start of $HOME is not expanded
let $USERPROFILE = 'unused'
let $HOME = 'C:\%USERPROFILE%'
let $HOMEDRIVE = 'unused'
let $HOMEPATH = 'unused'
call CheckHome('C:\%USERPROFILE%', 'C:\%USERPROFILE%')
if has('channel')
RestoreEnv
let $HOME = save_home
let env = ''
let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}})
sleep 1
let env = filter(split(env, "\n"), 'v:val=="HOME"')
let home = len(env) == 0 ? "" : env[0]
call assert_equal('', home)
endif
finally
RestoreEnv
delcommand SaveEnv
delcommand RestoreEnv
delcommand UnletEnv
endtry
endfunc

View File

@ -769,6 +769,34 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1024,
/**/
1023,
/**/
1022,
/**/
1021,
/**/
1020,
/**/
1019,
/**/
1018,
/**/
1017,
/**/
1016,
/**/
1015,
/**/
1014,
/**/
1013,
/**/
1012,
/**/
1011,
/**/ /**/
1010, 1010,
/**/ /**/

View File

@ -2012,7 +2012,11 @@ typedef int sock_T;
#define VV_TYPE_NONE 78 #define VV_TYPE_NONE 78
#define VV_TYPE_JOB 79 #define VV_TYPE_JOB 79
#define VV_TYPE_CHANNEL 80 #define VV_TYPE_CHANNEL 80
#define VV_LEN 81 /* number of v: vars */ #define VV_TERMRGBRESP 81
#define VV_TERMU7RESP 82
#define VV_TERMSTYLERESP 83
#define VV_TERMBLINKRESP 84
#define VV_LEN 85 /* number of v: vars */
/* used for v_number in VAR_SPECIAL */ /* used for v_number in VAR_SPECIAL */
#define VVAL_FALSE 0L #define VVAL_FALSE 0L