Merge #11211 from jbradaric/vim-8.1.1585

vim-patch:8.1.{1585,1625,1723,1729}
This commit is contained in:
Justin M. Keyes 2019-10-19 15:23:14 -07:00 committed by GitHub
commit 06a6828f01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 631 additions and 458 deletions

View File

@ -9779,27 +9779,37 @@ This does NOT work: >
Like above, but append/add/subtract the value for each
|List| item.
*:let=<<* *:let-heredoc* *E990* *E991*
*:let=<<* *:let-heredoc*
*E990* *E991* *E172* *E221*
:let {var-name} =<< [trim] {marker}
text...
text...
{marker}
Set internal variable {var-name} to a List containing
the lines of text bounded by the string {marker}.
{marker} must not contain white space.
{marker} cannot start with a lower case character.
The last line should end only with the {marker} string
without any other character. Watch out for white
space after {marker}!
If {marker} is not supplied, then "." is used as the
default marker.
Any white space characters in the lines of text are
preserved. If "trim" is specified before {marker},
then all the leading indentation exactly matching the
leading indentation before `let` is stripped from the
input lines and the line containing {marker}. Note
that the difference between space and tab matters
here.
Without "trim" any white space characters in the lines
of text are preserved. If "trim" is specified before
{marker}, then indentation is stripped so you can do: >
let text =<< trim END
if ok
echo 'done'
endif
END
< Results in: ["if ok", " echo 'done'", "endif"]
The marker must line up with "let" and the indentation
of the first line is removed from all the text lines.
Specifically: all the leading indentation exactly
matching the leading indentation of the first
non-empty text line is stripped from the input lines.
All leading indentation exactly matching the leading
indentation before `let` is stripped from the line
containing {marker}. Note that the difference between
space and tab matters here.
If {var-name} didn't exist yet, it is created.
Cannot be followed by another command, but can be

View File

