vis: also lookup Lua support files relative to the binary location
[vis.git] / register.c
blobdb87275ebae3e38dc0806e8697095e789ef7868f
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 if (reg->buf.len > 0 && reg->buf.data[reg->buf.len-1] != '\0')
34 buffer_append(&reg->buf, "\0", 1);
35 if (len)
36 *len = reg->buf.len > 0 ? reg->buf.len - 1 : 0;
37 return reg->buf.data;
38 case REGISTER_CLIPBOARD:
40 Buffer stderr;
41 buffer_init(&stderr);
42 buffer_clear(&reg->buf);
43 Clipboard clipboard = {
44 .stdout = &reg->buf,
45 .stderr = &stderr,
48 int status = vis_pipe(vis, &clipboard,
49 &(Filerange){ .start = 0, .end = 0 },
50 (const char*[]){ "vis-paste", "vis-paste", NULL },
51 read_stdout, read_stderr);
52 if (status != 0)
53 vis_info_show(vis, "Command failed %s", stderr.len > 0 ? stderr.data : "");
54 *len = reg->buf.len;
55 return reg->buf.data;
57 case REGISTER_BLACKHOLE:
58 default:
59 *len = 0;
60 return NULL;
64 bool register_put(Vis *vis, Register *reg, const char *data, size_t len) {
65 return reg->type == REGISTER_NORMAL && buffer_put(&reg->buf, data, len);
68 bool register_put0(Vis *vis, Register *reg, const char *data) {
69 return register_put(vis, reg, data, strlen(data)+1);
72 bool register_put_range(Vis *vis, Register *reg, Text *txt, Filerange *range) {
73 if (reg->append)
74 return register_append_range(reg, txt, range);
75 switch (reg->type) {
76 case REGISTER_NORMAL:
78 size_t len = text_range_size(range);
79 if (!buffer_grow(&reg->buf, len))
80 return false;
81 reg->buf.len = text_bytes_get(txt, range->start, len, reg->buf.data);
82 return true;
84 case REGISTER_CLIPBOARD:
86 Buffer stderr;
87 buffer_init(&stderr);
88 Clipboard clipboard = {
89 .stderr = &stderr,
92 int status = vis_pipe(vis, &clipboard, range,
93 (const char*[]){ "vis-copy", "vis-copy", NULL },
94 NULL, read_stderr);
96 if (status != 0)
97 vis_info_show(vis, "Command failed %s", stderr.len > 0 ? stderr.data : "");
98 return status == 0;
100 case REGISTER_BLACKHOLE:
101 return true;
102 default:
103 return false;
107 bool register_append_range(Register *reg, Text *txt, Filerange *range) {
108 switch (reg->type) {
109 case REGISTER_NORMAL:
111 size_t len = text_range_size(range);
112 if (!buffer_grow(&reg->buf, reg->buf.len + len))
113 return false;
114 reg->buf.len += text_bytes_get(txt, range->start, len, reg->buf.data + reg->buf.len);
115 return true;
117 default:
118 return false;