mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 14:38:32 +00:00
[RFC] ":source" sources from current buffer if filename is omitted (#11444)
Fix https://github.com/neovim/neovim/issues/8722
This commit is contained in:
@@ -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!
|
||||
|
Reference in New Issue
Block a user