@ -1521,7 +1521,9 @@ heredoc_get(exarg_T *eap, char_u *cmd)
{
char_u *marker;
char_u *p;
int indent_len = 0;
int marker_indent_len = 0;
int text_indent_len = 0;
char_u *text_indent = NULL;
if (eap->getline == NULL) {
EMSG(_("E991: cannot use =<< here"));
@ -1534,17 +1536,19 @@ heredoc_get(exarg_T *eap, char_u *cmd)
&& (cmd[4] == NUL || ascii_iswhite(cmd[4]))) {
cmd = skipwhite(cmd + 4);
// Trim the indentation from all the lines in the here document
// Trim the indentation from all the lines in the here document.
// The amount of indentation trimmed is the same as the indentation of
// the :let command line.
// the first line after the :let command line. To find the end marker
// the indent of the :let command line is trimmed.
p = *eap->cmdlinep;
while (ascii_iswhite(*p)) {
p++;
indent_len++;
marker_indent_len++;
}
text_indent_len = -1;
}
// The marker is the next word. Default marker is "."
// The marker is the next word.
if (*cmd != NUL && *cmd != '"') {
marker = skipwhite(cmd);
p = skiptowhite(marker);
@ -1553,34 +1557,59 @@ heredoc_get(exarg_T *eap, char_u *cmd)
return NULL;
}
*p = NUL;
if (islower(*marker)) {
EMSG(_("E221: Marker cannot start with lower case letter"));
return NULL;
}
} else {
marker = (char_u *)".";
EMSG(_("E172: Missing marker"));
return NULL;
}
list_T *l = tv_list_alloc(0);
for (;;) {
int i = 0;
int mi = 0;
int ti = 0;
char_u *theline = eap->getline(NUL, eap->cookie, 0, false);
if (theline != NULL && indent_len > 0) {
// trim the indent matching the first line
if (STRNCMP(theline, *eap->cmdlinep, indent_len) == 0) {
i = indent_len;
}
}
if (theline == NULL) {
EMSG2(_("E990: Missing end marker '%s'"), marker);
break;
}
if (STRCMP(marker, theline + i) == 0) {
// with "trim": skip the indent matching the :let line to find the
// marker
if (marker_indent_len > 0
&& STRNCMP(theline, *eap->cmdlinep, marker_indent_len) == 0) {
mi = marker_indent_len;
}
if (STRCMP(marker, theline + mi) == 0) {
xfree(theline);
break;
}
if (text_indent_len == -1 && *theline != NUL) {
// set the text indent from the first line.
p = theline;
text_indent_len = 0;
while (ascii_iswhite(*p)) {
p++;
text_indent_len++;
}
text_indent = vim_strnsave(theline, text_indent_len);
}
// with "trim": skip the indent matching the first line
if (text_indent != NULL) {
for (ti = 0; ti < text_indent_len; ti++) {
if (theline[ti] != text_indent[ti]) {
break;
}
}
}
tv_list_append_string(l, (char *)(theline + i), -1);
tv_list_append_string(l, (char *)(theline + ti), -1);
xfree(theline);
}
xfree(text_indent);
return l;
}
@ -21268,8 +21297,6 @@ void ex_function(exarg_T *eap)
bool overwrite = false;
int indent;
int nesting;
char_u *skip_until = NULL;
char_u *trimmed = NULL;
dictitem_T *v;
funcdict_T fudi;
static int func_nr = 0; /* number for nameless function */
@ -21277,7 +21304,11 @@ void ex_function(exarg_T *eap)
hashtab_T *ht;
int todo;
hashitem_T *hi;
int sourcing_lnum_off;
linenr_T sourcing_lnum_off;
linenr_T sourcing_lnum_top;
bool is_heredoc = false;
char_u *skip_until = NULL;
char_u *heredoc_trimmed = NULL;
bool show_block = false;
bool do_concat = true;
@ -21526,15 +21557,17 @@ void ex_function(exarg_T *eap)
cmdline_row = msg_row;
}
// Save the starting line number.
sourcing_lnum_top = sourcing_lnum;
indent = 2;
nesting = 0;
for (;; ) {
if (KeyTyped) {
msg_scroll = TRUE;
saved_wait_return = FALSE;
msg_scroll = true;
saved_wait_return = false;
}
need_wait_return = FALSE;
sourcing_lnum_off = sourcing_lnum;
need_wait_return = false;
if (line_arg != NULL) {
/* Use eap->arg, split up in parts by line breaks. */
@ -21567,21 +21600,36 @@ void ex_function(exarg_T *eap)
ui_ext_cmdline_block_append((size_t)indent, (const char *)theline);
}
/* Detect line continuation: sourcing_lnum increased more than one. */
if (sourcing_lnum > sourcing_lnum_off + 1)
sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1;
else
// Detect line continuation: sourcing_lnum increased more than one.
sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
if (sourcing_lnum < sourcing_lnum_off) {
sourcing_lnum_off -= sourcing_lnum;
} else {
sourcing_lnum_off = 0;
}
if (skip_until != NULL) {
// Between ":append" and "." and between ":python <<EOF" and "EOF"
// don't check for ":endfunc".
if (trimmed == NULL || STRNCMP(theline, trimmed, STRLEN(trimmed)) == 0) {
p = trimmed == NULL ? theline : theline + STRLEN(trimmed);
// Don't check for ":endfunc" between
// * ":append" and "."
// * ":python <<EOF" and "EOF"
// * ":let {var-name} =<< [trim] {marker}" and "{marker}"
if (heredoc_trimmed == NULL
|| (is_heredoc && skipwhite(theline) == theline)
|| STRNCMP(theline, heredoc_trimmed,
STRLEN(heredoc_trimmed)) == 0) {
if (heredoc_trimmed == NULL) {
p = theline;
} else if (is_heredoc) {
p = skipwhite(theline) == theline
? theline : theline + STRLEN(heredoc_trimmed);
} else {
p = theline + STRLEN(heredoc_trimmed);
}
if (STRCMP(p, skip_until) == 0) {
XFREE_CLEAR(skip_until);
XFREE_CLEAR(trimmed);
XFREE_CLEAR(heredoc_trimmed);
do_concat = true;
is_heredoc = false;
}
}
} else {
@ -21689,19 +21737,16 @@ void ex_function(exarg_T *eap)
&& ((p[0] == 'l' && p[1] == 'e'
&& (!ASCII_ISALNUM(p[2])
|| (p[2] == 't' && !ASCII_ISALNUM(p[3])))))) {
// ":let v =<<" continues until a dot
p = skipwhite(arg + 3);
if (STRNCMP(p, "trim", 4) == 0) {
// Ignore leading white space.
p = skipwhite(p + 4);
trimmed = vim_strnsave(theline, (int)(skipwhite(theline) - theline));
}
if (*p == NUL) {
skip_until = vim_strsave((char_u *)".");
} else {
skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p));
heredoc_trimmed = vim_strnsave(theline,
(int)(skipwhite(theline) - theline));
}
skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p));
do_concat = false;
is_heredoc = true;
}
}
@ -21872,7 +21917,8 @@ void ex_function(exarg_T *eap)
fp->uf_flags = flags;
fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx;
fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len - 1;
fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
goto ret_free;
erret:

