mirror of
https://github.com/neovim/neovim.git
synced 2025-09-23 19:48:32 +00:00
vim-patch:8.2.4603: sourcing buffer lines is too complicated
Problem: Sourcing buffer lines is too complicated. Solution: Simplify the code. Make it possible to source Vim9 script lines. (Yegappan Lakshmanan, closes vim/vim#9974)85b43c6cb7
This commit changes the behavior of sourcing buffer lines to always have a script ID, although sourcing the same buffer always produces the same script ID. vim-patch:9.1.0372: Calling CLEAR_FIELD() on the same struct twice Problem: Calling CLEAR_FIELD() on the same struct twice. Solution: Remove the second CLEAR_FIELD(). Move the assignment of cookie.sourceing_lnum (zeertzjq). closes: vim/vim#14627f68517c167
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
@@ -1461,19 +1461,12 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name
|
||||
}
|
||||
}
|
||||
|
||||
void nlua_source_str(const char *code, char *name)
|
||||
void nlua_exec_ga(garray_T *ga, char *name)
|
||||
{
|
||||
const sctx_T save_current_sctx = current_sctx;
|
||||
current_sctx.sc_sid = SID_STR;
|
||||
current_sctx.sc_seq = 0;
|
||||
current_sctx.sc_lnum = 0;
|
||||
estack_push(ETYPE_SCRIPT, name, 0);
|
||||
|
||||
char *code = ga_concat_strings_sep(ga, "\n");
|
||||
size_t len = strlen(code);
|
||||
nlua_typval_exec(code, len, name, NULL, 0, false, NULL);
|
||||
|
||||
estack_pop();
|
||||
current_sctx = save_current_sctx;
|
||||
xfree(code);
|
||||
}
|
||||
|
||||
/// Call a LuaCallable given some typvals
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/cmdexpand_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/ex_cmds_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/garray_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/macros_defs.h"
|
||||
#include "nvim/types_defs.h"
|
||||
#include "nvim/usercmd.h" // IWYU pragma: keep
|
||||
|
@@ -75,7 +75,10 @@ typedef struct {
|
||||
FILE *fp; ///< opened file for sourcing
|
||||
char *nextline; ///< if not NULL: line that was read ahead
|
||||
linenr_T sourcing_lnum; ///< line number of the source file
|
||||
int finished; ///< ":finish" used
|
||||
bool finished; ///< ":finish" used
|
||||
bool source_from_buf_or_str; ///< true if sourcing from a buffer or string
|
||||
int buf_lnum; ///< line number in the buffer or string
|
||||
garray_T buflines; ///< lines in the buffer or string
|
||||
#ifdef USE_CRNL
|
||||
int fileformat; ///< EOL_UNKNOWN, EOL_UNIX or EOL_DOS
|
||||
bool error; ///< true if LF found after CR-LF
|
||||
@@ -1947,42 +1950,6 @@ static bool concat_continued_line(garray_T *const ga, const int init_growsize, c
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *buf;
|
||||
size_t offset;
|
||||
} GetStrLineCookie;
|
||||
|
||||
/// Get one full line from a sourced string (in-memory, no file).
|
||||
/// Called by do_cmdline() when it's called from do_source_str().
|
||||
///
|
||||
/// @return pointer to allocated line, or NULL for end-of-file or
|
||||
/// some error.
|
||||
static char *get_str_line(int c, void *cookie, int indent, bool do_concat)
|
||||
{
|
||||
GetStrLineCookie *p = cookie;
|
||||
if (strlen(p->buf) <= p->offset) {
|
||||
return NULL;
|
||||
}
|
||||
const char *line = p->buf + p->offset;
|
||||
const char *eol = skip_to_newline(line);
|
||||
garray_T ga;
|
||||
ga_init(&ga, sizeof(char), 400);
|
||||
ga_concat_len(&ga, line, (size_t)(eol - line));
|
||||
if (do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL) {
|
||||
while (eol[0] != NUL) {
|
||||
line = eol + 1;
|
||||
const char *const next_eol = skip_to_newline(line);
|
||||
if (!concat_continued_line(&ga, 400, line, (size_t)(next_eol - line))) {
|
||||
break;
|
||||
}
|
||||
eol = next_eol;
|
||||
}
|
||||
}
|
||||
ga_append(&ga, NUL);
|
||||
p->offset = (size_t)(eol - p->buf) + 1;
|
||||
return ga.ga_data;
|
||||
}
|
||||
|
||||
/// Create a new script item and allocate script-local vars. @see new_script_vars
|
||||
///
|
||||
/// @param name File name of the script. NULL for anonymous :source.
|
||||
@@ -1990,6 +1957,7 @@ static char *get_str_line(int c, void *cookie, int indent, bool do_concat)
|
||||
///
|
||||
/// @return pointer to the created script item.
|
||||
scriptitem_T *new_script_item(char *const name, scid_T *const sid_out)
|
||||
FUNC_ATTR_NONNULL_RET
|
||||
{
|
||||
static scid_T last_current_SID = 0;
|
||||
const scid_T sid = ++last_current_SID;
|
||||
@@ -2012,99 +1980,97 @@ scriptitem_T *new_script_item(char *const name, scid_T *const sid_out)
|
||||
return SCRIPT_ITEM(sid);
|
||||
}
|
||||
|
||||
static int source_using_linegetter(void *cookie, LineGetter fgetline, const char *traceback_name)
|
||||
/// Initialization for sourcing lines from the current buffer. Reads all the
|
||||
/// lines from the buffer and stores it in the cookie grow array.
|
||||
/// Returns a pointer to the name ":source buffer=<n>" on success and NULL on failure.
|
||||
static char *do_source_buffer_init(source_cookie_T *sp, const exarg_T *eap, bool ex_lua)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
char *save_sourcing_name = SOURCING_NAME;
|
||||
linenr_T save_sourcing_lnum = SOURCING_LNUM;
|
||||
char sourcing_name_buf[256];
|
||||
char *sname;
|
||||
if (save_sourcing_name == NULL) {
|
||||
sname = (char *)traceback_name;
|
||||
} else {
|
||||
snprintf(sourcing_name_buf, sizeof(sourcing_name_buf),
|
||||
"%s called at %s:%" PRIdLINENR, traceback_name, save_sourcing_name,
|
||||
save_sourcing_lnum);
|
||||
sname = sourcing_name_buf;
|
||||
if (curbuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
estack_push(ETYPE_SCRIPT, sname, 0);
|
||||
|
||||
const sctx_T save_current_sctx = current_sctx;
|
||||
if (!script_is_lua(current_sctx.sc_sid)) {
|
||||
current_sctx.sc_sid = SID_STR;
|
||||
if (ex_lua) {
|
||||
// Use ":{range}lua buffer=<num>" as the script name
|
||||
snprintf(IObuff, IOSIZE, ":{range}lua buffer=%d", curbuf->b_fnum);
|
||||
} else {
|
||||
// Use ":source buffer=<num>" as the script name
|
||||
snprintf(IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum);
|
||||
}
|
||||
current_sctx.sc_seq = 0;
|
||||
current_sctx.sc_lnum = save_sourcing_lnum;
|
||||
funccal_entry_T entry;
|
||||
save_funccal(&entry);
|
||||
int retval = do_cmdline(NULL, fgetline, cookie,
|
||||
DOCMD_VERBOSE | DOCMD_NOWAIT | DOCMD_REPEAT);
|
||||
estack_pop();
|
||||
current_sctx = save_current_sctx;
|
||||
restore_funccal();
|
||||
return retval;
|
||||
char *fname = xstrdup(IObuff);
|
||||
|
||||
ga_init(&sp->buflines, sizeof(char *), 100);
|
||||
// Copy the lines from the buffer into a grow array
|
||||
for (linenr_T curr_lnum = eap->line1; curr_lnum <= eap->line2; curr_lnum++) {
|
||||
GA_APPEND(char *, &sp->buflines, xstrdup(ml_get(curr_lnum)));
|
||||
}
|
||||
sp->buf_lnum = 0;
|
||||
sp->source_from_buf_or_str = true;
|
||||
// When sourcing a range of lines from a buffer, use buffer line number.
|
||||
sp->sourcing_lnum = eap->line1 - 1;
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
/// Initialization for sourcing lines from a string. Reads all the
|
||||
/// lines from the string and stores it in the cookie grow array.
|
||||
static void do_source_str_init(source_cookie_T *sp, const char *str)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
ga_init(&sp->buflines, sizeof(char *), 100);
|
||||
// Copy the lines from the string into a grow array
|
||||
while (*str != NUL) {
|
||||
const char *eol = skip_to_newline(str);
|
||||
GA_APPEND(char *, &sp->buflines, xmemdupz(str, (size_t)(eol - str)));
|
||||
str = eol + (*eol != NUL);
|
||||
}
|
||||
sp->buf_lnum = 0;
|
||||
sp->source_from_buf_or_str = true;
|
||||
}
|
||||
|
||||
void cmd_source_buffer(const exarg_T *const eap, bool ex_lua)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
if (curbuf == NULL) {
|
||||
return;
|
||||
}
|
||||
garray_T ga;
|
||||
ga_init(&ga, sizeof(char), 400);
|
||||
const linenr_T final_lnum = eap->line2;
|
||||
// Copy the contents to be executed.
|
||||
for (linenr_T curr_lnum = eap->line1; curr_lnum <= final_lnum; curr_lnum++) {
|
||||
// Adjust growsize to current length to speed up concatenating many lines.
|
||||
if (ga.ga_len > 400) {
|
||||
ga_set_growsize(&ga, MIN(ga.ga_len, 8000));
|
||||
}
|
||||
ga_concat(&ga, ml_get(curr_lnum));
|
||||
ga_append(&ga, NL);
|
||||
}
|
||||
((char *)ga.ga_data)[ga.ga_len - 1] = NUL;
|
||||
if (ex_lua || strequal(curbuf->b_p_ft, "lua")
|
||||
|| (curbuf->b_fname && path_with_extension(curbuf->b_fname, "lua"))) {
|
||||
char *name = ex_lua ? ":{range}lua" : ":source (no file)";
|
||||
nlua_source_str(ga.ga_data, name);
|
||||
} else {
|
||||
const GetStrLineCookie cookie = {
|
||||
.buf = ga.ga_data,
|
||||
.offset = 0,
|
||||
};
|
||||
source_using_linegetter((void *)&cookie, get_str_line, ":source (no file)");
|
||||
}
|
||||
ga_clear(&ga);
|
||||
do_source_ext(NULL, false, DOSO_NONE, NULL, eap, ex_lua, NULL);
|
||||
}
|
||||
|
||||
/// Executes lines in `src` as Ex commands.
|
||||
/// Executes lines in `str` as Ex commands.
|
||||
///
|
||||
/// @see do_source()
|
||||
int do_source_str(const char *cmd, const char *traceback_name)
|
||||
/// @see do_source_ext()
|
||||
int do_source_str(const char *str, char *traceback_name)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
GetStrLineCookie cookie = {
|
||||
.buf = (char *)cmd,
|
||||
.offset = 0,
|
||||
};
|
||||
return source_using_linegetter((void *)&cookie, get_str_line, traceback_name);
|
||||
char *const sourcing_name = SOURCING_NAME;
|
||||
const linenr_T sourcing_lnum = SOURCING_LNUM;
|
||||
char sname_buf[256];
|
||||
if (sourcing_name != NULL) {
|
||||
snprintf(sname_buf, sizeof(sname_buf), "%s called at %s:%" PRIdLINENR,
|
||||
traceback_name, sourcing_name, sourcing_lnum);
|
||||
traceback_name = sname_buf;
|
||||
}
|
||||
return do_source_ext(traceback_name, false, DOSO_NONE, NULL, NULL, false, str);
|
||||
}
|
||||
|
||||
/// When fname is a 'lua' file nlua_exec_file() is invoked to source it.
|
||||
/// When fname is a .lua file nlua_exec_file() is invoked to source it.
|
||||
/// Otherwise reads the file `fname` and executes its lines as Ex commands.
|
||||
///
|
||||
/// This function may be called recursively!
|
||||
///
|
||||
/// @see do_source_str
|
||||
///
|
||||
/// @param fname
|
||||
/// @param fname if NULL, source from the current buffer
|
||||
/// @param check_other check for .vimrc and _vimrc
|
||||
/// @param is_vimrc DOSO_ value
|
||||
/// @param ret_sid if not NULL and we loaded the script before, don't load it again
|
||||
/// @param eap used when sourcing lines from a buffer instead of a file
|
||||
/// @param str if not NULL, source from the given string
|
||||
///
|
||||
/// @return FAIL if file could not be opened, OK otherwise
|
||||
///
|
||||
/// If a scriptitem_T was found or created "*ret_sid" is set to the SID.
|
||||
int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
static int do_source_ext(char *const fname, const bool check_other, const int is_vimrc,
|
||||
int *const ret_sid, const exarg_T *const eap, const bool ex_lua,
|
||||
const char *const str)
|
||||
{
|
||||
source_cookie_T cookie;
|
||||
uint8_t *firstline = NULL;
|
||||
@@ -2114,22 +2080,36 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
proftime_T wait_start;
|
||||
bool trigger_source_post = false;
|
||||
|
||||
char *p = expand_env_save(fname);
|
||||
if (p == NULL) {
|
||||
return retval;
|
||||
}
|
||||
char *fname_exp = fix_fname(p);
|
||||
xfree(p);
|
||||
if (fname_exp == NULL) {
|
||||
return retval;
|
||||
}
|
||||
if (os_isdir(fname_exp)) {
|
||||
smsg(0, _("Cannot source a directory: \"%s\""), fname);
|
||||
goto theend;
|
||||
CLEAR_FIELD(cookie);
|
||||
char *fname_exp = NULL;
|
||||
if (fname == NULL) {
|
||||
assert(str == NULL);
|
||||
// sourcing lines from a buffer
|
||||
fname_exp = do_source_buffer_init(&cookie, eap, ex_lua);
|
||||
if (fname_exp == NULL) {
|
||||
return FAIL;
|
||||
}
|
||||
} else if (str != NULL) {
|
||||
do_source_str_init(&cookie, str);
|
||||
fname_exp = xstrdup(fname);
|
||||
} else {
|
||||
char *p = expand_env_save(fname);
|
||||
if (p == NULL) {
|
||||
return retval;
|
||||
}
|
||||
fname_exp = fix_fname(p);
|
||||
xfree(p);
|
||||
if (fname_exp == NULL) {
|
||||
return retval;
|
||||
}
|
||||
if (os_isdir(fname_exp)) {
|
||||
smsg(0, _("Cannot source a directory: \"%s\""), fname);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
|
||||
// See if we loaded this script before.
|
||||
int sid = find_script_by_name(fname_exp);
|
||||
int sid = str != NULL ? SID_STR : find_script_by_name(fname_exp);
|
||||
if (sid > 0 && ret_sid != NULL) {
|
||||
// Already loaded and no need to load again, return here.
|
||||
*ret_sid = sid;
|
||||
@@ -2137,26 +2117,30 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
goto theend;
|
||||
}
|
||||
|
||||
// Apply SourceCmd autocommands, they should get the file and source it.
|
||||
if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
|
||||
&& apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
|
||||
false, curbuf)) {
|
||||
retval = aborting() ? FAIL : OK;
|
||||
if (retval == OK) {
|
||||
// Apply SourcePost autocommands.
|
||||
apply_autocmds(EVENT_SOURCEPOST, fname_exp, fname_exp, false, curbuf);
|
||||
if (str == NULL) {
|
||||
// Apply SourceCmd autocommands, they should get the file and source it.
|
||||
if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
|
||||
&& apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
|
||||
false, curbuf)) {
|
||||
retval = aborting() ? FAIL : OK;
|
||||
if (retval == OK) {
|
||||
// Apply SourcePost autocommands.
|
||||
apply_autocmds(EVENT_SOURCEPOST, fname_exp, fname_exp, false, curbuf);
|
||||
}
|
||||
goto theend;
|
||||
}
|
||||
goto theend;
|
||||
|
||||
// Apply SourcePre autocommands, they may get the file.
|
||||
apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, false, curbuf);
|
||||
}
|
||||
|
||||
// Apply SourcePre autocommands, they may get the file.
|
||||
apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, false, curbuf);
|
||||
|
||||
cookie.fp = fopen_noinh_readbin(fname_exp);
|
||||
if (!cookie.source_from_buf_or_str) {
|
||||
cookie.fp = fopen_noinh_readbin(fname_exp);
|
||||
}
|
||||
if (cookie.fp == NULL && check_other) {
|
||||
// Try again, replacing file name ".nvimrc" by "_nvimrc" or vice versa,
|
||||
// and ".exrc" by "_exrc" or vice versa.
|
||||
p = path_tail(fname_exp);
|
||||
char *p = path_tail(fname_exp);
|
||||
if ((*p == '.' || *p == '_')
|
||||
&& (STRICMP(p + 1, "nvimrc") == 0 || STRICMP(p + 1, "exrc") == 0)) {
|
||||
*p = (*p == '_') ? '.' : '_';
|
||||
@@ -2164,7 +2148,7 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie.fp == NULL) {
|
||||
if (cookie.fp == NULL && !cookie.source_from_buf_or_str) {
|
||||
if (p_verbose > 1) {
|
||||
verbose_enter();
|
||||
if (SOURCING_NAME == NULL) {
|
||||
@@ -2201,13 +2185,8 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
} else {
|
||||
cookie.fileformat = EOL_UNKNOWN;
|
||||
}
|
||||
cookie.error = false;
|
||||
#endif
|
||||
|
||||
cookie.nextline = NULL;
|
||||
cookie.sourcing_lnum = 0;
|
||||
cookie.finished = false;
|
||||
|
||||
// Check if this script has a breakpoint.
|
||||
cookie.breakpoint = dbg_find_breakpoint(true, fname_exp, 0);
|
||||
cookie.fname = fname_exp;
|
||||
@@ -2236,15 +2215,13 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
|
||||
const sctx_T save_current_sctx = current_sctx;
|
||||
|
||||
current_sctx.sc_lnum = 0;
|
||||
|
||||
// Always use a new sequence number.
|
||||
current_sctx.sc_seq = ++last_current_SID_seq;
|
||||
|
||||
if (sid > 0) {
|
||||
// loading the same script again
|
||||
si = SCRIPT_ITEM(sid);
|
||||
} else {
|
||||
} else if (str == NULL) {
|
||||
// It's new, generate a new SID.
|
||||
si = new_script_item(fname_exp, &sid);
|
||||
si->sn_lua = path_with_extension(fname_exp, "lua");
|
||||
@@ -2253,12 +2230,20 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
*ret_sid = sid;
|
||||
}
|
||||
}
|
||||
current_sctx.sc_sid = sid;
|
||||
// Sourcing a string doesn't allocate a script item immediately.
|
||||
assert((si != NULL) == (str == NULL));
|
||||
|
||||
// Don't change sc_sid to SID_STR when sourcing a string from a Lua script,
|
||||
// as keeping the current sc_sid allows more useful :verbose messages.
|
||||
if (str == NULL || !script_is_lua(current_sctx.sc_sid)) {
|
||||
current_sctx.sc_sid = sid;
|
||||
current_sctx.sc_lnum = 0;
|
||||
}
|
||||
|
||||
// Keep the sourcing name/lnum, for recursive calls.
|
||||
estack_push(ETYPE_SCRIPT, si->sn_name, 0);
|
||||
estack_push(ETYPE_SCRIPT, si != NULL ? si->sn_name : fname_exp, 0);
|
||||
|
||||
if (l_do_profiling == PROF_YES) {
|
||||
if (l_do_profiling == PROF_YES && si != NULL) {
|
||||
bool forceit = false;
|
||||
|
||||
// Check if we do profiling for this script.
|
||||
@@ -2275,7 +2260,12 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
|
||||
cookie.conv.vc_type = CONV_NONE; // no conversion
|
||||
|
||||
if (si->sn_lua) {
|
||||
if (fname == NULL
|
||||
&& (ex_lua || strequal(curbuf->b_p_ft, "lua")
|
||||
|| (curbuf->b_fname && path_with_extension(curbuf->b_fname, "lua")))) {
|
||||
// Source lines from the current buffer as lua
|
||||
nlua_exec_ga(&cookie.buflines, fname_exp);
|
||||
} else if (si != NULL && si->sn_lua) {
|
||||
// Source the file as lua
|
||||
nlua_exec_file(fname_exp);
|
||||
} else {
|
||||
@@ -2285,7 +2275,7 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
&& firstline[1] == 0xbb && firstline[2] == 0xbf) {
|
||||
// Found BOM; setup conversion, skip over BOM and recode the line.
|
||||
convert_setup(&cookie.conv, "utf-8", p_enc);
|
||||
p = string_convert(&cookie.conv, (char *)firstline + 3, NULL);
|
||||
char *p = string_convert(&cookie.conv, (char *)firstline + 3, NULL);
|
||||
if (p == NULL) {
|
||||
p = xstrdup((char *)firstline + 3);
|
||||
}
|
||||
@@ -2298,7 +2288,7 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
}
|
||||
retval = OK;
|
||||
|
||||
if (l_do_profiling == PROF_YES) {
|
||||
if (l_do_profiling == PROF_YES && si != NULL) {
|
||||
// Get "si" again, "script_items" may have been reallocated.
|
||||
si = SCRIPT_ITEM(current_sctx.sc_sid);
|
||||
if (si->sn_prof_on) {
|
||||
@@ -2345,12 +2335,17 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid)
|
||||
if (l_do_profiling == PROF_YES) {
|
||||
prof_child_exit(&wait_start); // leaving a child now
|
||||
}
|
||||
fclose(cookie.fp);
|
||||
if (cookie.fp != NULL) {
|
||||
fclose(cookie.fp);
|
||||
}
|
||||
if (cookie.source_from_buf_or_str) {
|
||||
ga_clear_strings(&cookie.buflines);
|
||||
}
|
||||
xfree(cookie.nextline);
|
||||
xfree(firstline);
|
||||
convert_setup(&cookie.conv, NULL, NULL);
|
||||
|
||||
if (trigger_source_post) {
|
||||
if (str == NULL && trigger_source_post) {
|
||||
apply_autocmds(EVENT_SOURCEPOST, fname_exp, fname_exp, false, curbuf);
|
||||
}
|
||||
|
||||
@@ -2359,6 +2354,13 @@ theend:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// @param check_other check for .vimrc and _vimrc
|
||||
/// @param is_vimrc DOSO_ value
|
||||
int do_source(char *fname, bool check_other, int is_vimrc, int *ret_sid)
|
||||
{
|
||||
return do_source_ext(fname, check_other, is_vimrc, ret_sid, NULL, false, NULL);
|
||||
}
|
||||
|
||||
/// Checks if the script with the given script ID is a Lua script.
|
||||
bool script_is_lua(scid_T sid)
|
||||
{
|
||||
@@ -2621,7 +2623,7 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat)
|
||||
char *line;
|
||||
|
||||
// If breakpoints have been added/deleted need to check for it.
|
||||
if (sp->dbg_tick < debug_tick) {
|
||||
if ((sp->dbg_tick < debug_tick) && !sp->source_from_buf_or_str) {
|
||||
sp->breakpoint = dbg_find_breakpoint(true, sp->fname, SOURCING_LNUM);
|
||||
sp->dbg_tick = debug_tick;
|
||||
}
|
||||
@@ -2632,7 +2634,7 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat)
|
||||
SOURCING_LNUM = sp->sourcing_lnum + 1;
|
||||
// Get current line. If there is a read-ahead line, use it, otherwise get
|
||||
// one now. "fp" is NULL if actually using a string.
|
||||
if (sp->finished || sp->fp == NULL) {
|
||||
if (sp->finished || (!sp->source_from_buf_or_str && sp->fp == NULL)) {
|
||||
line = NULL;
|
||||
} else if (sp->nextline == NULL) {
|
||||
line = get_one_sourceline(sp);
|
||||
@@ -2685,7 +2687,8 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat)
|
||||
}
|
||||
|
||||
// Did we encounter a breakpoint?
|
||||
if (sp->breakpoint != 0 && sp->breakpoint <= SOURCING_LNUM) {
|
||||
if (!sp->source_from_buf_or_str
|
||||
&& sp->breakpoint != 0 && sp->breakpoint <= SOURCING_LNUM) {
|
||||
dbg_breakpoint(sp->fname, SOURCING_LNUM);
|
||||
// Find next breakpoint.
|
||||
sp->breakpoint = dbg_find_breakpoint(true, sp->fname, SOURCING_LNUM);
|
||||
@@ -2714,17 +2717,23 @@ static char *get_one_sourceline(source_cookie_T *sp)
|
||||
while (true) {
|
||||
// make room to read at least 120 (more) characters
|
||||
ga_grow(&ga, 120);
|
||||
buf = ga.ga_data;
|
||||
|
||||
retry:
|
||||
errno = 0;
|
||||
if (fgets(buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
|
||||
sp->fp) == NULL) {
|
||||
if (errno == EINTR) {
|
||||
goto retry;
|
||||
if (sp->source_from_buf_or_str) {
|
||||
if (sp->buf_lnum >= sp->buflines.ga_len) {
|
||||
break; // all the lines are processed
|
||||
}
|
||||
ga_concat(&ga, ((char **)sp->buflines.ga_data)[sp->buf_lnum]);
|
||||
sp->buf_lnum++;
|
||||
buf = (char *)ga.ga_data;
|
||||
} else {
|
||||
buf = ga.ga_data;
|
||||
retry:
|
||||
errno = 0;
|
||||
if (fgets(buf + ga.ga_len, ga.ga_maxlen - ga.ga_len, sp->fp) == NULL) {
|
||||
if (errno == EINTR) {
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
len = ga.ga_len + (int)strlen(buf + ga.ga_len);
|
||||
#ifdef USE_CRNL
|
||||
@@ -2797,7 +2806,7 @@ retry:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Returns true if sourcing a script either from a file or a buffer.
|
||||
/// Returns true if sourcing a script either from a file or a buffer or a string.
|
||||
/// Otherwise returns false.
|
||||
int sourcing_a_script(exarg_T *eap)
|
||||
{
|
||||
|
Reference in New Issue
Block a user