Back to main page
summaryrefslogtreecommitdiff
path: root/patches
diff options
context:
space:
mode:
Diffstat (limited to 'patches')
-rw-r--r--patches/notes1
-rw-r--r--patches/st-anysize-0.8.4.diff152
-rw-r--r--patches/st-clipboard-20180309-c5ba9c0.diff13
-rw-r--r--patches/st-focus-20200731-43a395a.diff271
-rw-r--r--patches/st-keyboard_select-20200617-9ba7ecf.diff319
-rw-r--r--patches/st-newterm-20220221-0.8.5.diff111
6 files changed, 867 insertions, 0 deletions
diff --git a/patches/notes b/patches/notes
new file mode 100644
index 0000000..692f7db
--- /dev/null
+++ b/patches/notes
@@ -0,0 +1 @@
+changed XK_s to XK_v on line 2813 in st.c
diff --git a/patches/st-anysize-0.8.4.diff b/patches/st-anysize-0.8.4.diff
new file mode 100644
index 0000000..2f9a291
--- /dev/null
+++ b/patches/st-anysize-0.8.4.diff
@@ -0,0 +1,152 @@
+diff --git a/x.c b/x.c
+index 8bf998e..e2cda07 100644
+--- a/x.c
++++ b/x.c
+@@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec;
+ typedef struct {
+ int tw, th; /* tty width and height */
+ int w, h; /* window width and height */
++ int hborderpx, vborderpx;
+ int ch; /* char height */
+ int cw; /* char width */
+ int mode; /* window state/mode flags */
+@@ -331,7 +332,7 @@ ttysend(const Arg *arg)
+ int
+ evcol(XEvent *e)
+ {
+- int x = e->xbutton.x - borderpx;
++ int x = e->xbutton.x - win.hborderpx;
+ LIMIT(x, 0, win.tw - 1);
+ return x / win.cw;
+ }
+@@ -339,7 +340,7 @@ evcol(XEvent *e)
+ int
+ evrow(XEvent *e)
+ {
+- int y = e->xbutton.y - borderpx;
++ int y = e->xbutton.y - win.vborderpx;
+ LIMIT(y, 0, win.th - 1);
+ return y / win.ch;
+ }
+@@ -723,6 +724,9 @@ cresize(int width, int height)
+ col = MAX(1, col);
+ row = MAX(1, row);
+
++ win.hborderpx = (win.w - col * win.cw) / 2;
++ win.vborderpx = (win.h - row * win.ch) / 2;
++
+ tresize(col, row);
+ xresize(col, row);
+ ttyresize(win.tw, win.th);
+@@ -840,8 +844,8 @@ xhints(void)
+ sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
+ sizeh->height = win.h;
+ sizeh->width = win.w;
+- sizeh->height_inc = win.ch;
+- sizeh->width_inc = win.cw;
++ sizeh->height_inc = 1;
++ sizeh->width_inc = 1;
+ sizeh->base_height = 2 * borderpx;
+ sizeh->base_width = 2 * borderpx;
+ sizeh->min_height = win.ch + 2 * borderpx;
+@@ -1123,8 +1127,8 @@ xinit(int cols, int rows)
+ xloadcols();
+
+ /* adjust fixed window geometry */
+- win.w = 2 * borderpx + cols * win.cw;
+- win.h = 2 * borderpx + rows * win.ch;
++ win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw;
++ win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch;
+ if (xw.gm & XNegative)
+ xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
+ if (xw.gm & YNegative)
+@@ -1213,7 +1217,7 @@ xinit(int cols, int rows)
+ int
+ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
+ {
+- float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
++ float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp;
+ ushort mode, prevmode = USHRT_MAX;
+ Font *font = &dc.font;
+ int frcflags = FRC_NORMAL;
+@@ -1346,7 +1350,7 @@ void
+ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
+ {
+ int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
+- int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
++ int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch,
+ width = charlen * win.cw;
+ Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
+ XRenderColor colfg, colbg;
+@@ -1436,17 +1440,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
+
+ /* Intelligent cleaning up of the borders. */
+ if (x == 0) {
+- xclear(0, (y == 0)? 0 : winy, borderpx,
++ xclear(0, (y == 0)? 0 : winy, win.vborderpx,
+ winy + win.ch +
+- ((winy + win.ch >= borderpx + win.th)? win.h : 0));
++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0));
+ }
+- if (winx + width >= borderpx + win.tw) {
++ if (winx + width >= win.hborderpx + win.tw) {
+ xclear(winx + width, (y == 0)? 0 : winy, win.w,
+- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch)));
+ }
+ if (y == 0)
+- xclear(winx, 0, winx + width, borderpx);
+- if (winy + win.ch >= borderpx + win.th)
++ xclear(winx, 0, winx + width, win.vborderpx);
++ if (winy + win.ch >= win.vborderpx + win.th)
+ xclear(winx, winy + win.ch, winx + width, win.h);
+
+ /* Clean up the region we want to draw to. */
+@@ -1540,35 +1544,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
+ case 3: /* Blinking Underline */
+ case 4: /* Steady Underline */
+ XftDrawRect(xw.draw, &drawcol,
+- borderpx + cx * win.cw,
+- borderpx + (cy + 1) * win.ch - \
++ win.hborderpx + cx * win.cw,
++ win.vborderpx + (cy + 1) * win.ch - \
+ cursorthickness,
+ win.cw, cursorthickness);
+ break;
+ case 5: /* Blinking bar */
+ case 6: /* Steady bar */
+ XftDrawRect(xw.draw, &drawcol,
+- borderpx + cx * win.cw,
+- borderpx + cy * win.ch,
++ win.hborderpx + cx * win.cw,
++ win.vborderpx + cy * win.ch,
+ cursorthickness, win.ch);
+ break;
+ }
+ } else {
+ XftDrawRect(xw.draw, &drawcol,
+- borderpx + cx * win.cw,
+- borderpx + cy * win.ch,
++ win.hborderpx + cx * win.cw,
++ win.vborderpx + cy * win.ch,
+ win.cw - 1, 1);
+ XftDrawRect(xw.draw, &drawcol,
+- borderpx + cx * win.cw,
+- borderpx + cy * win.ch,
++ win.hborderpx + cx * win.cw,
++ win.vborderpx + cy * win.ch,
+ 1, win.ch - 1);
+ XftDrawRect(xw.draw, &drawcol,
+- borderpx + (cx + 1) * win.cw - 1,
+- borderpx + cy * win.ch,
++ win.hborderpx + (cx + 1) * win.cw - 1,
++ win.vborderpx + cy * win.ch,
+ 1, win.ch - 1);
+ XftDrawRect(xw.draw, &drawcol,
+- borderpx + cx * win.cw,
+- borderpx + (cy + 1) * win.ch - 1,
++ win.hborderpx + cx * win.cw,
++ win.vborderpx + (cy + 1) * win.ch - 1,
+ win.cw, 1);
+ }
+ }
diff --git a/patches/st-clipboard-20180309-c5ba9c0.diff b/patches/st-clipboard-20180309-c5ba9c0.diff
new file mode 100644
index 0000000..4a14e2b
--- /dev/null
+++ b/patches/st-clipboard-20180309-c5ba9c0.diff
@@ -0,0 +1,13 @@
+diff --git a/x.c b/x.c
+index 13fa9f4..88fd341 100644
+--- a/x.c
++++ b/x.c
+@@ -624,6 +624,8 @@ setsel(char *str, Time t)
+ XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
+ if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
+ selclear();
++
++ xclipcopy();
+ }
+
+ void
diff --git a/patches/st-focus-20200731-43a395a.diff b/patches/st-focus-20200731-43a395a.diff
new file mode 100644
index 0000000..809cb46
--- /dev/null
+++ b/patches/st-focus-20200731-43a395a.diff
@@ -0,0 +1,271 @@
+From 10fa2b6aebceb3a12219ef25376297b063638bd9 Mon Sep 17 00:00:00 2001
+From: Julius Huelsmann <juliusHuelsmann@gmail.com>
+Date: Fri, 31 Jul 2020 10:13:35 +0200
+Subject: [PATCH] patch: focus
+
+---
+ config.def.h | 5 ++++
+ config.mk | 2 +-
+ st.c | 1 -
+ st.h | 2 ++
+ x.c | 72 +++++++++++++++++++++++++++++++++++++++-------------
+ 5 files changed, 62 insertions(+), 20 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 0895a1f..577d1f1 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -84,6 +84,9 @@ char *termname = "st-256color";
+ */
+ unsigned int tabspaces = 8;
+
++/* bg opacity */
++float alpha = 0.8, alphaUnfocused = 0.6;
++
+ /* Terminal colors (16 first used in escape sequence) */
+ static const char *colorname[] = {
+ /* 8 normal colors */
+@@ -111,6 +114,7 @@ static const char *colorname[] = {
+ /* more colors can be added after 255 to use with DefaultXX */
+ "#cccccc",
+ "#555555",
++ "black",
+ };
+
+
+@@ -122,6 +126,7 @@ unsigned int defaultfg = 7;
+ unsigned int defaultbg = 0;
+ static unsigned int defaultcs = 256;
+ static unsigned int defaultrcs = 257;
++unsigned int bg = 17, bgUnfocused = 16;
+
+ /*
+ * Default shape of cursor
+diff --git a/config.mk b/config.mk
+index beafc35..ddc65ae 100644
+--- a/config.mk
++++ b/config.mk
+@@ -16,7 +16,7 @@ PKG_CONFIG = pkg-config
+ INCS = -I$(X11INC) \
+ `$(PKG_CONFIG) --cflags fontconfig` \
+ `$(PKG_CONFIG) --cflags freetype2`
+-LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
++LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\
+ `$(PKG_CONFIG) --libs fontconfig` \
+ `$(PKG_CONFIG) --libs freetype2`
+
+diff --git a/st.c b/st.c
+index 0ce6ac2..c7f40c8 100644
+--- a/st.c
++++ b/st.c
+@@ -194,7 +194,6 @@ static void tsetscroll(int, int);
+ static void tswapscreen(void);
+ static void tsetmode(int, int, int *, int);
+ static int twrite(const char *, int, int);
+-static void tfulldirt(void);
+ static void tcontrolcode(uchar );
+ static void tdectest(char );
+ static void tdefutf8(char);
+diff --git a/st.h b/st.h
+index d978458..44cb3fd 100644
+--- a/st.h
++++ b/st.h
+@@ -79,6 +79,7 @@ typedef union {
+
+ void die(const char *, ...);
+ void redraw(void);
++void tfulldirt(void);
+ void draw(void);
+
+ void printscreen(const Arg *);
+@@ -122,3 +123,4 @@ extern char *termname;
+ extern unsigned int tabspaces;
+ extern unsigned int defaultfg;
+ extern unsigned int defaultbg;
++extern float alpha, alphaUnfocused;
+diff --git a/x.c b/x.c
+index e5f1737..a2e820f 100644
+--- a/x.c
++++ b/x.c
+@@ -105,6 +105,7 @@ typedef struct {
+ XSetWindowAttributes attrs;
+ int scr;
+ int isfixed; /* is fixed geometry? */
++ int depth; /* bit depth */
+ int l, t; /* left and top offset */
+ int gm; /* geometry mask */
+ } XWindow;
+@@ -243,6 +244,7 @@ static char *usedfont = NULL;
+ static double usedfontsize = 0;
+ static double defaultfontsize = 0;
+
++static char *opt_alpha = NULL;
+ static char *opt_class = NULL;
+ static char **opt_cmd = NULL;
+ static char *opt_embed = NULL;
+@@ -252,6 +254,8 @@ static char *opt_line = NULL;
+ static char *opt_name = NULL;
+ static char *opt_title = NULL;
+
++static int focused = 0;
++
+ static int oldbutton = 3; /* button event on startup: 3 = release */
+
+ void
+@@ -734,7 +738,7 @@ xresize(int col, int row)
+
+ XFreePixmap(xw.dpy, xw.buf);
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
+- DefaultDepth(xw.dpy, xw.scr));
++ xw.depth);
+ XftDrawChange(xw.draw, xw.buf);
+ xclear(0, 0, win.w, win.h);
+
+@@ -772,28 +776,38 @@ xloadcolor(int i, const char *name, Color *ncolor)
+ return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
+ }
+
++void
++xloadalpha(void)
++{
++ float const usedAlpha = focused ? alpha : alphaUnfocused;
++ if (opt_alpha) alpha = strtof(opt_alpha, NULL);
++ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * usedAlpha);
++ dc.col[defaultbg].pixel &= 0x00FFFFFF;
++ dc.col[defaultbg].pixel |= (unsigned char)(0xff * usedAlpha) << 24;
++}
++
+ void
+ xloadcols(void)
+ {
+- int i;
+ static int loaded;
+ Color *cp;
+
+- if (loaded) {
+- for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
+- XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
+- } else {
+- dc.collen = MAX(LEN(colorname), 256);
+- dc.col = xmalloc(dc.collen * sizeof(Color));
++ if (!loaded) {
++ dc.collen = 1 + (defaultbg = MAX(LEN(colorname), 256));
++ dc.col = xmalloc((dc.collen) * sizeof(Color));
+ }
+
+- for (i = 0; i < dc.collen; i++)
++ for (int i = 0; i+1 < dc.collen; ++i)
+ if (!xloadcolor(i, NULL, &dc.col[i])) {
+ if (colorname[i])
+ die("could not allocate color '%s'\n", colorname[i]);
+ else
+ die("could not allocate color %d\n", i);
+ }
++ if (dc.collen) // cannot die, as the color is already loaded.
++ xloadcolor(focused ?bg :bgUnfocused, NULL, &dc.col[defaultbg]);
++
++ xloadalpha();
+ loaded = 1;
+ }
+
+@@ -1103,11 +1117,23 @@ xinit(int cols, int rows)
+ Window parent;
+ pid_t thispid = getpid();
+ XColor xmousefg, xmousebg;
++ XWindowAttributes attr;
++ XVisualInfo vis;
+
+ if (!(xw.dpy = XOpenDisplay(NULL)))
+ die("can't open display\n");
+ xw.scr = XDefaultScreen(xw.dpy);
+- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
++
++ if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) {
++ parent = XRootWindow(xw.dpy, xw.scr);
++ xw.depth = 32;
++ } else {
++ XGetWindowAttributes(xw.dpy, parent, &attr);
++ xw.depth = attr.depth;
++ }
++
++ XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis);
++ xw.vis = vis.visual;
+
+ /* font */
+ if (!FcInit())
+@@ -1117,7 +1143,7 @@ xinit(int cols, int rows)
+ xloadfonts(usedfont, 0);
+
+ /* colors */
+- xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
++ xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
+ xloadcols();
+
+ /* adjust fixed window geometry */
+@@ -1137,19 +1163,15 @@ xinit(int cols, int rows)
+ | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
+ xw.attrs.colormap = xw.cmap;
+
+- if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
+- parent = XRootWindow(xw.dpy, xw.scr);
+ xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
+- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
++ win.w, win.h, 0, xw.depth, InputOutput,
+ xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
+ | CWEventMask | CWColormap, &xw.attrs);
+
+ memset(&gcvalues, 0, sizeof(gcvalues));
+ gcvalues.graphics_exposures = False;
+- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
+- &gcvalues);
+- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
+- DefaultDepth(xw.dpy, xw.scr));
++ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
++ dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues);
+ XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
+ XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
+
+@@ -1730,12 +1752,22 @@ focus(XEvent *ev)
+ xseturgency(0);
+ if (IS_SET(MODE_FOCUS))
+ ttywrite("\033[I", 3, 0);
++ if (!focused) {
++ focused = 1;
++ xloadcols();
++ tfulldirt();
++ }
+ } else {
+ if (xw.ime.xic)
+ XUnsetICFocus(xw.ime.xic);
+ win.mode &= ~MODE_FOCUSED;
+ if (IS_SET(MODE_FOCUS))
+ ttywrite("\033[O", 3, 0);
++ if (focused) {
++ focused = 0;
++ xloadcols();
++ tfulldirt();
++ }
+ }
+ }
+
+@@ -1994,6 +2026,9 @@ main(int argc, char *argv[])
+ case 'a':
+ allowaltscreen = 0;
+ break;
++ case 'A':
++ opt_alpha = EARGF(usage());
++ break;
+ case 'c':
+ opt_class = EARGF(usage());
+ break;
+@@ -2045,6 +2080,7 @@ run:
+ XSetLocaleModifiers("");
+ cols = MAX(cols, 1);
+ rows = MAX(rows, 1);
++ defaultbg = MAX(LEN(colorname), 256);
+ tnew(cols, rows);
+ xinit(cols, rows);
+ xsetenv();
+--
+2.28.0
+
diff --git a/patches/st-keyboard_select-20200617-9ba7ecf.diff b/patches/st-keyboard_select-20200617-9ba7ecf.diff
new file mode 100644
index 0000000..fac41ea
--- /dev/null
+++ b/patches/st-keyboard_select-20200617-9ba7ecf.diff
@@ -0,0 +1,319 @@
+diff --git a/config.def.h b/config.def.h
+index 6f05dce..54612d1 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -199,6 +199,7 @@ static Shortcut shortcuts[] = {
+ { TERMMOD, XK_Y, selpaste, {.i = 0} },
+ { ShiftMask, XK_Insert, selpaste, {.i = 0} },
+ { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
++ { TERMMOD, XK_Escape, keyboard_select,{.i = 0} },
+ };
+
+ /*
+diff --git a/st.c b/st.c
+index ef8abd5..0c6c6ca 100644
+--- a/st.c
++++ b/st.c
+@@ -16,6 +16,8 @@
+ #include <termios.h>
+ #include <unistd.h>
+ #include <wchar.h>
++#include <X11/keysym.h>
++#include <X11/X.h>
+
+ #include "st.h"
+ #include "win.h"
+@@ -2487,6 +2489,9 @@ tresize(int col, int row)
+ int *bp;
+ TCursor c;
+
++ if ( row < term.row || col < term.col )
++ toggle_winmode(trt_kbdselect(XK_Escape, NULL, 0));
++
+ if (col < 1 || row < 1) {
+ fprintf(stderr,
+ "tresize: error resizing to %dx%d\n", col, row);
+@@ -2612,3 +2617,220 @@ redraw(void)
+ tfulldirt();
+ draw();
+ }
++
++void set_notifmode(int type, KeySym ksym) {
++ static char *lib[] = { " MOVE ", " SEL "};
++ static Glyph *g, *deb, *fin;
++ static int col, bot;
++
++ if ( ksym == -1 ) {
++ free(g);
++ col = term.col, bot = term.bot;
++ g = xmalloc(col * sizeof(Glyph));
++ memcpy(g, term.line[bot], col * sizeof(Glyph));
++
++ }
++ else if ( ksym == -2 )
++ memcpy(term.line[bot], g, col * sizeof(Glyph));
++
++ if ( type < 2 ) {
++ char *z = lib[type];
++ for (deb = &term.line[bot][col - 6], fin = &term.line[bot][col]; deb < fin; z++, deb++)
++ deb->mode = ATTR_REVERSE,
++ deb->u = *z,
++ deb->fg = defaultfg, deb->bg = defaultbg;
++ }
++ else if ( type < 5 )
++ memcpy(term.line[bot], g, col * sizeof(Glyph));
++ else {
++ for (deb = &term.line[bot][0], fin = &term.line[bot][col]; deb < fin; deb++)
++ deb->mode = ATTR_REVERSE,
++ deb->u = ' ',
++ deb->fg = defaultfg, deb->bg = defaultbg;
++ term.line[bot][0].u = ksym;
++ }
++
++ term.dirty[bot] = 1;
++ drawregion(0, bot, col, bot + 1);
++}
++
++void select_or_drawcursor(int selectsearch_mode, int type) {
++ int done = 0;
++
++ if ( selectsearch_mode & 1 ) {
++ selextend(term.c.x, term.c.y, type, done);
++ xsetsel(getsel());
++ }
++ else
++ xdrawcursor(term.c.x, term.c.y, term.line[term.c.y][term.c.x],
++ term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
++}
++
++void search(int selectsearch_mode, Rune *target, int ptarget, int incr, int type, TCursor *cu) {
++ Rune *r;
++ int i, bound = (term.col * cu->y + cu->x) * (incr > 0) + incr;
++
++ for (i = term.col * term.c.y + term.c.x + incr; i != bound; i += incr) {
++ for (r = target; r - target < ptarget; r++) {
++ if ( *r == term.line[(i + r - target) / term.col][(i + r - target) % term.col].u ) {
++ if ( r - target == ptarget - 1 ) break;
++ } else {
++ r = NULL;
++ break;
++ }
++ }
++ if ( r != NULL ) break;
++ }
++
++ if ( i != bound ) {
++ term.c.y = i / term.col, term.c.x = i % term.col;
++ select_or_drawcursor(selectsearch_mode, type);
++ }
++}
++
++int trt_kbdselect(KeySym ksym, char *buf, int len) {
++ static TCursor cu;
++ static Rune target[64];
++ static int type = 1, ptarget, in_use;
++ static int sens, quant;
++ static char selectsearch_mode;
++ int i, bound, *xy;
++
++
++ if ( selectsearch_mode & 2 ) {
++ if ( ksym == XK_Return ) {
++ selectsearch_mode ^= 2;
++ set_notifmode(selectsearch_mode, -2);
++ if ( ksym == XK_Escape ) ptarget = 0;
++ return 0;
++ }
++ else if ( ksym == XK_BackSpace ) {
++ if ( !ptarget ) return 0;
++ term.line[term.bot][ptarget--].u = ' ';
++ }
++ else if ( len < 1 ) {
++ return 0;
++ }
++ else if ( ptarget == term.col || ksym == XK_Escape ) {
++ return 0;
++ }
++ else {
++ utf8decode(buf, &target[ptarget++], len);
++ term.line[term.bot][ptarget].u = target[ptarget - 1];
++ }
++
++ if ( ksym != XK_BackSpace )
++ search(selectsearch_mode, &target[0], ptarget, sens, type, &cu);
++
++ term.dirty[term.bot] = 1;
++ drawregion(0, term.bot, term.col, term.bot + 1);
++ return 0;
++ }
++
++ switch ( ksym ) {
++ case -1 :
++ in_use = 1;
++ cu.x = term.c.x, cu.y = term.c.y;
++ set_notifmode(0, ksym);
++ return MODE_KBDSELECT;
++ case XK_s :
++ if ( selectsearch_mode & 1 )
++ selclear();
++ else
++ selstart(term.c.x, term.c.y, 0);
++ set_notifmode(selectsearch_mode ^= 1, ksym);
++ break;
++ case XK_t :
++ selextend(term.c.x, term.c.y, type ^= 3, i = 0); /* 2 fois */
++ selextend(term.c.x, term.c.y, type, i = 0);
++ break;
++ case XK_slash :
++ case XK_KP_Divide :
++ case XK_question :
++ ksym &= XK_question; /* Divide to slash */
++ sens = (ksym == XK_slash) ? -1 : 1;
++ ptarget = 0;
++ set_notifmode(15, ksym);
++ selectsearch_mode ^= 2;
++ break;
++ case XK_Escape :
++ if ( !in_use ) break;
++ selclear();
++ case XK_Return :
++ set_notifmode(4, ksym);
++ term.c.x = cu.x, term.c.y = cu.y;
++ select_or_drawcursor(selectsearch_mode = 0, type);
++ in_use = quant = 0;
++ return MODE_KBDSELECT;
++ case XK_n :
++ case XK_N :
++ if ( ptarget )
++ search(selectsearch_mode, &target[0], ptarget, (ksym == XK_n) ? -1 : 1, type, &cu);
++ break;
++ case XK_BackSpace :
++ term.c.x = 0;
++ select_or_drawcursor(selectsearch_mode, type);
++ break;
++ case XK_dollar :
++ term.c.x = term.col - 1;
++ select_or_drawcursor(selectsearch_mode, type);
++ break;
++ case XK_Home :
++ term.c.x = 0, term.c.y = 0;
++ select_or_drawcursor(selectsearch_mode, type);
++ break;
++ case XK_End :
++ term.c.x = cu.x, term.c.y = cu.y;
++ select_or_drawcursor(selectsearch_mode, type);
++ break;
++ case XK_Page_Up :
++ case XK_Page_Down :
++ term.c.y = (ksym == XK_Prior ) ? 0 : cu.y;
++ select_or_drawcursor(selectsearch_mode, type);
++ break;
++ case XK_exclam :
++ term.c.x = term.col >> 1;
++ select_or_drawcursor(selectsearch_mode, type);
++ break;
++ case XK_asterisk :
++ case XK_KP_Multiply :
++ term.c.x = term.col >> 1;
++ case XK_underscore :
++ term.c.y = cu.y >> 1;
++ select_or_drawcursor(selectsearch_mode, type);
++ break;
++ default :
++ if ( ksym >= XK_0 && ksym <= XK_9 ) { /* 0-9 keyboard */
++ quant = (quant * 10) + (ksym ^ XK_0);
++ return 0;
++ }
++ else if ( ksym >= XK_KP_0 && ksym <= XK_KP_9 ) { /* 0-9 numpad */
++ quant = (quant * 10) + (ksym ^ XK_KP_0);
++ return 0;
++ }
++ else if ( ksym == XK_k || ksym == XK_h )
++ i = ksym & 1;
++ else if ( ksym == XK_l || ksym == XK_j )
++ i = ((ksym & 6) | 4) >> 1;
++ else if ( (XK_Home & ksym) != XK_Home || (i = (ksym ^ XK_Home) - 1) > 3 )
++ break;
++
++ xy = (i & 1) ? &term.c.y : &term.c.x;
++ sens = (i & 2) ? 1 : -1;
++ bound = (i >> 1 ^ 1) ? 0 : (i ^ 3) ? term.col - 1 : term.bot;
++
++ if ( quant == 0 )
++ quant++;
++
++ if ( *xy == bound && ((sens < 0 && bound == 0) || (sens > 0 && bound > 0)) )
++ break;
++
++ *xy += quant * sens;
++ if ( *xy < 0 || ( bound > 0 && *xy > bound) )
++ *xy = bound;
++
++ select_or_drawcursor(selectsearch_mode, type);
++ }
++ quant = 0;
++ return 0;
++}
+diff --git a/st.h b/st.h
+index 3d351b6..2d1a11b 100644
+--- a/st.h
++++ b/st.h
+@@ -110,6 +110,7 @@ size_t utf8encode(Rune, char *);
+ void *xmalloc(size_t);
+ void *xrealloc(void *, size_t);
+ char *xstrdup(char *);
++int trt_kbdselect(KeySym, char *, int);
+
+ /* config.h globals */
+ extern char *utmp;
+diff --git a/win.h b/win.h
+index a6ef1b9..9a47fbb 100644
+--- a/win.h
++++ b/win.h
+@@ -21,6 +21,7 @@ enum win_mode {
+ MODE_NUMLOCK = 1 << 17,
+ MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
+ |MODE_MOUSEMANY,
++ MODE_KBDSELECT = 1 << 18,
+ };
+
+ void xbell(void);
+@@ -36,4 +37,6 @@ void xsetmode(int, unsigned int);
+ void xsetpointermotion(int);
+ void xsetsel(char *);
+ int xstartdraw(void);
++void toggle_winmode(int);
++void keyboard_select(const Arg *);
+ void xximspot(int, int);
+diff --git a/x.c b/x.c
+index 210f184..b77ce54 100644
+--- a/x.c
++++ b/x.c
+@@ -1800,6 +1800,12 @@ 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_KBDSELECT) ) {
++ if ( match(XK_NO_MOD, e->state) ||
++ (XK_Shift_L | XK_Shift_R) & e->state )
++ win.mode ^= trt_kbdselect(ksym, buf, len);
++ return;
++ }
+ /* 1. shortcuts */
+ for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
+ if (ksym == bp->keysym && match(bp->mod, e->state)) {
+@@ -1977,6 +1983,14 @@ usage(void)
+ " [stty_args ...]\n", argv0, argv0);
+ }
+
++void toggle_winmode(int flag) {
++ win.mode ^= flag;
++}
++
++void keyboard_select(const Arg *dummy) {
++ win.mode ^= trt_kbdselect(-1, NULL, 0);
++}
++
+ int
+ main(int argc, char *argv[])
+ {
diff --git a/patches/st-newterm-20220221-0.8.5.diff b/patches/st-newterm-20220221-0.8.5.diff
new file mode 100644
index 0000000..a43e7af
--- /dev/null
+++ b/patches/st-newterm-20220221-0.8.5.diff
@@ -0,0 +1,111 @@
+From 063d3eff86c788798d8219a7eb10b39d41f06482 Mon Sep 17 00:00:00 2001
+From: Santtu Lakkala <inz@inz.fi>
+Date: Sat, 19 Feb 2022 14:12:02 +0200
+Subject: [PATCH] Add shortcut to spawn new terminal in the current dir
+
+Build on bakkeby's doule fork version. Use /proc/self/exe as the binary,
+and argv[0] as the called name. This allows to have several different
+st's and running from build tree etc. Also skip the unnecessary readlink
+part, shell shall do that anyway. Futher mark the pty master as cloexec,
+so the fd's are not leaked to spawned processes.
+---
+ config.def.h | 1 +
+ st.c | 36 ++++++++++++++++++++++++++++++++++++
+ st.h | 1 +
+ 3 files changed, 38 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index 91ab8ca..7c75246 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -201,6 +201,7 @@ static Shortcut shortcuts[] = {
+ { TERMMOD, XK_Y, selpaste, {.i = 0} },
+ { ShiftMask, XK_Insert, selpaste, {.i = 0} },
+ { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
++ { TERMMOD, XK_Return, newterm, {.i = 0} },
+ };
+
+ /*
+diff --git a/st.c b/st.c
+index 51049ba..5d435de 100644
+--- a/st.c
++++ b/st.c
+@@ -20,6 +20,8 @@
+ #include "st.h"
+ #include "win.h"
+
++extern char *argv0;
++
+ #if defined(__linux)
+ #include <pty.h>
+ #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+@@ -153,6 +155,7 @@ typedef struct {
+ } STREscape;
+
+ static void execsh(char *, char **);
++static int chdir_by_pid(pid_t pid);
+ static void stty(char **);
+ static void sigchld(int);
+ static void ttywriteraw(const char *, size_t);
+@@ -813,6 +816,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
+ if (pledge("stdio rpath tty proc", NULL) == -1)
+ die("pledge\n");
+ #endif
++ fcntl(m, F_SETFD, FD_CLOEXEC);
+ close(s);
+ cmdfd = m;
+ signal(SIGCHLD, sigchld);
+@@ -1061,6 +1065,38 @@ tswapscreen(void)
+ tfulldirt();
+ }
+
++void
++newterm(const Arg* a)
++{
++ int res;
++ switch (fork()) {
++ case -1:
++ die("fork failed: %s\n", strerror(errno));
++ break;
++ case 0:
++ switch (fork()) {
++ case -1:
++ die("fork failed: %s\n", strerror(errno));
++ break;
++ case 0:
++ chdir_by_pid(pid);
++ execlp("/proc/self/exe", argv0, NULL);
++ exit(1);
++ break;
++ default:
++ exit(0);
++ }
++ default:
++ wait(NULL);
++ }
++}
++
++static int chdir_by_pid(pid_t pid) {
++ char buf[32];
++ snprintf(buf, sizeof buf, "/proc/%ld/cwd", (long)pid);
++ return chdir(buf);
++}
++
+ void
+ tscrolldown(int orig, int n)
+ {
+diff --git a/st.h b/st.h
+index 519b9bd..fbdad18 100644
+--- a/st.h
++++ b/st.h
+@@ -81,6 +81,7 @@ void die(const char *, ...);
+ void redraw(void);
+ void draw(void);
+
++void newterm(const Arg *);
+ void printscreen(const Arg *);
+ void printsel(const Arg *);
+ void sendbreak(const Arg *);
+--
+2.32.0
+