vis: mark output of pipe command as saved
[vis.git] / register.c
blob518f93ab9b0d622791d980ee3e0166f798cdb5cb
1 #include <stdlib.h>
2 #include <string.h>
4 #include "vis.h"
5 #include "text.h"
6 #include "util.h"
7 #include "register.h"
9 typedef struct {
10 Buffer *stdout;
11 Buffer *stderr;
12 } Clipboard;
14 static ssize_t read_stdout(void *context, char *data, size_t len) {
15 Buffer *buf = ((Clipboard*)context)->stdout;
16 buffer_append(buf, data, len);
17 return len;
20 static ssize_t read_stderr(void *context, char *data, size_t len) {
21 Buffer *buf = ((Clipboard*)context)->stderr;
22 buffer_append(buf, data, len);
23 return len;
26 void register_release(Register *reg) {
27 buffer_release(&reg->buf);
30 const char *register_get(Vis *vis, Register *reg, size_t *len) {
31 switch (reg->type) {
32 case REGISTER_NORMAL:
33 *len = reg->buf.len;
34 return reg->buf.data;
35 case REGISTER_CLIPBOARD:
37 Buffer stderr;
38 buffer_init(&stderr);
39 buffer_clear(&reg->buf);
40 Clipboard clipboard = {
41 .stdout = &reg->buf,
42 .stderr = &stderr,
45 int status = vis_pipe(vis, &clipboard,
46 &(Filerange){ .start = 0, .end = 0 },
47 (const char*[]){ "vis-paste", "vis-paste", NULL },
48 read_stdout, read_stderr);
49 if (status != 0)
50 vis_info_show(vis, "Command failed %s", stderr.len > 0 ? stderr.data : "");
51 *len = reg->buf.len;
52 return reg->buf.data;
54 case REGISTER_BLACKHOLE:
55 default:
56 *len = 0;
57 return NULL;
61 bool register_put(Vis *vis, Register *reg, Text *txt, Filerange *range) {
62 if (reg->append)
63 return register_append(reg, txt, range);
64 switch (reg->type) {
65 case REGISTER_NORMAL:
67 size_t len = text_range_size(range);
68 if (!buffer_grow(&reg->buf, len))
69 return false;
70 reg->buf.len = text_bytes_get(txt, range->start, len, reg->buf.data);
71 return true;
73 case REGISTER_CLIPBOARD:
75 Buffer stderr;
76 buffer_init(&stderr);
77 Clipboard clipboard = {
78 .stderr = &stderr,
81 int status = vis_pipe(vis, &clipboard, range,
82 (const char*[]){ "vis-copy", "vis-copy", NULL },
83 NULL, read_stderr);
85 if (status != 0)
86 vis_info_show(vis, "Command failed %s", stderr.len > 0 ? stderr.data : "");
87 return status == 0;
89 case REGISTER_BLACKHOLE:
90 return true;
91 default:
92 return false;
96 bool register_append(Register *reg, Text *txt, Filerange *range) {
97 switch (reg->type) {
98 case REGISTER_NORMAL:
100 size_t len = text_range_size(range);
101 if (!buffer_grow(&reg->buf, reg->buf.len + len))
102 return false;
103 reg->buf.len += text_bytes_get(txt, range->start, len, reg->buf.data + reg->buf.len);
104 return true;
106 default:
107 return false;