diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-01-29 19:45:23 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-01-29 19:46:18 +0100 |
| commit | 603a2d2e78d1f1dd71a2f1a7f4560e0816e3dd32 (patch) | |
| tree | 222c716e68c830ef204960ea1675502e87fe6362 /vis-cmds.c | |
| parent | 68c3fa73b29fc1cc560414518a73ceac93f087b0 (diff) | |
| download | vis-603a2d2e78d1f1dd71a2f1a7f4560e0816e3dd32.tar.gz vis-603a2d2e78d1f1dd71a2f1a7f4560e0816e3dd32.tar.xz | |
vis: implement new pipe/write out command :| or :w !
Diffstat (limited to 'vis-cmds.c')
| -rw-r--r-- | vis-cmds.c | 53 |
1 files changed, 52 insertions, 1 deletions
@@ -79,6 +79,8 @@ static bool cmd_write(Vis*, Filerange*, enum CmdOpt, const char *argv[]); static bool cmd_saveas(Vis*, Filerange*, enum CmdOpt, const char *argv[]); /* filter range through external program argv[1] */ static bool cmd_filter(Vis*, Filerange*, enum CmdOpt, const char *argv[]); +/* write range to external program, display output in a new window */ +static bool cmd_pipe(Vis *vis, Filerange*, enum CmdOpt, const char *argv[]); /* switch to the previous/next saved state of the text, chronologically */ static bool cmd_earlier_later(Vis*, Filerange*, enum CmdOpt, const char *argv[]); /* dump current key bindings */ @@ -117,6 +119,7 @@ static Command cmds[] = { { { "earlier" }, cmd_earlier_later, CMD_OPT_NONE }, { { "later" }, cmd_earlier_later, CMD_OPT_NONE }, { { "!", }, cmd_filter, CMD_OPT_NONE }, + { { "|", }, cmd_pipe, CMD_OPT_NONE }, { { NULL, }, NULL, CMD_OPT_NONE }, }; @@ -601,6 +604,12 @@ static bool cmd_write(Vis *vis, Filerange *range, enum CmdOpt opt, const char *a vis_info_show(vis, "Filename expected"); return false; } + + if (argv[1][0] == '!') { + argv[1]++; + return cmd_pipe(vis, range, opt, argv); + } + for (const char **name = &argv[1]; *name; name++) { struct stat meta; if (!(opt & CMD_OPT_FORCE) && file->stat.st_mtime && stat(*name, &meta) == 0 && @@ -865,6 +874,48 @@ static bool cmd_filter(Vis *vis, Filerange *range, enum CmdOpt opt, const char * return !vis->cancel_filter && status == 0; } +static ssize_t read_stdout_new(void *context, char *data, size_t len) { + Filter *filter = context; + + if (!filter->txt && vis_window_new(filter->vis, NULL)) + filter->txt = filter->vis->win->file->text; + + if (filter->txt) { + text_insert(filter->txt, filter->pos, data, len); + filter->pos += len; + } + return len; +} + +static bool cmd_pipe(Vis *vis, Filerange *range, enum CmdOpt opt, const char *argv[]) { + Text *txt = vis->win->file->text; + if (!text_range_valid(range)) + *range = (Filerange){ .start = 0, .end = text_size(txt) }; + + Filter filter = { + .vis = vis, + .txt = NULL, + .pos = 0, + }; + + buffer_init(&filter.stderr); + + int status = vis_pipe(vis, &filter, range, argv, read_stdout_new, read_stderr); + + if (vis->cancel_filter) + vis_info_show(vis, "Command cancelled"); + else if (status == 0) + vis_info_show(vis, "Command succeded"); + else if (filter.stderr.len > 0) + vis_info_show(vis, "Command failed: %s", filter.stderr.data); + else + vis_info_show(vis, "Command failed"); + + buffer_release(&filter.stderr); + + return !vis->cancel_filter && status == 0; +} + static bool cmd_earlier_later(Vis *vis, Filerange *range, enum CmdOpt opt, const char *argv[]) { Text *txt = vis->win->file->text; char *unit = ""; @@ -1181,7 +1232,7 @@ bool vis_cmd(Vis *vis, const char *cmdline) { while (*name == ' ') name++; char *param = name; - while (*param && (isalpha((unsigned char)*param) || *param == '-')) + while (*param && (isalpha((unsigned char)*param) || *param == '-' || *param == '|')) param++; if (*param == '!') { |
