Skip to content

Commit 8471e57

Browse files
committed
patch 8.1.1356: some text in heredoc assignment ends the text
Problem: Some text in heredoc assignment ends the text. (Ozaki Kiichi) Solution: Recognize "let v =<<" and skip until the end.
1 parent 16e9b85 commit 8471e57

3 files changed

Lines changed: 99 additions & 12 deletions

File tree

src/testdir/test_let.vim

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,28 @@ func Test_let_utf8_environment()
152152
call assert_equal('ĀĒĪŌŪあいうえお', $a)
153153
endfunc
154154

155+
func Test_let_heredoc_fails()
156+
call assert_fails('let v =<< marker', 'E991:')
157+
158+
let text =<< trim END
159+
func WrongSyntax()
160+
let v =<< that there
161+
endfunc
162+
END
163+
call writefile(text, 'XheredocFail')
164+
call assert_fails('source XheredocFail', 'E126:')
165+
call delete('XheredocFail')
166+
167+
let text =<< trim END
168+
func MissingEnd()
169+
let v =<< END
170+
endfunc
171+
END
172+
call writefile(text, 'XheredocWrong')
173+
call assert_fails('source XheredocWrong', 'E126:')
174+
call delete('XheredocWrong')
175+
endfunc
176+
155177
" Test for the setting a variable using the heredoc syntax
156178
func Test_let_heredoc()
157179
let var1 =<< END
@@ -193,15 +215,45 @@ END
193215
.
194216
call assert_equal([' Line1'], var1)
195217

196-
call assert_fails('let v =<< marker', 'E991:')
197-
call assert_fails('call WrongSyntax()', 'E488:')
198-
call assert_fails('call MissingEnd()', 'E990:')
218+
" ignore "endfunc"
219+
let var1 =<< END
220+
something
199221
endfunc
222+
END
223+
call assert_equal(['something', 'endfunc'], var1)
200224

201-
func WrongSyntax()
202-
let fail =<< that there
203-
endfunc
225+
" ignore "endfunc" with trim
226+
let var1 =<< trim END
227+
something
228+
endfunc
229+
END
230+
call assert_equal(['something', 'endfunc'], var1)
231+
232+
" ignore "python << xx"
233+
let var1 =<<END
234+
something
235+
python << xx
236+
END
237+
call assert_equal(['something', 'python << xx'], var1)
238+
239+
" ignore "python << xx" with trim
240+
let var1 =<< trim END
241+
something
242+
python << xx
243+
END
244+
call assert_equal(['something', 'python << xx'], var1)
204245

205-
func MissingEnd()
206-
let fail =<< END
246+
" ignore "append"
247+
let var1 =<<
248+
something
249+
app
250+
.
251+
call assert_equal(['something', 'app'], var1)
252+
253+
" ignore "append" with trim
254+
let var1 =<< trim
255+
something
256+
app
257+
.
258+
call assert_equal(['something', 'app'], var1)
207259
endfunc

src/userfunc.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,7 @@ ex_function(exarg_T *eap)
19791979
int indent;
19801980
int nesting;
19811981
char_u *skip_until = NULL;
1982+
char_u *trimmed = NULL;
19821983
dictitem_T *v;
19831984
funcdict_T fudi;
19841985
static int func_nr = 0; /* number for nameless function */
@@ -2303,10 +2304,18 @@ ex_function(exarg_T *eap)
23032304

23042305
if (skip_until != NULL)
23052306
{
2306-
/* between ":append" and "." and between ":python <<EOF" and "EOF"
2307-
* don't check for ":endfunc". */
2308-
if (STRCMP(theline, skip_until) == 0)
2309-
VIM_CLEAR(skip_until);
2307+
// Between ":append" and "." and between ":python <<EOF" and "EOF"
2308+
// don't check for ":endfunc".
2309+
if (trimmed == NULL
2310+
|| STRNCMP(theline, trimmed, STRLEN(trimmed)) == 0)
2311+
{
2312+
p = trimmed == NULL ? theline : theline + STRLEN(trimmed);
2313+
if (STRCMP(p, skip_until) == 0)
2314+
{
2315+
VIM_CLEAR(skip_until);
2316+
VIM_CLEAR(trimmed);
2317+
}
2318+
}
23102319
}
23112320
else
23122321
{
@@ -2406,6 +2415,30 @@ ex_function(exarg_T *eap)
24062415
else
24072416
skip_until = vim_strsave(p);
24082417
}
2418+
2419+
// Check for ":let v =<< [trim] EOF"
2420+
arg = skipwhite(skiptowhite(p));
2421+
arg = skipwhite(skiptowhite(arg));
2422+
if (arg[0] == '=' && arg[1] == '<' && arg[2] =='<'
2423+
&& ((p[0] == 'l'
2424+
&& p[1] == 'e'
2425+
&& (!ASCII_ISALNUM(p[2])
2426+
|| (p[2] == 't' && !ASCII_ISALNUM(p[3]))))))
2427+
{
2428+
// ":let v =<<" continues until a dot
2429+
p = skipwhite(arg + 3);
2430+
if (STRNCMP(p, "trim", 4) == 0)
2431+
{
2432+
// Ignore leading white space.
2433+
p = skipwhite(p + 4);
2434+
trimmed = vim_strnsave(theline,
2435+
(int)(skipwhite(theline) - theline));
2436+
}
2437+
if (*p == NUL)
2438+
skip_until = vim_strsave((char_u *)".");
2439+
else
2440+
skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p));
2441+
}
24092442
}
24102443

24112444
/* Add the line to the function. */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ static char *(features[]) =
767767

768768
static int included_patches[] =
769769
{ /* Add new patch number below this line */
770+
/**/
771+
1356,
770772
/**/
771773
1355,
772774
/**/

0 commit comments

Comments
 (0)