-
INCS = -Iinc/
LIBEDIT_OBJS = \
libedit/mouse.o \
libedit/screen.o \
libedit/utf8.o \
- libedit/utils.o
+ libedit/utils.o \
+ libedit/exec.o \
+ libedit/clip.o
LIBX_OBJS = \
libx/x11.o
bool risword(Rune r);
bool risblank(Rune r);
char* stringdup(const char* str);
+char* fdgets(int fd);
/* Buffer management functions
*****************************************************************************/
unsigned buf_byline(Buf* buf, unsigned pos, int count);
unsigned buf_getcol(Buf* buf, unsigned pos);
unsigned buf_setcol(Buf* buf, unsigned pos, unsigned col);
+char* buf_getstr(Buf* buf, unsigned beg, unsigned end);
+unsigned buf_putstr(Buf* buf, unsigned beg, unsigned end, char* str);
/* Charset Handling
*****************************************************************************/
unsigned screen_setcell(unsigned row, unsigned col, uint32_t attr, Rune r);
UGlyph* screen_getglyph(unsigned row, unsigned col, unsigned* scrwidth);
+/* Command Executions
+ *****************************************************************************/
+typedef struct {
+ int pid;
+ int in;
+ int out;
+ int err;
+} Process;
+
+int execute(char** cmd, Process* proc);
+void detach(Process* proc);
+void terminate(Process* proc, int sig);
+char* cmdread(char** cmd);
+void cmdwrite(char** cmd, char* text);
+
+/* Clipboard Access
+ *****************************************************************************/
+void clipcopy(char* text);
+char* clippaste(void);
+
/* Color Scheme Handling
*****************************************************************************/
/* color indexes for the colorscheme */
}
return curr;
}
+
+char* buf_getstr(Buf* buf, unsigned beg, unsigned end) {
+ char utf[UTF_MAX] = {0};
+ size_t len = 0;
+ char* str = NULL;
+ for (; beg <= end; beg++) {
+ Rune rune = buf_get(buf, beg);
+ if (rune == RUNE_CRLF) {
+ str = realloc(str, len + 2);
+ str[len + 1] = '\r';
+ str[len + 2] = '\n';
+ len += 2;
+ } else {
+ size_t n = utf8encode(utf, rune);
+ str = realloc(str, len + n);
+ memcpy(str+len, utf, n);
+ len += n;
+ }
+ }
+ str = realloc(str, len+1);
+ if (str) str[len] = '\0';
+ return str;
+}
+
+unsigned buf_putstr(Buf* buf, unsigned beg, unsigned end, char* str) {
+ bool locked = buf_locked(buf);
+ buf_setlocked(buf, false);
+ /* delete the selected text first */
+ for (unsigned i = beg; ((end-beg) > 1) && (i <= end); i++)
+ buf_del(buf, beg);
+ /* insert the text */
+ while (*str) {
+ Rune rune = 0;
+ size_t length = 0;
+ while (!utf8decode(&rune, &length, *str++));
+ buf_ins(buf, beg++, rune);
+ }
+ buf_setlocked(buf, locked);
+ return beg;
+}
--- /dev/null
+#include <stdc.h>
+#include <utf.h>
+#include <edit.h>
+#include <unistd.h>
+
+#ifdef __MACH__
+char* CopyCmd[] = { "pbcopy", NULL };
+char* PasteCmd[] = { "pbpaste", NULL };
+#else
+char* CopyCmd[] = { "xsel", "-bi", NULL };
+char* PasteCmd[] = { "xsel", "-bo", NULL };
+#endif
+
+void clipcopy(char* text) {
+ cmdwrite(CopyCmd, text);
+}
+
+char* clippaste(void) {
+ return cmdread(PasteCmd);
+}
--- /dev/null
+#include <stdc.h>
+#include <utf.h>
+#include <edit.h>
+
+#define _POSIX_C_SOURCE 200809L
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#define PIPE_READ 0
+#define PIPE_WRITE 1
+
+int execute(char** cmd, Process* proc) {
+ int inpipe[2], outpipe[2], errpipe[2];
+ /* create the pipes */
+ if ((pipe(inpipe) < 0) || (pipe(outpipe) < 0) || (pipe(errpipe) < 0))
+ return -1;
+ /* create the process */
+ proc->pid = fork();
+ if (proc->pid < 0) {
+ /* signal that we failed to fork */
+ proc->in = -1;
+ proc->out = -1;
+ proc->err = -1;
+ } else if (0 == proc->pid) {
+ /* redirect child process's io to the pipes */
+ if ((dup2(inpipe[PIPE_READ], STDIN_FILENO) < 0) ||
+ (dup2(outpipe[PIPE_WRITE], STDOUT_FILENO) < 0) ||
+ (dup2(errpipe[PIPE_WRITE], STDERR_FILENO) < 0)) {
+ perror("failed to pipe");
+ exit(1);
+ }
+ /* execute the process */
+ close(inpipe[PIPE_WRITE]);
+ close(outpipe[PIPE_READ]);
+ close(errpipe[PIPE_READ]);
+ exit(execvp(cmd[0], cmd));
+ } else {
+ close(inpipe[PIPE_READ]);
+ close(outpipe[PIPE_WRITE]);
+ close(errpipe[PIPE_WRITE]);
+ proc->in = inpipe[PIPE_WRITE];
+ proc->out = outpipe[PIPE_READ];
+ proc->err = errpipe[PIPE_READ];
+ }
+ return proc->pid;
+}
+
+void detach(Process* proc) {
+ close(proc->in);
+ close(proc->out);
+ close(proc->err);
+}
+
+void terminate(Process* proc, int sig) {
+ detach(proc);
+ kill(proc->pid, sig);
+}
+
+char* cmdread(char** cmd) {
+ Process proc;
+ if (execute(cmd, &proc) < 0) {
+ perror("failed to execute");
+ return NULL;
+ }
+ char* str = fdgets(proc.out);
+ detach(&proc);
+ waitpid(proc.pid, NULL, 0);
+ return str;
+}
+
+void cmdwrite(char** cmd, char* text) {
+ Process proc;
+ if (execute(cmd, &proc) < 0) {
+ perror("failed to execute");
+ return;
+ }
+ if (write(proc.in, text, strlen(text)) < 0) {
+ perror("failed to write");
+ return;
+ }
+ detach(&proc);
+ waitpid(proc.pid, NULL, 0);
+}
/*****************************************************************************/
+static void yank_selection(void) {
+ char* str = buf_getstr(&Buffer, SelBeg, SelEnd);
+ clipcopy(str);
+ free(str);
+}
+
+static void paste_after(void) {
+ char* str = clippaste();
+ buf_putstr(&Buffer, SelBeg, SelEnd, str);
+ free(str);
+}
+
+/*****************************************************************************/
+
typedef struct {
Rune key;
void (*action)(void);
{ KEY_DELETE, dot_delete },
/* Copy/Paste */
- //{ 'y', yank_selection },
+ { 'y', yank_selection },
+ { 'p', paste_after },
//{ 'Y', yank_line },
- //{ 'p', paste_after },
//{ 'P', paste_before },
/* context sensitive language */
strcpy(ns,s);
return ns;
}
+
+char* fdgets(int fd) {
+ char buf[256];
+ size_t len = 0, nread = 0;
+ char* str = NULL;
+ while ((nread = read(fd, buf, 256)) > 0) {
+ str = realloc(str, len + nread + 1);
+ memcpy(str+len, buf, nread);
+ len += nread;
+ }
+ if (str) str[len] = '\0';
+ return str;
+}