diff --git a/Makefile b/Makefile index 32830c2..907e29a 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,11 @@ install: st mkdir -p $(DESTDIR)$(APPPREFIX) cp -f st.desktop $(DESTDIR)$(APPPREFIX) cp -f scripts/urllist $(DESTDIR)$(PREFIX)/bin + cp -f scripts/st_buffer $(DESTDIR)$(PREFIX)/bin + cp -f scripts/st_xurls $(DESTDIR)$(PREFIX)/bin chmod +x $(DESTDIR)$(PREFIX)/bin/urllist + chmod +x $(DESTDIR)$(PREFIX)/bin/st_buffer + chmod +x $(DESTDIR)$(PREFIX)/bin/st_xurls rm -f ./st rm -f *.o diff --git a/docs/patchlist b/docs/patchlist index 2715abd..65c4f93 100644 --- a/docs/patchlist +++ b/docs/patchlist @@ -26,3 +26,4 @@ st-xrandrfontsize st-delkey st-extenralpipe st-externalpipe-eternal +st-externalpipe-signal diff --git a/external.h b/external.h index 41a64fd..adbcb9e 100644 --- a/external.h +++ b/external.h @@ -1,3 +1,4 @@ /* This is the header used to control extenralpipe. */ +char *externalpipe_sigusr1[] = { "/bin/sh", "-c", "st_buffer st_strings_read" }; static char *listurl[] = { "/bin/sh", "-c", "urllist", NULL }; diff --git a/scripts/st_buffer b/scripts/st_buffer new file mode 100644 index 0000000..67eb13c --- /dev/null +++ b/scripts/st_buffer @@ -0,0 +1,47 @@ +#!/usr/bin/env sh +# externalpipe_buffer.sh: use with surf/st externalpipe-signal patches +# Input Usage: echo st or surf content from externalpipe | ./externalpipe_buffer.sh {st,surf}_strings_read +# Menus Usage: ./externalpipe_buffer.sh dmenu_{copy, type} +BUFFER_FILE=/tmp/content_buffer +function st_strings_read() { + INPUT="$(cat)" + echo "$( + echo "$INPUT" | grep -Eo '\S+' | tr -d '[:blank:]' + echo "$INPUT" | grep -oP '"[^"]+"' | tr -d '"' + echo "$INPUT" | sed 's/^ *[0-9]\+.//g' | awk '{$1=$1};1' + )" | uniq | grep . | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2- \ + >> $BUFFER_FILE & +} +function surf_strings_read() { + awk '{printf "%sNEWLINE_REPLACE", $0} END {printf "\n"}' | + xmllint --html --xpath "//*" - | + awk '{ gsub("<[^>]*>", ""); print($0); }' | + sed 's/NEWLINE_REPLACE/↵/g' | + awk '{ gsub("<[^>]*>",""); print $0 }' | + sed 's/<//g' | + uniq | grep . | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2- \ + >> $BUFFER_FILE & +} +function trigger_sigusr1() { + USE_FIFO=F # Recomended as T but only if using dmenu-stdin patch w/ FIFO + rm -f $BUFFER_FILE + if [ $USE_FIFO == T ]; then mkfifo $BUFFER_FILE; else touch $BUFFER_FILE; fi + pkill -USR1 "surf" & + pkill -USR1 "^st$" & + if [ $USE_FIFO != T ]; then sleep 0.8; fi +} +function dmenu_copy() { + trigger_sigusr1 + cat $BUFFER_FILE | dmenu -l 10 -i -w $(xdotool getactivewindow) -p 'Screen Copy' | sed 's/↵/\n/g' | xclip -i +} +function dmenu_type() { + trigger_sigusr1 + cat $BUFFER_FILE | dmenu -l 10 -i -w $(xdotool getactivewindow) -p 'Screen Type' | sed 's/↵/\n/g' | xargs -IC xdotool type --delay 0 "C" +} +function pipe_combine() { + trigger_sigusr1 + cat - $BUFFER_FILE +} + +$1 diff --git a/scripts/st_xurls b/scripts/st_xurls new file mode 100644 index 0000000..bbc3ad1 --- /dev/null +++ b/scripts/st_xurls @@ -0,0 +1,116 @@ +#!/usr/bin/perl + +use warnings; + +$hostchars = '[a-z0-9-._+]'; +$pathchars = '[a-z0-9-._+#=?&:;%/!,~]'; + +sub scan($$$) +{ + my ($file, $lineno, $line) = @_; + + chomp $line; + + while($line =~ s! + ([a-z]+://)? + +# http:// + + $hostchars+\.[a-z]+ + +# www.tim.google.com - the [a-z].com is the main anchor for the whole regex - incase http:// is omitted +# note no trailing slash + + ($pathchars+/\?)* + +# check for the index.php? part + + ($pathchars+|\($pathchars+\))* + +# check for pathchars, or a set of nested parens + !!xoi){ # allow space + comments, compile once, strcasecmp + + my($p,$m,$e) = ($`,$&,$'); + + $e = '.' . $e if $m =~ s/\.$//; + + if($opt{fname} && $file){ + print "$col{red}$file$col{none}:"; + } + + if($opt{lineno}){ + print "$col{green}$lineno$col{none}: "; + }elsif($opt{fname} && $file){ + print ' '; + } + + if($opt{hl}){ + print "$p$col{brown}$m$col{none}$e\n"; + }else{ + print "$m\n"; + } + } +} + +sub usage(){ + $printme =<<"!"; +Usage: $0 -[Chn] [FILES...] + -h: highlight + -c: force colour on (for pipes) + -C: colour off (only makes sense with -h) + -n: show line number +! + print STDERR $printme; + exit 1; +} + + +%opt = ( + colour => 1, + lineno => 0, + fname => 0, + hl => 0 +); +%col = ( + brown => "\e[0;31m", # hl + red => "\e[0;35m", # fname + green => "\e[0;32m", # lineno + none => "\e[0;0m" +); + +for $arg (@ARGV){ + if($arg eq '-h'){ + $opt{hl} = 1; + }elsif($arg eq '-n'){ + $opt{lineno} = 1; + }elsif($arg eq '-C'){ + $opt{colour} = 0; + }elsif($arg eq '-c'){ + usage() if $opt{colour} == 0; + $opt{colour} = 2; # force on + }elsif($arg eq '--help'){ + usage(); + }else{ + push @files, $arg; + } +} + +usage() if $opt{hl} && !$opt{colour}; + +$opt{fname} = 1 if $#files > 0 || $opt{lineno}; +if(!$opt{colour} || ($opt{colour} == 1 && !-t STDOUT)){ + $col{$_} = '' for keys %col; +} + +$| = 1; + +if(@files){ + for my $f (@files){ + my $n = 1; + open F, '<', $f or warn "$f: $!\n"; + scan($f, $n++, $_) for ; + close F; + } +}else{ + scan(undef, $., $_) while ; +} diff --git a/scripts/urllist b/scripts/urllist index dc1951e..cd76dba 100644 --- a/scripts/urllist +++ b/scripts/urllist @@ -1 +1,16 @@ -# temporarily empty +#!/bin/sh +case "$RUNLAUNCHER" in +"") RUNLAUNCHER=dmenu ;; +esac + +command -v xdg-open > /dev/null && BROWSER="xdg-open" + +st_xurls | grep -q http || exit 0 # Don't prompt when there are no urls. + +URL=$(st_xurls | grep http | awk '!_[$1]++' | $RUNLAUNCHER -l 10 -w $WINDOWID -g 1 -p 'Open:') + +case "$1" in +"") $BROWSER $URL ;; +"-o") $BROWSER $URL ;; +"-c") echo $URL | xclip -selection clipboard ;; +esac diff --git a/st.c b/st.c index e473ecf..6b44e7e 100644 --- a/st.c +++ b/st.c @@ -189,6 +189,7 @@ typedef struct { static void execsh(char *, char **); static void stty(char **); static void sigchld(int); +static void sigusr1(int); static void ttywriteraw(const char *, size_t); static void csidump(void); @@ -832,6 +833,13 @@ execsh(char *cmd, char **args) _exit(1); } +void +sigusr1(int unused) +{ + static Arg a = {.v = externalpipe_sigusr1}; + externalpipe(&a); +} + void sigchld(int a) { @@ -884,6 +892,12 @@ stty(char **args) int ttynew(const char *line, char *cmd, const char *out, char **args) { + static struct sigaction sa; + sa.sa_handler = sigusr1; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction(SIGUSR1, &sa, NULL); + int m, s; if (out) { diff --git a/st.h b/st.h index 488ace2..25243cb 100644 --- a/st.h +++ b/st.h @@ -136,6 +136,7 @@ void drawboxes(int, int, int, int, XftColor *, XftColor *, const XftGlyphFontSpe #endif /* config.h globals */ +extern char *externalpipe_sigusr1[]; extern char *utmp; extern char *scroll; extern char *stty_args;