diff -r fe61798f04a5 config.def.h --- a/config.def.h Sun Apr 03 21:40:33 2011 +0200 +++ b/config.def.h Sun Apr 10 02:54:14 2011 +0100 @@ -4,6 +4,7 @@ #define BOLDFONT "-*-*-bold-r-*-*-*-120-75-75-*-60-*-*" #define BORDER 2 #define SHELL "/bin/sh" +#define EDIT_TERMINAL "st" /* Terminal colors */ static const char *colorname[] = { diff -r fe61798f04a5 st.c --- a/st.c Sun Apr 03 21:40:33 2011 +0200 +++ b/st.c Sun Apr 10 02:54:14 2011 +0100 @@ -402,9 +403,117 @@ void bpress(XEvent *e) { - sel.mode = 1; - sel.ex = sel.bx = (e->xbutton.x - BORDER)/xw.cw; - sel.ey = sel.by = (e->xbutton.y - BORDER)/xw.ch; + if(e->xbutton.button == 2){ + seledit(); + }else{ + sel.mode = 1; + sel.ex = sel.bx = (e->xbutton.x - BORDER)/xw.cw; + sel.ey = sel.by = (e->xbutton.y - BORDER)/xw.ch; + } +} + +void noop(int x) { + /* FIXME: dirty hack? */ +} + +int system2(char *const *args) { + pid_t pid; + int ret; + + switch((pid = fork())){ + case -1: + return -1; + + default: + break; + + case 0: + execvp(*args, args); + die("exec(%s)", *args); + } + + /* parent */ + signal(SIGCHLD, noop); + if(waitpid(pid, &ret, 0) != pid) + ret = -1; + signal(SIGCHLD, sigchld); + + return ret; +} + +void +seledit(void) { + struct stat st; + char fname[64], cmd[128]; + char *env = getenv("TMPDIR"); + char *sel = NULL; + int fd; + int x, y; + + DEFAULT(env, "/tmp"); + snprintf(fname, sizeof fname, "%s/st_edXXXXXX", env); + + fd = mkstemp(fname); + if(fd == -1){ + perror("mkstemp()"); + return; + } + + for(y = 0; y < term.row; y++) { + for(x = 0; x < term.col; x++) + if(term.line[y][x].state && isprint(term.line[y][x].c[0])) + write(fd, term.line[y][x].c, utf8size(term.line[y][x].c)); + else + break; /* assume the rest of the line is empty - XXX: kludge alert */ + + write(fd, "\n", 1); + } + close(fd); + + env = getenv("VISUAL"); + DEFAULT(env, getenv("EDITOR")); + DEFAULT(env, "vi"); + + { + char *const system_args[] = { EDIT_TERMINAL, "-e", env, fname, NULL }; + + if(system2(system_args) != 0){ + perror(cmd); + goto bail; + } + } + + fd = open(fname, O_RDONLY); + if(fd == -1){ + perror(fname); + goto bail; + } + + if(fstat(fd, &st) != 0){ + perror("fstat()"); + goto bail; + } + + sel = malloc(st.st_size + 1); + if(!sel){ + perror("malloc()"); + goto bail; + } + + if(read(fd, sel, st.st_size) == -1){ + perror("read()"); + goto bail; + } + + sel[st.st_size] = '\0'; + + xsetsel(sel); + sel = NULL; /* prevent sel.clip deallocation by the following free() */ + +bail: + free(sel); + close(fd); + remove(fname); } void