aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--buffer.c4
-rw-r--r--buffer.h2
-rw-r--r--main.c2
-rw-r--r--register.c60
-rw-r--r--register.h9
-rw-r--r--ui.h2
-rwxr-xr-xvis-copy10
-rw-r--r--vis-operators.c6
-rwxr-xr-xvis-paste10
-rw-r--r--vis.c3
-rw-r--r--vis.h1
12 files changed, 104 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 486aa3b..b04d860 100644
--- a/Makefile
+++ b/Makefile
@@ -80,6 +80,10 @@ install: vis
@chmod 755 ${DESTDIR}${PREFIX}/bin/vis
@cp -f vis-open ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/vis-open
+ @cp -f vis-copy ${DESTDIR}${PREFIX}/bin
+ @chmod 755 ${DESTDIR}${PREFIX}/bin/vis-copy
+ @cp -f vis-paste ${DESTDIR}${PREFIX}/bin
+ @chmod 755 ${DESTDIR}${PREFIX}/bin/vis-paste
@echo installing support files to ${DESTDIR}${SHAREPREFIX}
@mkdir -p ${DESTDIR}${SHAREPREFIX}
@cp -r visrc.lua lexers ${DESTDIR}${SHAREPREFIX}
@@ -92,6 +96,8 @@ uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/vis
@rm -f ${DESTDIR}${PREFIX}/bin/vis-open
+ @rm -f ${DESTDIR}${PREFIX}/bin/vis-copy
+ @rm -f ${DESTDIR}${PREFIX}/bin/vis-paste
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/vis.1
@echo removing support files from ${DESTDIR}${SHAREPREFIX}
diff --git a/buffer.c b/buffer.c
index a0b60e2..b9bc28c 100644
--- a/buffer.c
+++ b/buffer.c
@@ -36,6 +36,10 @@ void buffer_release(Buffer *buf) {
buffer_init(buf);
}
+void buffer_clear(Buffer *buf) {
+ buf->len = 0;
+}
+
bool buffer_put(Buffer *buf, const void *data, size_t len) {
if (!buffer_grow(buf, len))
return false;
diff --git a/buffer.h b/buffer.h
index 0dc2dc6..037055b 100644
--- a/buffer.h
+++ b/buffer.h
@@ -16,6 +16,8 @@ typedef struct {
void buffer_init(Buffer*);
/* release/free all data stored in this buffer, reset size to zero */
void buffer_release(Buffer*);
+/* set buffer size to zero, keep allocated memory */
+void buffer_clear(Buffer*);
/* reserve space to store at least size bytes in this buffer.*/
bool buffer_grow(Buffer*, size_t size);
/* truncate buffer, but keep associated memory region for further data */
diff --git a/main.c b/main.c
index 487ce3c..077ed77 100644
--- a/main.c
+++ b/main.c
@@ -1306,6 +1306,8 @@ static const char *key2register(Vis *vis, const char *keys, enum VisRegister *re
return NULL;
if (keys[0] >= 'a' && keys[0] <= 'z')
*reg = keys[0] - 'a';
+ else if (keys[0] == '*' || keys[0] == '+')
+ *reg = VIS_REG_CLIPBOARD;
else if (keys[0] == '_')
*reg = VIS_REG_BLACKHOLE;
return keys+1;
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:
diff --git a/register.h b/register.h
index 1b14688..d3f7b7f 100644
--- a/register.h
+++ b/register.h
@@ -6,18 +6,23 @@
#include "buffer.h"
#include "text-util.h"
+#ifndef VIS_H
+typedef struct Vis Vis;
+#endif
+
typedef struct {
Buffer buf;
bool linewise; /* place register content on a new line when inserting? */
enum {
REGISTER_NORMAL,
REGISTER_BLACKHOLE,
+ REGISTER_CLIPBOARD,
} type;
} Register;
void register_release(Register *reg);
-const char *register_get(Register *reg, size_t *len);
-bool register_put(Register *reg, Text *txt, Filerange *range);
+const char *register_get(Vis*, Register*reg, size_t *len);
+bool register_put(Vis*, Register *reg, Text *txt, Filerange *range);
bool register_append(Register *reg, Text *txt, Filerange *range);
#endif
diff --git a/ui.h b/ui.h
index 61fa4df..314bc9d 100644
--- a/ui.h
+++ b/ui.h
@@ -38,9 +38,9 @@ enum UiStyles {
UI_STYLE_MAX,
};
+#include "vis.h"
#include "text.h"
#include "view.h"
-#include "vis.h"
struct Ui {
bool (*init)(Ui*, Vis*);
diff --git a/vis-copy b/vis-copy
new file mode 100755
index 0000000..80d1a07
--- /dev/null
+++ b/vis-copy
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ ! -z "$DISPLAY" ]; then
+ exec xsel -i
+elif type pbcopy >/dev/null 2>&1; then
+ exec pbcopy
+else
+ echo "System clipboard not supported" 1>&2
+ exit 1
+fi
diff --git a/vis-operators.c b/vis-operators.c
index fe410dc..7901851 100644
--- a/vis-operators.c
+++ b/vis-operators.c
@@ -8,7 +8,7 @@
static size_t op_delete(Vis *vis, Text *txt, OperatorContext *c) {
c->reg->linewise = c->linewise;
- register_put(c->reg, txt, &c->range);
+ register_put(vis, c->reg, txt, &c->range);
text_delete_range(txt, &c->range);
size_t pos = c->range.start;
if (c->linewise && pos == text_size(txt))
@@ -24,7 +24,7 @@ static size_t op_change(Vis *vis, Text *txt, OperatorContext *c) {
static size_t op_yank(Vis *vis, Text *txt, OperatorContext *c) {
c->reg->linewise = c->linewise;
- register_put(c->reg, txt, &c->range);
+ register_put(vis, c->reg, txt, &c->range);
return c->pos;
}
@@ -52,7 +52,7 @@ static size_t op_put(Vis *vis, Text *txt, OperatorContext *c) {
}
size_t len;
- const char *data = register_get(c->reg, &len);
+ const char *data = register_get(vis, c->reg, &len);
for (int i = 0; i < c->count; i++) {
text_insert(txt, pos, data, len);
diff --git a/vis-paste b/vis-paste
new file mode 100755
index 0000000..232da2e
--- /dev/null
+++ b/vis-paste
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ ! -z "$DISPLAY" ]; then
+ exec xsel -o
+elif type pbpaste >/dev/null 2>&1; then
+ exec pbpaste
+else
+ echo "System clipboard not supported" 1>&2
+ exit 1
+fi
diff --git a/vis.c b/vis.c
index 3edc766..b6d6b49 100644
--- a/vis.c
+++ b/vis.c
@@ -316,6 +316,7 @@ Vis *vis_new(Ui *ui, VisEvent *event) {
vis->tabwidth = 8;
vis->expandtab = false;
vis->registers[VIS_REG_BLACKHOLE].type = REGISTER_BLACKHOLE;
+ vis->registers[VIS_REG_CLIPBOARD].type = REGISTER_CLIPBOARD;
action_reset(&vis->action);
if (!(vis->search_pattern = text_regex_new()))
goto err;
@@ -1005,7 +1006,7 @@ void vis_register_set(Vis *vis, enum VisRegister reg) {
const char *vis_register_get(Vis *vis, enum VisRegister reg, size_t *len) {
if (reg < LENGTH(vis->registers))
- return register_get(&vis->registers[reg], len);
+ return register_get(vis, &vis->registers[reg], len);
*len = 0;
return NULL;
}
diff --git a/vis.h b/vis.h
index 8de1f51..00d95a6 100644
--- a/vis.h
+++ b/vis.h
@@ -349,6 +349,7 @@ enum VisRegister {
VIS_REG_z,
VIS_REG_DEFAULT, /* used when no other register is specified */
VIS_REG_BLACKHOLE, /* /dev/null register */
+ VIS_REG_CLIPBOARD, /* system clipboard register */
VIS_REG_PROMPT, /* internal register which shadows DEFAULT in PROMPT mode */
VIS_REG_INVALID, /* has to be the last enum member */
};