diff options
Diffstat (limited to 'src/nvim/ex_cmds2.c')
-rw-r--r-- | src/nvim/ex_cmds2.c | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index bb53f4d373..c24ecde096 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -29,6 +29,7 @@ #include "nvim/getchar.h" #include "nvim/mark.h" #include "nvim/mbyte.h" +#include "nvim/memline.h" #include "nvim/message.h" #include "nvim/misc1.h" #include "nvim/garray.h" @@ -2526,7 +2527,7 @@ void ex_pyxdo(exarg_T *eap) } } -/// ":source {fname}" +/// ":source [{fname}]" void ex_source(exarg_T *eap) { cmd_source(eap->arg, eap); @@ -2535,7 +2536,7 @@ void ex_source(exarg_T *eap) static void cmd_source(char_u *fname, exarg_T *eap) { if (*fname == NUL) { - EMSG(_(e_argreq)); + cmd_source_buffer(eap); } else if (eap != NULL && eap->forceit) { // ":source!": read Normal mode commands // Need to execute the commands directly. This is required at least @@ -2553,6 +2554,37 @@ static void cmd_source(char_u *fname, exarg_T *eap) } } +typedef struct { + linenr_T curr_lnum; + const linenr_T final_lnum; +} GetBufferLineCookie; + +/// Get one line from the current selection in the buffer. +/// Called by do_cmdline() when it's called from cmd_source_buffer(). +/// +/// @return pointer to allocated line, or NULL for end-of-file or +/// some error. +static char_u *get_buffer_line(int c, void *cookie, int indent, bool do_concat) +{ + GetBufferLineCookie *p = cookie; + if (p->curr_lnum > p->final_lnum) { + return NULL; + } + char_u *curr_line = ml_get(p->curr_lnum); + p->curr_lnum++; + return (char_u *)xstrdup((const char *)curr_line); +} + +static void cmd_source_buffer(exarg_T *eap) +{ + GetBufferLineCookie cookie = { + .curr_lnum = eap->line1, + .final_lnum = eap->line2, + }; + source_using_linegetter((void *)&cookie, get_buffer_line, + ":source (no file)"); +} + /// ":source" and associated commands. /// /// @return address holding the next breakpoint line for a source cookie @@ -2624,10 +2656,9 @@ static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat) return (char_u *)xstrdup(buf); } -/// Executes lines in `src` as Ex commands. -/// -/// @see do_source() -int do_source_str(const char *cmd, const char *traceback_name) +static int source_using_linegetter(void *cookie, + LineGetter fgetline, + const char *traceback_name) { char_u *save_sourcing_name = sourcing_name; linenr_T save_sourcing_lnum = sourcing_lnum; @@ -2642,22 +2673,33 @@ int do_source_str(const char *cmd, const char *traceback_name) } sourcing_lnum = 0; - GetStrLineCookie cookie = { - .buf = (char_u *)cmd, - .offset = 0, - }; const sctx_T save_current_sctx = current_sctx; current_sctx.sc_sid = SID_STR; current_sctx.sc_seq = 0; current_sctx.sc_lnum = save_sourcing_lnum; - int retval = do_cmdline(NULL, get_str_line, (void *)&cookie, + funccal_entry_T entry; + save_funccal(&entry); + int retval = do_cmdline(NULL, fgetline, cookie, DOCMD_VERBOSE | DOCMD_NOWAIT | DOCMD_REPEAT); - current_sctx = save_current_sctx; sourcing_lnum = save_sourcing_lnum; sourcing_name = save_sourcing_name; + current_sctx = save_current_sctx; + restore_funccal(); return retval; } +/// Executes lines in `src` as Ex commands. +/// +/// @see do_source() +int do_source_str(const char *cmd, const char *traceback_name) +{ + GetStrLineCookie cookie = { + .buf = (char_u *)cmd, + .offset = 0, + }; + return source_using_linegetter((void *)&cookie, get_str_line, traceback_name); +} + /// Reads the file `fname` and executes its lines as Ex commands. /// /// This function may be called recursively! |