View File

@ -97,10 +97,11 @@ typedef struct sn_prl_S {
struct source_cookie {
FILE *fp; ///< opened file for sourcing
char_u *nextline; ///< if not NULL: line that was read ahead
linenr_T sourcing_lnum; ///< line number of the source file
int finished; ///< ":finish" used
#if defined(USE_CRNL)
int fileformat; ///< EOL_UNKNOWN, EOL_UNIX or EOL_DOS
bool error; ///< true if LF found after CR-LF
bool error; ///< true if LF found after CR-LF
#endif
linenr_T breakpoint; ///< next line with breakpoint or zero
char_u *fname; ///< name of sourced file
@ -3124,6 +3125,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
#endif
cookie.nextline = NULL;
cookie.sourcing_lnum = 0;
cookie.finished = false;
// Check if this script has a breakpoint.
@ -3375,6 +3377,13 @@ void free_scriptnames(void)
}
# endif
linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie)
{
return fgetline == getsourceline
? ((struct source_cookie *)cookie)->sourcing_lnum
: sourcing_lnum;
}
/// Get one full line from a sourced file.
/// Called by do_cmdline() when it's called from do_source().
@ -3395,6 +3404,8 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
if (do_profiling == PROF_YES) {
script_line_end();
}
// Set the current sourcing line number.
sourcing_lnum = sp->sourcing_lnum + 1;
// Get current line. If there is a read-ahead line, use it, otherwise get
// one now.
if (sp->finished) {
@ -3404,7 +3415,7 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
} else {
line = sp->nextline;
sp->nextline = NULL;
sourcing_lnum++;
sp->sourcing_lnum++;
}
if (line != NULL && do_profiling == PROF_YES) {
script_line_start();
@ -3414,7 +3425,7 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
// contain the 'C' flag.
if (line != NULL && do_concat && (vim_strchr(p_cpo, CPO_CONCAT) == NULL)) {
// compensate for the one line read-ahead
sourcing_lnum--;
sp->sourcing_lnum--;
// Get the next line and concatenate it when it starts with a
// backslash. We always need to read the next line, keep it in
@ -3492,7 +3503,7 @@ static char_u *get_one_sourceline(struct source_cookie *sp)
ga_init(&ga, 1, 250);
// Loop until there is a finished line (or end-of-file).
sourcing_lnum++;
sp->sourcing_lnum++;
for (;; ) {
// make room to read at least 120 (more) characters
ga_grow(&ga, 120);
@ -3559,7 +3570,7 @@ retry:
// len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo
for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--) {}
if ((len & 1) != (c & 1)) { // escaped NL, read more
sourcing_lnum++;
sp->sourcing_lnum++;
continue;
}

View File

@ -19,23 +19,23 @@ func Test_cino_extern_c()
" Test for cino-E
let without_ind =<< trim [CODE]
#ifdef __cplusplus
extern "C" {
#endif
int func_a(void);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
int func_a(void);
#ifdef __cplusplus
}
#endif
[CODE]
let with_ind =<< trim [CODE]
#ifdef __cplusplus
extern "C" {
#endif
int func_a(void);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
int func_a(void);
#ifdef __cplusplus
}
#endif
[CODE]
new
setlocal cindent cinoptions=E0
@ -90,30 +90,30 @@ func Test_cindent_expr()
endfunc
setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction()
let testinput =<< trim [CODE]
var_a = something()
b = something()
var_a = something()
b = something()
[CODE]
call setline(1, testinput)
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
let expected =<< trim [CODE]
var_a = something();
b = something();
[CODE]
let expected =<< [CODE]
var_a = something();
b = something();
[CODE]
call assert_equal(expected, getline(1, '$'))
%d
let testinput =<< trim [CODE]
var_a = something()
b = something()
[CODE]
let testinput =<< [CODE]
var_a = something()
b = something()
[CODE]
call setline(1, testinput)
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
let expected =<< trim [CODE]
var_a = something();
b = something()
[CODE]
let expected =<< [CODE]
var_a = something();
b = something()
[CODE]
call assert_equal(expected, getline(1, '$'))
bw!
endfunc

View File

@ -26,27 +26,29 @@ func Test_Debugger()
endif
" Create a Vim script with some functions
call writefile([
\ 'func Foo()',
\ ' let var1 = 1',
\ ' let var2 = Bar(var1) + 9',
\ ' return var2',
\ 'endfunc',
\ 'func Bar(var)',
\ ' let var1 = 2 + a:var',
\ ' let var2 = Bazz(var1) + 4',
\ ' return var2',
\ 'endfunc',
\ 'func Bazz(var)',
\ ' try',
\ ' let var1 = 3 + a:var',
\ ' let var3 = "another var"',
\ ' let var3 = "value2"',
\ ' catch',
\ ' let var4 = "exception"',
\ ' endtry',
\ ' return var1',
\ 'endfunc'], 'Xtest.vim')
let lines =<< trim END
func Foo()
let var1 = 1
let var2 = Bar(var1) + 9
return var2
endfunc
func Bar(var)
let var1 = 2 + a:var
let var2 = Bazz(var1) + 4
return var2
endfunc
func Bazz(var)
try
let var1 = 3 + a:var
let var3 = "another var"
let var3 = "value2"
catch
let var4 = "exception"
endtry
return var1
endfunc
END
call writefile(lines, 'Xtest.vim')
" Start Vim in a terminal
let buf = RunVimInTerminal('-S Xtest.vim', {})
@ -294,11 +296,13 @@ func Test_Debugger()
" Tests for :breakadd file and :breakadd here
" Breakpoints should be set before sourcing the file
call writefile([
\ 'let var1 = 10',
\ 'let var2 = 20',
\ 'let var3 = 30',
\ 'let var4 = 40'], 'Xtest.vim')
let lines =<< trim END
let var1 = 10
let var2 = 20
let var3 = 30
let var4 = 40
END
call writefile(lines, 'Xtest.vim')
" Start Vim in a terminal
let buf = RunVimInTerminal('Xtest.vim', {})

View File

@ -16,12 +16,12 @@ endfunc
func Test_gD()
let lines =<< trim [CODE]
int x;
int func(void)
{
return x;
}
int x;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 1, 5)
@ -29,12 +29,12 @@ endfunc
func Test_gD_too()
let lines =<< trim [CODE]
Filename x;
int Filename
int func() {
Filename x;
return x;
int Filename
int func() {
Filename x;
return x;
[CODE]
call XTest_goto_decl('gD', lines, 1, 10)
@ -42,13 +42,13 @@ endfunc
func Test_gD_comment()
let lines =<< trim [CODE]
/* int x; */
int x;
int func(void)
{
return x;
}
/* int x; */
int x;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
@ -56,13 +56,13 @@ endfunc
func Test_gD_inline_comment()
let lines =<< trim [CODE]
int y /* , x */;
int x;
int func(void)
{
return x;
}
int y /* , x */;
int x;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
@ -70,13 +70,13 @@ endfunc
func Test_gD_string()
let lines =<< trim [CODE]
char *s[] = "x";
int x = 1;
int func(void)
{
return x;
}
char *s[] = "x";
int x = 1;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
@ -84,12 +84,12 @@ endfunc
func Test_gD_string_same_line()
let lines =<< trim [CODE]
char *s[] = "x", int x = 1;
int func(void)
{
return x;
}
char *s[] = "x", int x = 1;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 1, 22)
@ -97,13 +97,13 @@ endfunc
func Test_gD_char()
let lines =<< trim [CODE]
char c = 'x';
int x = 1;
int func(void)
{
return x;
}
char c = 'x';
int x = 1;
int func(void)
{
return x;
}
[CODE]
call XTest_goto_decl('gD', lines, 2, 5)
@ -111,12 +111,12 @@ endfunc
func Test_gd()
let lines =<< trim [CODE]
int x;
int func(int x)
{
return x;
}
int x;
int func(int x)
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 14)
@ -124,15 +124,15 @@ endfunc
func Test_gd_not_local()
let lines =<< trim [CODE]
int func1(void)
{
return x;
}
int func2(int x)
{
return x;
}
int func1(void)
{
return x;
}
int func2(int x)
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 10)
@ -140,11 +140,11 @@ endfunc
func Test_gd_kr_style()
let lines =<< trim [CODE]
int func(x)
int x;
{
return x;
}
int func(x)
int x;
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 2, 7)
@ -152,15 +152,15 @@ endfunc
func Test_gd_missing_braces()
let lines =<< trim [CODE]
def func1(a)
a + 1
end
a = 1
def func2()
return a
end
def func1(a)
a + 1
end
a = 1
def func2()
return a
end
[CODE]
call XTest_goto_decl('gd', lines, 1, 11)
@ -168,12 +168,12 @@ endfunc
func Test_gd_comment()
let lines =<< trim [CODE]
int func(void)
{
/* int x; */
int x;
return x;
}
int func(void)
{
/* int x; */
int x;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 4, 7)
@ -181,12 +181,12 @@ endfunc
func Test_gd_comment_in_string()
let lines =<< trim [CODE]
int func(void)
{
char *s ="//"; int x;
int x;
return x;
}
int func(void)
{
char *s ="//"; int x;
int x;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 22)
@ -195,12 +195,12 @@ endfunc
func Test_gd_string_in_comment()
set comments=
let lines =<< trim [CODE]
int func(void)
{
/* " */ int x;
int x;
return x;
}
int func(void)
{
/* " */ int x;
int x;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 15)
@ -209,10 +209,10 @@ endfunc
func Test_gd_inline_comment()
let lines =<< trim [CODE]
int func(/* x is an int */ int x)
{
return x;
}
int func(/* x is an int */ int x)
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 1, 32)
@ -220,10 +220,10 @@ endfunc
func Test_gd_inline_comment_only()
let lines =<< trim [CODE]
int func(void) /* one lonely x */
{
return x;
}
int func(void) /* one lonely x */
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 3, 10)
@ -231,16 +231,16 @@ endfunc
func Test_gd_inline_comment_body()
let lines =<< trim [CODE]
int func(void)
{
int y /* , x */;
for (/* int x = 0 */; y < 2; y++);
int x = 0;
return x;
}
int func(void)
{
int y /* , x */;
for (/* int x = 0 */; y < 2; y++);
int x = 0;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 7, 7)
@ -248,10 +248,10 @@ endfunc
func Test_gd_trailing_multiline_comment()
let lines =<< trim [CODE]
int func(int x) /* x is an int */
{
return x;
}
int func(int x) /* x is an int */
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 1, 14)
@ -259,10 +259,10 @@ endfunc
func Test_gd_trailing_comment()
let lines =<< trim [CODE]
int func(int x) // x is an int
{
return x;
}
int func(int x) // x is an int
{
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 1, 14)
@ -270,13 +270,13 @@ endfunc
func Test_gd_string()
let lines =<< trim [CODE]
int func(void)
{
char *s = "x";
int x = 1;
return x;
}
int func(void)
{
char *s = "x";
int x = 1;
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 4, 7)
@ -284,12 +284,12 @@ endfunc
func Test_gd_string_only()
let lines =<< trim [CODE]
int func(void)
{
char *s = "x";
return x;
}
int func(void)
{
char *s = "x";
return x;
}
[CODE]
call XTest_goto_decl('gd', lines, 5, 10)
@ -312,21 +312,21 @@ endfunc
func Test_gd_local_block()
let lines =<< trim [CODE]
int main()
{
char *a = "NOT NULL";
if(a)
{
char *b = a;
printf("%s\n", b);
char *a = "NOT NULL";
if(a)
{
char *b = a;
printf("%s\n", b);
}
else
{
char *b = "NULL";
return b;
}
return 0;
}
else
{
char *b = "NULL";
return b;
}
return 0;
}
[CODE]
call XTest_goto_decl('1gd', lines, 11, 11)

