#include #include #include "vis.h" #include "text.h" #include "util.h" #include "register.h" typedef struct { Buffer *stdout; Buffer *stderr; } Clipboard; static ssize_t read_stdout(void *context, char *data, size_t len) { Buffer *buf = ((Clipboard*)context)->stdout; buffer_append(buf, data, len); return len; } static ssize_t read_stderr(void *context, char *data, size_t len) { Buffer *buf = ((Clipboard*)context)->stderr; buffer_append(buf, data, len); return len; } void register_release(Register *reg) { buffer_release(®->buf); } const char *register_get(Vis *vis, Register *reg, size_t *len) { switch (reg->type) { case REGISTER_NORMAL: *len = buffer_length0(®->buf); return reg->buf.data; case REGISTER_CLIPBOARD: { Buffer stderr; buffer_init(&stderr); buffer_clear(®->buf); Clipboard clipboard = { .stdout = ®->buf, .stderr = &stderr, }; int status = vis_pipe(vis, &clipboard, &(Filerange){ .start = 0, .end = 0 }, (const char*[]){ "vis-paste", "vis-paste", NULL }, read_stdout, read_stderr); if (status != 0) vis_info_show(vis, "Command failed %s", stderr.len > 0 ? stderr.data : ""); *len = reg->buf.len; return reg->buf.data; } case REGISTER_BLACKHOLE: default: *len = 0; return NULL; } } bool register_put(Vis *vis, Register *reg, Text *txt, Filerange *range) { if (reg->append) return register_append(reg, txt, range); switch (reg->type) { case REGISTER_NORMAL: { size_t len = text_range_size(range); if (!buffer_grow(®->buf, len)) return false; reg->buf.len = text_bytes_get(txt, range->start, len, reg->buf.data); return true; } case REGISTER_CLIPBOARD: { Buffer stderr; buffer_init(&stderr); Clipboard clipboard = { .stderr = &stderr, }; int status = vis_pipe(vis, &clipboard, range, (const char*[]){ "vis-copy", "vis-copy", NULL }, NULL, read_stderr); if (status != 0) vis_info_show(vis, "Command failed %s", stderr.len > 0 ? stderr.data : ""); return status == 0; } case REGISTER_BLACKHOLE: return true; default: return false; } } bool register_append(Register *reg, Text *txt, Filerange *range) { switch (reg->type) { case REGISTER_NORMAL: { size_t len = text_range_size(range); if (!buffer_grow(®->buf, reg->buf.len + len)) return false; reg->buf.len += text_bytes_get(txt, range->start, len, reg->buf.data + reg->buf.len); return true; } default: return false; } }