mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.2.1079: Vim9: no line break allowed in a while loop
Problem: Vim9: no line break allowed in a while loop.
Solution: Update stored loop lines when finding line breaks.
d5053d015a
Omit getline_peek(): Vim9 script only.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
parent
e99f28e57d
commit
4b84b2e2aa
@ -705,8 +705,11 @@ int eval_to_bool(char *arg, bool *error, exarg_T *eap, int skip)
|
|||||||
|
|
||||||
evalarg_T evalarg = {
|
evalarg_T evalarg = {
|
||||||
.eval_flags = skip ? 0 : EVAL_EVALUATE,
|
.eval_flags = skip ? 0 : EVAL_EVALUATE,
|
||||||
.eval_cookie = eap != NULL && eap->getline == getsourceline ? eap->cookie : NULL,
|
|
||||||
};
|
};
|
||||||
|
if (eap != NULL && getline_equal(eap->getline, eap->cookie, getsourceline)) {
|
||||||
|
evalarg.eval_getline = eap->getline;
|
||||||
|
evalarg.eval_cookie = eap->cookie;
|
||||||
|
}
|
||||||
|
|
||||||
if (skip) {
|
if (skip) {
|
||||||
emsg_skip++;
|
emsg_skip++;
|
||||||
@ -7461,8 +7464,11 @@ void ex_echo(exarg_T *eap)
|
|||||||
|
|
||||||
evalarg_T evalarg = {
|
evalarg_T evalarg = {
|
||||||
.eval_flags = eap->skip ? 0 : EVAL_EVALUATE,
|
.eval_flags = eap->skip ? 0 : EVAL_EVALUATE,
|
||||||
.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL,
|
|
||||||
};
|
};
|
||||||
|
if (getline_equal(eap->getline, eap->cookie, getsourceline)) {
|
||||||
|
evalarg.eval_getline = eap->getline;
|
||||||
|
evalarg.eval_cookie = eap->cookie;
|
||||||
|
}
|
||||||
|
|
||||||
if (eap->skip) {
|
if (eap->skip) {
|
||||||
emsg_skip++;
|
emsg_skip++;
|
||||||
|
@ -272,7 +272,8 @@ typedef struct {
|
|||||||
int eval_flags; ///< EVAL_ flag values below
|
int eval_flags; ///< EVAL_ flag values below
|
||||||
|
|
||||||
/// copied from exarg_T when "getline" is "getsourceline". Can be NULL.
|
/// copied from exarg_T when "getline" is "getsourceline". Can be NULL.
|
||||||
void *eval_cookie; // argument for getline()
|
LineGetter eval_getline;
|
||||||
|
void *eval_cookie; ///< argument for eval_getline()
|
||||||
|
|
||||||
/// pointer to the line obtained with getsourceline()
|
/// pointer to the line obtained with getsourceline()
|
||||||
char *eval_tofree;
|
char *eval_tofree;
|
||||||
@ -284,7 +285,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Passed to an eval() function to enable evaluation.
|
/// Passed to an eval() function to enable evaluation.
|
||||||
EXTERN evalarg_T EVALARG_EVALUATE INIT(= { EVAL_EVALUATE, NULL, NULL });
|
EXTERN evalarg_T EVALARG_EVALUATE INIT(= { EVAL_EVALUATE, NULL, NULL, NULL });
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "eval.h.generated.h"
|
# include "eval.h.generated.h"
|
||||||
|
@ -261,8 +261,11 @@ void ex_let(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
evalarg_T evalarg = {
|
evalarg_T evalarg = {
|
||||||
.eval_flags = eap->skip ? 0 : EVAL_EVALUATE,
|
.eval_flags = eap->skip ? 0 : EVAL_EVALUATE,
|
||||||
.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL,
|
|
||||||
};
|
};
|
||||||
|
if (getline_equal(eap->getline, eap->cookie, getsourceline)) {
|
||||||
|
evalarg.eval_getline = eap->getline;
|
||||||
|
evalarg.eval_cookie = eap->cookie;
|
||||||
|
}
|
||||||
int eval_res = eval0(expr, &rettv, eap, &evalarg);
|
int eval_res = eval0(expr, &rettv, eap, &evalarg);
|
||||||
if (eap->skip) {
|
if (eap->skip) {
|
||||||
emsg_skip--;
|
emsg_skip--;
|
||||||
|
@ -484,24 +484,6 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cstack.cs_looplevel > 0) {
|
|
||||||
// Inside a while/for loop we need to store the lines and use them
|
|
||||||
// again. Pass a different "fgetline" function to do_one_cmd()
|
|
||||||
// below, so that it stores lines in or reads them from
|
|
||||||
// "lines_ga". Makes it possible to define a function inside a
|
|
||||||
// while/for loop.
|
|
||||||
cmd_getline = get_loop_line;
|
|
||||||
cmd_cookie = (void *)&cmd_loop_cookie;
|
|
||||||
cmd_loop_cookie.lines_gap = &lines_ga;
|
|
||||||
cmd_loop_cookie.current_line = current_line;
|
|
||||||
cmd_loop_cookie.getline = fgetline;
|
|
||||||
cmd_loop_cookie.cookie = cookie;
|
|
||||||
cmd_loop_cookie.repeating = (current_line < lines_ga.ga_len);
|
|
||||||
} else {
|
|
||||||
cmd_getline = fgetline;
|
|
||||||
cmd_cookie = cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. If no line given, get an allocated line with fgetline().
|
// 2. If no line given, get an allocated line with fgetline().
|
||||||
if (next_cmdline == NULL) {
|
if (next_cmdline == NULL) {
|
||||||
// Need to set msg_didout for the first line after an ":if",
|
// Need to set msg_didout for the first line after an ":if",
|
||||||
@ -540,15 +522,37 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
|||||||
}
|
}
|
||||||
cmdline_copy = next_cmdline;
|
cmdline_copy = next_cmdline;
|
||||||
|
|
||||||
// Save the current line when inside a ":while" or ":for", and when
|
int current_line_before = 0;
|
||||||
// the command looks like a ":while" or ":for", because we may need it
|
// Inside a while/for loop, and when the command looks like a ":while"
|
||||||
// later. When there is a '|' and another command, it is stored
|
// or ":for", the line is stored, because we may need it later when
|
||||||
// separately, because we need to be able to jump back to it from an
|
// looping.
|
||||||
|
//
|
||||||
|
// When there is a '|' and another command, it is stored separately,
|
||||||
|
// because we need to be able to jump back to it from an
|
||||||
// :endwhile/:endfor.
|
// :endwhile/:endfor.
|
||||||
if (current_line == lines_ga.ga_len
|
//
|
||||||
&& (cstack.cs_looplevel || has_loop_cmd(next_cmdline))) {
|
// Pass a different "fgetline" function to do_one_cmd() below,
|
||||||
store_loop_line(&lines_ga, next_cmdline);
|
// that it stores lines in or reads them from "lines_ga". Makes it
|
||||||
|
// possible to define a function inside a while/for loop.
|
||||||
|
if ((cstack.cs_looplevel > 0 || has_loop_cmd(next_cmdline))) {
|
||||||
|
cmd_getline = get_loop_line;
|
||||||
|
cmd_cookie = (void *)&cmd_loop_cookie;
|
||||||
|
cmd_loop_cookie.lines_gap = &lines_ga;
|
||||||
|
cmd_loop_cookie.current_line = current_line;
|
||||||
|
cmd_loop_cookie.getline = fgetline;
|
||||||
|
cmd_loop_cookie.cookie = cookie;
|
||||||
|
cmd_loop_cookie.repeating = (current_line < lines_ga.ga_len);
|
||||||
|
|
||||||
|
// Save the current line when encountering it the first time.
|
||||||
|
if (current_line == lines_ga.ga_len) {
|
||||||
|
store_loop_line(&lines_ga, next_cmdline);
|
||||||
|
}
|
||||||
|
current_line_before = current_line;
|
||||||
|
} else {
|
||||||
|
cmd_getline = fgetline;
|
||||||
|
cmd_cookie = cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
did_endif = false;
|
did_endif = false;
|
||||||
|
|
||||||
if (count++ == 0) {
|
if (count++ == 0) {
|
||||||
@ -651,7 +655,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
|||||||
} else if (cstack.cs_lflags & CSL_HAD_LOOP) {
|
} else if (cstack.cs_lflags & CSL_HAD_LOOP) {
|
||||||
// For a ":while" or ":for" we need to remember the line number.
|
// For a ":while" or ":for" we need to remember the line number.
|
||||||
cstack.cs_lflags &= ~CSL_HAD_LOOP;
|
cstack.cs_lflags &= ~CSL_HAD_LOOP;
|
||||||
cstack.cs_line[cstack.cs_idx] = current_line - 1;
|
cstack.cs_line[cstack.cs_idx] = current_line_before;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user