View File

@ -153,14 +153,37 @@ func Test_let_heredoc_fails()
call assert_fails('source XheredocFail', 'E126:')
call delete('XheredocFail')
let text =<< trim END
let text =<< trim CodeEnd
func MissingEnd()
let v =<< END
endfunc
END
CodeEnd
call writefile(text, 'XheredocWrong')
call assert_fails('source XheredocWrong', 'E126:')
call delete('XheredocWrong')
let text =<< trim TEXTend
let v =<< " comment
TEXTend
call writefile(text, 'XheredocNoMarker')
call assert_fails('source XheredocNoMarker', 'E172:')
call delete('XheredocNoMarker')
let text =<< trim TEXTend
let v =<< text
TEXTend
call writefile(text, 'XheredocBadMarker')
call assert_fails('source XheredocBadMarker', 'E221:')
call delete('XheredocBadMarker')
endfunc
func Test_let_heredoc_trim_no_indent_marker()
let text =<< trim END
Text
with
indent
END
call assert_equal(['Text', 'with', 'indent'], text)
endfunc
" Test for the setting a variable using the heredoc syntax
@ -173,9 +196,9 @@ END
call assert_equal(["Some sample text", "\tText with indent", " !@#$%^&*()-+_={}|[]\\~`:\";'<>?,./"], var1)
let var2 =<<
let var2 =<< XXX
Editor
.
XXX
call assert_equal(['Editor'], var2)
let var3 =<<END
@ -199,10 +222,18 @@ END
END
call assert_equal(['Line1', ' Line2', "\tLine3", ' END'], var1)
let var1 =<< trim
let var1 =<< trim !!!
Line1
line2
Line3
!!!
!!!
call assert_equal(['Line1', ' line2', "\tLine3", '!!!',], var1)
let var1 =<< trim XX
Line1
.
call assert_equal([' Line1'], var1)
XX
call assert_equal(['Line1'], var1)
" ignore "endfunc"
let var1 =<< END
@ -233,16 +264,16 @@ END
call assert_equal(['something', 'python << xx'], var1)
" ignore "append"
let var1 =<<
let var1 =<< E
something
app
.
E
call assert_equal(['something', 'app'], var1)
" ignore "append" with trim
let var1 =<< trim
let var1 =<< trim END
something
app
.
END
call assert_equal(['something', 'app'], var1)
endfunc

