diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | config.def.h | 15 | ||||
| -rwxr-xr-x | st-cpyout | 34 | ||||
| -rw-r--r-- | st.c | 68 | ||||
| -rw-r--r-- | st.h | 2 | ||||
| -rw-r--r-- | x.c | 6 |
6 files changed, 121 insertions, 8 deletions
@@ -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 @@ -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; @@ -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); @@ -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); */ } } |
