aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoe <rbo@gmx.us>2025-09-27 19:51:34 +0200
committerjoe <rbo@gmx.us>2025-09-27 19:51:34 +0200
commit14101eefa260ec23f09ac961a3bed6a32932b9c3 (patch)
treeeaee1618fb9cd17fd13bb1df5378b778d1a84d2f
parentpatch (diff)
downloadst-14101eefa260ec23f09ac961a3bed6a32932b9c3.tar.gz
st-14101eefa260ec23f09ac961a3bed6a32932b9c3.tar.bz2
st-14101eefa260ec23f09ac961a3bed6a32932b9c3.tar.xz
st-14101eefa260ec23f09ac961a3bed6a32932b9c3.tar.zst
st-14101eefa260ec23f09ac961a3bed6a32932b9c3.zip
up
-rw-r--r--Makefile4
-rw-r--r--config.def.h15
-rwxr-xr-xst-cpyout34
-rw-r--r--st.c68
-rw-r--r--st.h2
-rw-r--r--x.c6
6 files changed, 121 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index afea78d..a8debd5 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ config.h:
cp config.def.h config.h
.c.o:
- $(CC) $(STCFLAGS) -c $<
+ $(CC) -O0 -g3 -fsanitize=address $(STCFLAGS) -c $<
st.o: config.h st.h win.h
x.o: arg.h config.h st.h win.h
@@ -21,7 +21,7 @@ x.o: arg.h config.h st.h win.h
$(OBJ): config.h config.mk
st: $(OBJ)
- $(CC) -o $@ $(OBJ) $(STLDFLAGS)
+ $(CC) -fsanitize=address -o $@ $(OBJ) $(STLDFLAGS)
clean:
rm -f st $(OBJ) config.h st-$(VERSION).tar.gz
diff --git a/config.def.h b/config.def.h
index f0a7968..cb031b1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -176,17 +176,25 @@ static uint forcemousemod = ShiftMask;
*/
static MouseShortcut mshortcuts[] = {
/* mask button function argument release */
+ { XK_ANY_MOD, Button4, kscrollup, {.i = 3}, 0, /* !alt */ -1 },
+ { XK_ANY_MOD, Button5, kscrolldown, {.i = 3}, 0, /* !alt */ -1 },
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
- { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
+ /* { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
- { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
+ { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, */
};
/* Internal keyboard shortcuts. */
#define MODKEY Mod1Mask
#define TERMMOD (ControlMask|ShiftMask)
+static char *linkviewcmd[] = { "/bin/sh", "-c",
+ "alacritty -e linkview $(tmp=$(xurls | uniq); IFS=; [ ! -z $tmp ] && echo $tmp | dmenu -i -l 20 -m 0 | tr -d '\n' | cat)",
+ "externalpipe", NULL };
+static char *cpyoutcmd[] = { "/bin/sh", "-c", "/usr/local/bin/st-cpyout", "externalpipe", NULL };
+static char *cpyoutnopcmd[] = { "/bin/sh", "-c", "/usr/local/bin/st-cpyout noprompt", "externalpipe", NULL };
+
static Shortcut shortcuts[] = {
/* mask keysym function argument */
{ XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
@@ -208,6 +216,9 @@ static Shortcut shortcuts[] = {
{ TERMMOD, XK_D, kscrolldown, {.i = -1} },
{ TERMMOD, XK_K, kscrollup, {.i = 1} },
{ TERMMOD, XK_J, kscrolldown, {.i = 1} },
+ { TERMMOD, XK_I, externalpipe, {.v = linkviewcmd } },
+ { TERMMOD, XK_P, externalpipe, {.v = cpyoutcmd} },
+ { TERMMOD, XK_O, externalpipe, {.v = cpyoutnopcmd} },
};
/*
diff --git a/st-cpyout b/st-cpyout
new file mode 100755
index 0000000..98aaa99
--- /dev/null
+++ b/st-cpyout
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Using external pipe with st, give a dmenu prompt of recent commands,
+# allowing the user to copy the output of one.
+# xclip required for this script.
+# By Jaywalker and Luke
+# Adapted for FreeBSD by Joe
+mem=$(cat)
+mem=$(printf "%s" "$mem" | sed 's/\x0//g')
+ps1=$(printf "%s" "$mem" |
+ tac |
+ tail -n1 |
+ sed 's/%.\+/%/')
+chosen=$(printf "%s" "$mem" |
+ grep -F "$ps1" |
+ sed '$ d' |
+ tac |
+ dmenu -i -l 10 -m 0 |
+ sed 's/[^^]/[&]/g; s/\^/\\^/g')
+eps1=$(echo "$ps1" |
+ sed 's/[^^]/[&]/g; s/\^/\\^/g')
+if [ "$1" = "noprompt" ]; then
+ printf "%s" "$mem" |
+ gawk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" |
+ tac |
+ sed '$ d' |
+ tac |
+ perl -p -e 'chomp if eof' |
+ xclip -selection clipboard
+else
+ printf "%s" "$mem" |
+ gawk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" |
+ xclip -selection clipboard
+fi
diff --git a/st.c b/st.c
index f77598c..d8db29c 100644
--- a/st.c
+++ b/st.c
@@ -736,8 +736,14 @@ sigchld(int a)
if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
- if (pid != p)
+ if (pid != p) {
+ if (p == 0 && wait(&stat) < 0)
+ die("wait: %s\n", strerror(errno));
+
+ /* reinstall sigchld handler */
+ signal(SIGCHLD, sigchld);
return;
+ }
if (WIFEXITED(stat) && WEXITSTATUS(stat))
die("child exited with status %d\n", WEXITSTATUS(stat));
@@ -814,7 +820,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
if (s > 2)
close(s);
#ifdef __OpenBSD__
- if (pledge("stdio getpw proc exec", NULL) == -1)
+ if (pledge("stdio rpath tty proc exec", NULL) == -1)
die("pledge\n");
#endif
execsh(cmd, args);
@@ -1081,6 +1087,11 @@ tnew(int col, int row)
treset();
}
+int tisaltscr(void)
+{
+ return IS_SET(MODE_ALTSCREEN);
+}
+
void
tswapscreen(void)
{
@@ -2115,6 +2126,59 @@ strparse(void)
}
void
+externalpipe(const Arg *arg)
+{
+ int to[2];
+ char buf[UTF_SIZ];
+ void (*oldsigpipe)(int);
+ Glyph *bp, *end;
+ int lastpos, n, newline;
+
+ if (pipe(to) == -1)
+ return;
+
+ switch (fork()) {
+ case -1:
+ close(to[0]);
+ close(to[1]);
+ return;
+ case 0:
+ dup2(to[0], STDIN_FILENO);
+ close(to[0]);
+ close(to[1]);
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
+ perror("failed");
+ exit(0);
+ }
+
+ close(to[0]);
+ /* ignore sigpipe for now, in case child exists early */
+ oldsigpipe = signal(SIGPIPE, SIG_IGN);
+ newline = 0;
+ for (n = 0; n < term.row; n++) {
+ bp = TLINE(n);
+ lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
+ if (lastpos < 0)
+ break;
+ end = &bp[lastpos + 1];
+ for (; bp < end; ++bp)
+ if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
+ break;
+ if ((newline = TLINE(n)[lastpos].mode & ATTR_WRAP))
+ continue;
+ if (xwrite(to[1], "\n", 1) < 0)
+ break;
+ newline = 0;
+ }
+ if (newline)
+ (void)xwrite(to[1], "\n", 1);
+ close(to[1]);
+ /* restore */
+ signal(SIGPIPE, oldsigpipe);
+}
+
+void
strdump(void)
{
size_t i;
diff --git a/st.h b/st.h
index fdb758d..406a161 100644
--- a/st.h
+++ b/st.h
@@ -82,12 +82,14 @@ void die(const char *, ...);
void redraw(void);
void draw(void);
+void externalpipe(const Arg *);
void printscreen(const Arg *);
void printsel(const Arg *);
void sendbreak(const Arg *);
void toggleprinter(const Arg *);
int tattrset(int);
+int tisaltscr(void);
void tnew(int, int);
void tresize(int, int);
void tsetdirtattr(int);
diff --git a/x.c b/x.c
index fa4375d..d67cb7a 100644
--- a/x.c
+++ b/x.c
@@ -34,6 +34,7 @@ typedef struct {
void (*func)(const Arg *);
const Arg arg;
uint release;
+ int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
} MouseShortcut;
typedef struct {
@@ -459,6 +460,7 @@ mouseaction(XEvent *e, uint release)
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
if (ms->release == release &&
ms->button == e->xbutton.button &&
+ (!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
(match(ms->mod, state) || /* exact or forced */
match(ms->mod, state & ~forcemousemod))) {
ms->func(&(ms->arg));
@@ -1597,7 +1599,7 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
break;
}
} else {
- XftDrawRect(xw.draw, &drawcol,
+ /* XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw,
borderpx + cy * win.ch,
win.cw - 1, 1);
@@ -1612,7 +1614,7 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw,
borderpx + (cy + 1) * win.ch - 1,
- win.cw, 1);
+ win.cw, 1); */
}
}