View File

@ -66,32 +66,32 @@ func Test_mksession_utf8()
mksession! test_mks.out
let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"')
let expected =<< trim [DATA]
normal! 016|
normal! 016|
normal! 016|
normal! 08|
normal! 08|
normal! 016|
normal! 016|
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 8 . '|'
normal! 08|
exe 'normal! ' . s:c . '|zs' . 8 . '|'
normal! 08|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 8 . '|'
normal! 08|
exe 'normal! ' . s:c . '|zs' . 8 . '|'
normal! 08|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
exe 'normal! ' . s:c . '|zs' . 16 . '|'
normal! 016|
[DATA]
call assert_equal(expected, li)

View File

@ -1564,34 +1564,34 @@ endfunc
fun! Test_normal29_brace()
" basic test for { and } movements
let text =<< trim [DATA]
A paragraph begins after each empty line, and also at each of a set of
paragraph macros, specified by the pairs of characters in the 'paragraphs'
option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
the first column). A section boundary is also a paragraph boundary.
Note that a blank line (only containing white space) is NOT a paragraph
boundary.
A paragraph begins after each empty line, and also at each of a set of
paragraph macros, specified by the pairs of characters in the 'paragraphs'
option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
the first column). A section boundary is also a paragraph boundary.
Note that a blank line (only containing white space) is NOT a paragraph
boundary.
Also note that this does not include a '{' or '}' in the first column. When
the '{' flag is in 'cpoptions' then '{' in the first column is used as a
paragraph boundary |posix|.
{
This is no paragraph
unless the '{' is set
in 'cpoptions'
}
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
Also note that this does not include a '{' or '}' in the first column. When
the '{' flag is in 'cpoptions' then '{' in the first column is used as a
paragraph boundary |posix|.
{
This is no paragraph
unless the '{' is set
in 'cpoptions'
}
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
new
@ -1600,17 +1600,17 @@ fun! Test_normal29_brace()
norm! 0d2}
let expected =<< trim [DATA]
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
.IP
The nroff macros IP separates a paragraph
That means, it must be a '.'
followed by IP
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
call assert_equal(expected, getline(1, '$'))
@ -1618,13 +1618,13 @@ fun! Test_normal29_brace()
norm! 0d}
let expected =<< trim [DATA]
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.NH
End of text here
[DATA]
call assert_equal(expected, getline(1, '$'))
@ -1633,11 +1633,11 @@ fun! Test_normal29_brace()
norm! d{
let expected =<< trim [DATA]
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
.LPIt does not matter, if afterwards some
more characters follow.
.SHAlso section boundaries from the nroff
macros terminate a paragraph. That means
a character like this:
[DATA]
call assert_equal(expected, getline(1, '$'))
@ -1645,8 +1645,8 @@ fun! Test_normal29_brace()
norm! d{
let expected =<< trim [DATA]
.LPIt does not matter, if afterwards some
more characters follow.
.LPIt does not matter, if afterwards some
more characters follow.
[DATA]
call assert_equal(expected, getline(1, '$'))
@ -1659,22 +1659,22 @@ fun! Test_normal29_brace()
" 1
" norm! 0d2}
" let expected =<< trim [DATA]
" {
" This is no paragraph
" unless the '{' is set
" in 'cpoptions'
" }
" .IP
" The nroff macros IP separates a paragraph
" That means, it must be a '.'
" followed by IP
" .LPIt does not matter, if afterwards some
" more characters follow.
" .SHAlso section boundaries from the nroff
" macros terminate a paragraph. That means
" a character like this:
" .NH
" End of text here
" {
" This is no paragraph
" unless the '{' is set
" in 'cpoptions'
" }
" .IP
" The nroff macros IP separates a paragraph
" That means, it must be a '.'
" followed by IP
" .LPIt does not matter, if afterwards some
" more characters follow.
" .SHAlso section boundaries from the nroff
" macros terminate a paragraph. That means
" a character like this:
" .NH
" End of text here
"
" [DATA]
" call assert_equal(expected, getline(1, '$'))
@ -1682,22 +1682,22 @@ fun! Test_normal29_brace()
" $
" norm! d}
" let expected =<< trim [DATA]
" {
" This is no paragraph
" unless the '{' is set
" in 'cpoptions'
" }
" .IP
" The nroff macros IP separates a paragraph
" That means, it must be a '.'
" followed by IP
" .LPIt does not matter, if afterwards some
" more characters follow.
" .SHAlso section boundaries from the nroff
" macros terminate a paragraph. That means
" a character like this:
" .NH
" End of text here
" {
" This is no paragraph
" unless the '{' is set
" in 'cpoptions'
" }
" .IP
" The nroff macros IP separates a paragraph
" That means, it must be a '.'
" followed by IP
" .LPIt does not matter, if afterwards some
" more characters follow.
" .SHAlso section boundaries from the nroff
" macros terminate a paragraph. That means
" a character like this:
" .NH
" End of text here
"
" [DATA]
" call assert_equal(expected, getline(1, '$'))
@ -1706,11 +1706,11 @@ fun! Test_normal29_brace()
" norm! d5}
"
" let expected =<< trim [DATA]
" {
" This is no paragraph
" unless the '{' is set
" in 'cpoptions'
" }
" {
" This is no paragraph
" unless the '{' is set
" in 'cpoptions'
" }
" [DATA]
" call assert_equal(expected, getline(1, '$'))

View File

@ -737,11 +737,12 @@ func Test_popup_position()
if !CanRunVimInTerminal()
return
endif
call writefile([
\ '123456789_123456789_123456789_a',
\ '123456789_123456789_123456789_b',
\ ' 123',
\ ], 'Xtest')
let lines =<< trim END
123456789_123456789_123456789_a
123456789_123456789_123456789_b
123
END
call writefile(lines, 'Xtest')
let buf = RunVimInTerminal('Xtest', {})
call term_sendkeys(buf, ":vsplit\<CR>")

View File

@ -312,13 +312,13 @@ endfunc
func Test_profile_file()
let lines =<< trim [CODE]
func! Foo()
endfunc
for i in range(10)
" a comment
func! Foo()
endfunc
for i in range(10)
" a comment
call Foo()
endfor
call Foo()
endfor
call Foo()
[CODE]
call writefile(lines, 'Xprofile_file.vim')

View File

@ -776,67 +776,67 @@ func Test_efm1()
endif
let l =<< trim [DATA]
"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
"Xtestfile", line 6 col 19; this is an error
gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
Xtestfile:9: parse error before `asd'
make: *** [vim] Error 1
in file "Xtestfile" linenr 10: there is an error
2 returned
"Xtestfile", line 11 col 1; this is an error
"Xtestfile", line 12 col 2; this is another error
"Xtestfile", line 14:10; this is an error in column 10
=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
"Xtestfile", linenr 16: yet another problem
Error in "Xtestfile" at line 17:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
^
Error in "Xtestfile" at line 18:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
.............^
Error in "Xtestfile" at line 19:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
--------------^
Error in "Xtestfile" at line 20:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
^
Does anyone know what is the problem and how to correction it?
"Xtestfile", line 21 col 9: What is the title of the quickfix window?
"Xtestfile", line 22 col 9: What is the title of the quickfix window?
"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
"Xtestfile", line 6 col 19; this is an error
gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
Xtestfile:9: parse error before `asd'
make: *** [vim] Error 1
in file "Xtestfile" linenr 10: there is an error
2 returned
"Xtestfile", line 11 col 1; this is an error
"Xtestfile", line 12 col 2; this is another error
"Xtestfile", line 14:10; this is an error in column 10
=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
"Xtestfile", linenr 16: yet another problem
Error in "Xtestfile" at line 17:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
^
Error in "Xtestfile" at line 18:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
.............^
Error in "Xtestfile" at line 19:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
--------------^
Error in "Xtestfile" at line 20:
x should be a dot
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
^
Does anyone know what is the problem and how to correction it?
"Xtestfile", line 21 col 9: What is the title of the quickfix window?
"Xtestfile", line 22 col 9: What is the title of the quickfix window?
[DATA]
call writefile(l, 'Xerrorfile1')
call writefile(l[:-2], 'Xerrorfile2')
let m =<< trim [DATA]
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
[DATA]
let m =<< [DATA]
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
[DATA]
call writefile(m, 'Xtestfile')
let save_efm = &efm
@ -1053,20 +1053,20 @@ func Test_efm2()
" Test for %P, %Q and %t format specifiers
let lines =<< trim [DATA]
[Xtestfile1]
(1,17) error: ';' missing
(21,2) warning: variable 'z' not defined
(67,3) error: end of file found before string ended
--
[Xtestfile2]
--
[Xtestfile3]
NEW compiler v1.1
(2,2) warning: variable 'x' not defined
(67,3) warning: 's' already defined
-
[Xtestfile1]
(1,17) error: ';' missing
(21,2) warning: variable 'z' not defined
(67,3) error: end of file found before string ended
--
[Xtestfile2]
--
[Xtestfile3]
NEW compiler v1.1
(2,2) warning: variable 'x' not defined
(67,3) warning: 's' already defined
--
[DATA]
set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
" To exercise the push/pop file functionality in quickfix, the test files
@ -1090,10 +1090,10 @@ func Test_efm2()
" Tests for %E, %C and %Z format specifiers
let lines =<< trim [DATA]
Error 275
line 42
column 3
' ' expected after '--'
Error 275
line 42
column 3
' ' expected after '--'
[DATA]
set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
@ -1107,8 +1107,8 @@ func Test_efm2()
" Test for %>
let lines =<< trim [DATA]
Error in line 147 of foo.c:
unknown variable 'i'
Error in line 147 of foo.c:
unknown variable 'i'
[DATA]
set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m

View File

@ -1409,6 +1409,76 @@ func Test_compound_assignment_operators()
let @/ = ''
endfunc
func Test_function_defined_line()
if has('gui_running')
" Can't catch the output of gvim.
return
endif
let lines =<< trim [CODE]
" F1
func F1()
" F2
func F2()
"
"
"
return
endfunc
" F3
execute "func F3()\n\n\n\nreturn\nendfunc"
" F4
execute "func F4()\n
\\n
\\n
\\n
\return\n
\endfunc"
endfunc
" F5
execute "func F5()\n\n\n\nreturn\nendfunc"
" F6
execute "func F6()\n
\\n
\\n
\\n
\return\n
\endfunc"
call F1()
verbose func F1
verbose func F2
verbose func F3
verbose func F4
verbose func F5
verbose func F6
qall!
[CODE]
call writefile(lines, 'Xtest.vim')
let res = system(v:progpath .. ' --clean -es -X -S Xtest.vim')
call assert_equal(0, v:shell_error)
let m = matchstr(res, 'function F1()[^[:print:]]*[[:print:]]*')
call assert_match(' line 2$', m)
let m = matchstr(res, 'function F2()[^[:print:]]*[[:print:]]*')
call assert_match(' line 4$', m)
let m = matchstr(res, 'function F3()[^[:print:]]*[[:print:]]*')
call assert_match(' line 11$', m)
let m = matchstr(res, 'function F4()[^[:print:]]*[[:print:]]*')
call assert_match(' line 13$', m)
let m = matchstr(res, 'function F5()[^[:print:]]*[[:print:]]*')
call assert_match(' line 21$', m)
let m = matchstr(res, 'function F6()[^[:print:]]*[[:print:]]*')
call assert_match(' line 23$', m)
call delete('Xtest.vim')
endfunc
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker