From 9887127b03523097957a48657a130c0999574f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Thu, 29 Sep 2016 22:41:37 +0200 Subject: 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. --- sam.c | 40 +++++++++++++++++----------------------- sam.h | 1 - vis-cmds.c | 7 +++++-- 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); -- cgit v1.2.3