aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-09-29 22:41:37 +0200
committerMarc André Tanner <mat@brain-dump.org>2016-09-29 22:41:37 +0200
commit9887127b03523097957a48657a130c0999574f1b (patch)
treef6d033d98f8a6be891f2bb9809a1bc8e1c9d3f8d
parentcab0d2ce3f375084dd2de764e760ccc229689b71 (diff)
downloadvis-9887127b03523097957a48657a130c0999574f1b.tar.gz
vis-9887127b03523097957a48657a130c0999574f1b.tar.xz
sam: consistent argument handling for :r, :w, :e commands
:e without any argument can be used to reload the file from disk whereas before a "Filename expected" error would be displayed.
-rw-r--r--sam.c40
-rw-r--r--sam.h1
-rw-r--r--vis-cmds.c7
3 files changed, 22 insertions, 26 deletions
diff --git a/sam.c b/sam.c
index 3eb2d02..3121a13 100644
--- a/sam.c
+++ b/sam.c
@@ -78,10 +78,9 @@ struct CommandDef {
CMD_ADDRESS_LINE = 1 << 7, /* if no address is given, use the current line */
CMD_ADDRESS_AFTER = 1 << 8, /* if no address is given, begin at the start of the next line */
CMD_SHELL = 1 << 9, /* command needs a shell command as argument */
- CMD_FILE = 1 << 10, /* does the command take a file name */
- CMD_FORCE = 1 << 11, /* can the command be forced with ! */
- CMD_ARGV = 1 << 12, /* whether shell like argument splitted is desired */
- CMD_ONCE = 1 << 13, /* command should only be executed once, not for every selection */
+ CMD_FORCE = 1 << 10, /* can the command be forced with ! */
+ CMD_ARGV = 1 << 11, /* whether shell like argument splitted is desired */
+ CMD_ONCE = 1 << 12, /* command should only be executed once, not for every selection */
} flags;
const char *defcmd; /* name of a default target command */
bool (*func)(Vis*, Win*, Command*, const char *argv[], Cursor*, Filerange*); /* command implementation */
@@ -147,10 +146,10 @@ static const CommandDef cmds[] = {
{ "|", "Pipe range through command", CMD_SHELL|CMD_ADDRESS_POS, NULL, cmd_filter },
{ "!", "Run the command", CMD_SHELL|CMD_ONCE, NULL, cmd_launch },
{ "w", "Write range to named file", CMD_ARGV|CMD_FORCE|CMD_ADDRESS_NONE|CMD_ONCE, NULL, cmd_write},
- { "r", "Replace range by contents of file", CMD_FILE|CMD_ADDRESS_AFTER, NULL, cmd_read },
+ { "r", "Replace range by contents of file", CMD_ARGV|CMD_ADDRESS_AFTER, NULL, cmd_read },
{ "{", "Start of command group", CMD_NONE, NULL, NULL },
{ "}", "End of command group" , CMD_NONE, NULL, NULL },
- { "e", "Edit file", CMD_FILE|CMD_FORCE|CMD_ONCE, NULL, cmd_edit },
+ { "e", "Edit file", CMD_ARGV|CMD_FORCE|CMD_ONCE, NULL, cmd_edit },
{ "q", "Quit the current window", CMD_FORCE|CMD_ONCE, NULL, cmd_quit },
{ "cd", "Change directory", CMD_ARGV|CMD_ONCE, NULL, cmd_cd },
/* vi(m) related commands */
@@ -242,7 +241,6 @@ const char *sam_error(enum SamError err) {
[SAM_ERR_UNMATCHED_BRACE] = "Unmatched `}'",
[SAM_ERR_REGEX] = "Bad regular expression",
[SAM_ERR_TEXT] = "Bad text",
- [SAM_ERR_FILENAME] = "Filename expected",
[SAM_ERR_COMMAND] = "Unknown command",
[SAM_ERR_EXECUTE] = "Error executing command",
};
@@ -356,13 +354,6 @@ static char *parse_shellcmd(const char **s) {
return parse_until(s, "\n", NULL);
}
-static char *parse_filename(const char **s) {
- skip_spaces(s);
- if (**s == '"' || **s == '\'')
- return parse_delimited_text(s);
- return parse_until(s, "\n", "\'\"");
-}
-
static void parse_argv(const char **s, const char *argv[], size_t maxarg) {
for (size_t i = 0; i < maxarg; i++) {
skip_spaces(s);
@@ -606,13 +597,6 @@ static Command *command_parse(Vis *vis, const char **s, int level, enum SamError
(*s)++;
}
- if (cmddef->flags & CMD_FILE) {
- if (!(cmd->argv[1] = parse_filename(s)) && cmd->argv[0][0] != 'w') {
- *err = SAM_ERR_FILENAME;
- goto fail;
- }
- }
-
if (cmddef->flags & CMD_REGEX) {
if ((cmddef->flags & CMD_REGEX_DEFAULT) && (!**s || **s == ' ')) {
skip_spaces(s);
@@ -1165,10 +1149,20 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs
}
static bool cmd_read(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!argv[1]) {
+ vis_info_show(vis, "Filename expected");
+ return false;
+ }
+
Buffer buf;
buffer_init(&buf);
- bool ret = false;
- if (buffer_put0(&buf, "cat ") && buffer_append0(&buf, argv[1]))
+ bool ret = buffer_put0(&buf, "cat --");
+ for (const char **name = &argv[1]; *name; name++) {
+ ret &= buffer_append0(&buf, " '");
+ ret &= buffer_append0(&buf, *name);
+ ret &= buffer_append0(&buf, "'");
+ }
+ if (ret)
ret = cmd_pipein(vis, win, cmd, (const char*[]){ argv[0], buf.data, NULL }, cur, range);
buffer_release(&buf);
return ret;
diff --git a/sam.h b/sam.h
index f44079a..de7e910 100644
--- a/sam.h
+++ b/sam.h
@@ -12,7 +12,6 @@ enum SamError {
SAM_ERR_REGEX,
SAM_ERR_TEXT,
SAM_ERR_SHELL,
- SAM_ERR_FILENAME,
SAM_ERR_COMMAND,
SAM_ERR_EXECUTE,
};
diff --git a/vis-cmds.c b/vis-cmds.c
index ea6ed8c..87ebd67 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -326,6 +326,10 @@ static void info_unsaved_changes(Vis *vis) {
}
static bool cmd_edit(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (argv[2]) {
+ vis_info_show(vis, "Only 1 filename allowed");
+ return false;
+ }
Win *oldwin = win;
if (!oldwin)
return false;
@@ -520,13 +524,12 @@ static bool print_action(const char *key, void *value, void *data) {
static bool print_cmd(const char *key, void *value, void *data) {
char help[256];
CommandDef *cmd = value;
- snprintf(help, sizeof help, "%s%s%s%s%s%s%s%s",
+ snprintf(help, sizeof help, "%s%s%s%s%s%s%s",
cmd->name,
(cmd->flags & CMD_FORCE) ? "[!]" : "",
(cmd->flags & CMD_TEXT) ? "/text/" : "",
(cmd->flags & CMD_REGEX) ? "/regexp/" : "",
(cmd->flags & CMD_CMD) ? " command" : "",
- (cmd->flags & CMD_FILE) ? " file-name" : "",
(cmd->flags & CMD_SHELL) ? (!strcmp(cmd->name, "s") ? "/regexp/text/" : " shell-command") : "",
(cmd->flags & CMD_ARGV) ? " [args...]" : "");
return text_appendf(data, " %-30s %s\n", help, cmd->help);