aboutsummaryrefslogtreecommitdiff
path: root/register.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-01-30 20:15:30 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-01-30 23:12:54 +0100
commitc9662de55d78baa82dfcac1afab170a0d8e4f163 (patch)
tree86e9efd6b1fc229cf70a30fbd598715a673b8bb8 /register.c
parentd94bb93f10365a39d90cc0d4d4b151fc797767df (diff)
downloadvis-c9662de55d78baa82dfcac1afab170a0d8e4f163.tar.gz
vis-c9662de55d78baa82dfcac1afab170a0d8e4f163.tar.xz
Implement system clipboard registers "* and "+
Both registers are currently treated identically. The actual system integration is performed by two shell scripts vis-copy and vis-paste.
Diffstat (limited to 'register.c')
-rw-r--r--register.c60
1 files changed, 56 insertions, 4 deletions
diff --git a/register.c b/register.c
index 30e4c58..a15e8b3 100644
--- a/register.c
+++ b/register.c
@@ -1,20 +1,56 @@
#include <stdlib.h>
#include <string.h>
-#include "register.h"
-#include "buffer.h"
+#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(&reg->buf);
}
-const char *register_get(Register *reg, size_t *len) {
+const char *register_get(Vis *vis, Register *reg, size_t *len) {
switch (reg->type) {
case REGISTER_NORMAL:
*len = reg->buf.len;
return reg->buf.data;
+ case REGISTER_CLIPBOARD:
+ {
+ Buffer stderr;
+ buffer_init(&stderr);
+ buffer_clear(&reg->buf);
+ Clipboard clipboard = {
+ .stdout = &reg->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;
@@ -22,7 +58,7 @@ const char *register_get(Register *reg, size_t *len) {
}
}
-bool register_put(Register *reg, Text *txt, Filerange *range) {
+bool register_put(Vis *vis, Register *reg, Text *txt, Filerange *range) {
switch (reg->type) {
case REGISTER_NORMAL:
{
@@ -32,6 +68,22 @@ bool register_put(Register *reg, Text *txt, Filerange *range) {
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: