aboutsummaryrefslogtreecommitdiff
path: root/vis.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-05-15 23:36:22 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-05-17 12:47:59 +0200
commitc651f730bcf60b3c963e21203221cc98990afc28 (patch)
treec261a3a70ef0d1d985b8aed26bf3c756c30cf74f /vis.c
parent1244aeae5c603593aa71df4b67974c11ea1576cd (diff)
downloadvis-c651f730bcf60b3c963e21203221cc98990afc28.tar.gz
vis-c651f730bcf60b3c963e21203221cc98990afc28.tar.xz
Implement :r and :r! in terms of filter commands
Diffstat (limited to 'vis.c')
-rw-r--r--vis.c45
1 files changed, 20 insertions, 25 deletions
diff --git a/vis.c b/vis.c
index d78ed6b..6998f5e 100644
--- a/vis.c
+++ b/vis.c
@@ -1536,32 +1536,27 @@ static bool cmd_qall(Filerange *range, enum CmdOpt opt, const char *argv[]) {
}
static bool cmd_read(Filerange *range, enum CmdOpt opt, const char *argv[]) {
- size_t pos = view_cursor_get(vis->win->view);
- for (const char **file = &argv[1]; *file; file++) {
- int fd = open(*file, O_RDONLY);
- char *text = NULL;
- struct stat info;
- if (fd == -1)
- goto err;
- if (fstat(fd, &info) == -1)
- goto err;
- if (!S_ISREG(info.st_mode))
- goto err;
- // XXX: use lseek(fd, 0, SEEK_END); instead?
- text = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (text == MAP_FAILED)
- goto err;
-
- text_insert(vis->win->file->text, pos, text, info.st_size);
- pos += info.st_size;
- err:
- if (fd != -1)
- close(fd);
- if (text && text != MAP_FAILED)
- munmap(text, info.st_size);
+ char cmd[255];
+
+ if (!argv[1]) {
+ editor_info_show(vis, "Filename or command expected");
+ return false;
}
- editor_draw(vis);
- return true;
+
+ bool iscmd = (opt & CMD_OPT_FORCE) || argv[1][0] == '!';
+ const char *arg = argv[1]+(argv[1][0] == '!');
+ snprintf(cmd, sizeof cmd, "%s%s", iscmd ? "" : "cat ", arg);
+
+ size_t pos = view_cursor_get(vis->win->view);
+ if (!text_range_valid(range))
+ range = &(Filerange){ .start = pos, .end = pos };
+ Filerange delete = *range;
+ range->start = range->end;
+
+ bool ret = cmd_filter(range, opt, (const char*[]){ argv[0], "sh", "-c", cmd, NULL});
+ if (ret)
+ text_delete(vis->win->file->text, delete.start, delete.end - delete.start);
+ return ret;
}
static bool cmd_substitute(Filerange *range, enum CmdOpt opt, const char *argv[]) {