change normal mode key
[st.git] / x.c
diff --git a/x.c b/x.c
index a358386..5989947 100644 (file)
--- a/x.c
+++ b/x.c
@@ -5,6 +5,7 @@
 #include <locale.h>
 #include <signal.h>
 #include <sys/select.h>
+#include <sys/wait.h>
 #include <time.h>
 #include <unistd.h>
 #include <libgen.h>
@@ -20,6 +21,7 @@ char *argv0;
 #include "arg.h"
 #include "st.h"
 #include "win.h"
+#include "normalMode.h"
 
 /* types used in config.h */
 typedef struct {
@@ -73,6 +75,7 @@ static void zoom(const Arg *);
 static void zoomabs(const Arg *);
 static void zoomreset(const Arg *);
 static void ttysend(const Arg *);
+static void plumber(const Arg *);
 
 /* config.h for applying patches and the configuration. */
 #include "config.h"
@@ -195,11 +198,13 @@ static void selnotify(XEvent *);
 static void selclear_(XEvent *);
 static void selrequest(XEvent *);
 static void setsel(char *, Time);
+static void plumb(char *sel);
 static void mousesel(XEvent *, int);
 static void mousereport(XEvent *);
 static char *kmap(KeySym, uint);
 static int match(uint, uint);
 
+
 static void run(void);
 static void usage(void);
 
@@ -230,6 +235,7 @@ static void (*handler[LASTEvent])(XEvent *) = {
 };
 
 /* Globals */
+static int plumbsel;
 static DC dc;
 static XWindow xw;
 static XSelection xsel;
@@ -276,6 +282,7 @@ clipcopy(const Arg *dummy)
 
        free(xsel.clipboard);
        xsel.clipboard = NULL;
+       xsetsel(getsel());
 
        if (xsel.primary != NULL) {
                xsel.clipboard = xstrdup(xsel.primary);
@@ -343,6 +350,12 @@ ttysend(const Arg *arg)
        ttywrite(arg->s, strlen(arg->s), 1);
 }
 
+void
+plumber(const Arg *arg)
+{
+    plumb(xsel.primary);
+}
+
 int
 evcol(XEvent *e)
 {
@@ -696,6 +709,37 @@ xsetsel(char *str)
        setsel(str, CurrentTime);
 }
 
+void
+plumbinit()
+{
+       for(plumbsel = 0; plumb_cmd[plumbsel]; plumbsel++);
+}
+
+void
+plumb(char *sel) {
+       if (sel == NULL)
+               return;
+       char cwd[PATH_MAX];
+       pid_t child;
+       if (subprocwd(cwd) != 0)
+               return;
+
+       plumb_cmd[plumbsel] = sel;
+
+       switch(child = fork()) {
+               case -1:
+                       return;
+               case 0:
+                       if (chdir(cwd) != 0)
+                               exit(1);
+                       if (execvp(plumb_cmd[0], plumb_cmd) == -1)
+                               exit(1);
+                       exit(0);
+               default:
+                       waitpid(child, NULL, 0);
+       }
+}
+
 void
 brelease(XEvent *e)
 {
@@ -787,6 +831,8 @@ xloadcolor(int i, const char *name, Color *ncolor)
        return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
 }
 
+void normalMode() { historyModeToggle((win.mode ^=MODE_NORMAL) & MODE_NORMAL); }
+
 void
 xloadcols(void)
 {
@@ -1238,8 +1284,10 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
 
        for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
                /* Fetch rune and mode for current glyph. */
-               rune = glyphs[i].u;
-               mode = glyphs[i].mode;
+               Glyph g = glyphs[i];
+               historyOverlay(x+i, y, &g);
+               rune = g.u;
+               mode = g.mode;
 
                /* Skip dummy wide-character spacing. */
                if (mode == ATTR_WDUMMY)
@@ -1622,6 +1670,8 @@ xsettitle(char *p)
 int
 xstartdraw(void)
 {
+       if (IS_SET(MODE_VISIBLE))
+               XCopyArea(xw.dpy, xw.win, xw.buf, dc.gc, 0, 0, win.w, win.h, 0, 0);
        return IS_SET(MODE_VISIBLE);
 }
 
@@ -1636,6 +1686,7 @@ xdrawline(Line line, int x1, int y1, int x2)
        i = ox = 0;
        for (x = x1; x < x2 && i < numspecs; x++) {
                new = line[x];
+               historyOverlay(x, y1, &new);
                if (new.mode == ATTR_WDUMMY)
                        continue;
                if (selected(x, y1))
@@ -1830,6 +1881,11 @@ kpress(XEvent *ev)
                len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
        else
                len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
+       if (IS_SET(MODE_NORMAL)) {
+               if (kpressHist(buf, len, match(ControlMask, e->state), &ksym)
+                                                     == finished) normalMode();
+               return;
+       }
        /* 1. shortcuts */
        for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
                if (ksym == bp->keysym && match(bp->mod, e->state)) {
@@ -2116,6 +2172,7 @@ main(int argc, char *argv[])
        } ARGEND;
 
 run:
+       plumbinit();
        if (argc > 0) /* eat all remaining arguments */
                opt_cmd = argv;