diff options
-rwxr-xr-x | crc32 | 9 | ||||
-rwxr-xr-x | dumprpath | 6 | ||||
-rwxr-xr-x | imagebin | 16 | ||||
-rwxr-xr-x | netqiv | 7 | ||||
-rwxr-xr-x | slacklog | 4 | ||||
-rwxr-xr-x | smartfmt | 51 | ||||
-rwxr-xr-x | uleft | 41 | ||||
-rwxr-xr-x | unibmptxt.pl | 875 | ||||
-rwxr-xr-x | urxvt-change-font | 9 | ||||
-rwxr-xr-x | utf8ord | 12 | ||||
-rwxr-xr-x | vipaste | 53 | ||||
-rwxr-xr-x | wide.pl | 112 | ||||
-rwxr-xr-x | x1 | 13 | ||||
-rwxr-xr-x | xcleanpaste | 153 |
14 files changed, 1361 insertions, 0 deletions
@@ -0,0 +1,9 @@ +#!/bin/sh + +# Horribly inefficient way to calculate crc32 of a file. + +Z=/tmp/crc32hack.$$.$RANDOM.zip +rm -f $Z +zip -q $Z "$1" +zipinfo -v $Z | grep CRC | sed 's,.* ,,' +rm -f $Z diff --git a/dumprpath b/dumprpath new file mode 100755 index 0000000..cc07fd0 --- /dev/null +++ b/dumprpath @@ -0,0 +1,6 @@ +#!/bin/sh + +for i in "$@"; do + echo -n "$i: " + objdump -x "$i" | grep RPATH +done diff --git a/imagebin b/imagebin new file mode 100755 index 0000000..a5de360 --- /dev/null +++ b/imagebin @@ -0,0 +1,16 @@ +#!/bin/sh + +# pastebin an image. if xsel is installed, copy the URL to the X clipboard. +# uses this API: https://ibin.co/tools.php +# no support for using a login + API key, don't need it. + +url="$( + curl -F file="@${1:-}" https://imagebin.ca/upload.php | \ + grep ^url: | \ + cut -d: -f2- +)" + +if [ -n "$url" ]; then + echo "$url" + which xsel &>/dev/null && echo -n "$url" | xsel +fi @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e +mkdir -p ~/.netqiv +cd ~/.netqiv +wget "$1" +qiv "$@" "$( basename "$1" )" diff --git a/slacklog b/slacklog new file mode 100755 index 0000000..819b4b1 --- /dev/null +++ b/slacklog @@ -0,0 +1,4 @@ +#!/bin/sh + +VER=${@:-14.2} +exec tmux new links ftp://ftp.osuosl.org/pub/slackware/slackware-$VER/ChangeLog.txt diff --git a/smartfmt b/smartfmt new file mode 100755 index 0000000..71ca8c7 --- /dev/null +++ b/smartfmt @@ -0,0 +1,51 @@ +#!/usr/bin/perl -w + +# wrapper for fmt, detects when every line has +# the same prefix (or is blank) and passes the prefix +# as a -p option to fmt. Called by ~/.vimrc, F mapping. + +sub shortest { + my $oldprefix = shift; + my $line = shift; + my $newprefix = ""; + + for(my $i = 0; $i < length($oldprefix) && $i < length($line); $i++) { + last if substr($line, $i, 1) ne substr($oldprefix, $i, 1); + $newprefix .= substr($line, $i, 1); + } + + return $newprefix; +} + +$nonblank = 0; +while(<STDIN>) { + chomp; + s/^\s+$//; + push @lines, $_; + next if /^$/; + + $nonblank++; + + if(not defined $prefix) { + $prefix = $_; + } elsif($prefix ne "") { + $prefix = shortest($prefix, $_); + } +} + +$width = 71; +if($nonblank > 1 && $prefix ne "" && ($prefix =~ /[^A-Za-z]$/)) { + $opt = ' -p' . quotemeta($prefix) . ' '; + if(@ARGV && ($ARGV[0] eq '-s')) { + $width = (length($prefix) + 71); + } +} + +$opt.= "-w $width -g $width"; + +#warn "line: $_" for @lines; +#warn "opt: $opt"; + +open OUT,"|fmt $opt" or die $!; +print OUT "$_\n" for @lines; +close OUT; @@ -0,0 +1,41 @@ +#!/bin/sh + +# uleft, uright, ukill, ufull, unext - start & kill urxvt with +# preferred geometry. the terminals persist when their shells exit +# (they just start a new one). + +# any arguments passed to this script are passed thru to urxvt. + +GLEFT="96x53+0+0" +GRIGHT="88x53+968+0" +GFULL="185x53+0+0" + +murder_shell() { + # kill the shell that called the shell that's running this script + kill $( ps -o ppid --no-headers $( ps -o ppid --no-headers $$ ) ) + exit 0 +} + +get_next_geom() { + # lets this script alternate between starting left and right terminals + if [ ! -e ~/.uleftright ] || grep -q right ~/.uleftright; then + G=$GLEFT + echo left > ~/.uleftright + else + G=$GRIGHT + echo right > ~/.uleftright + fi + + echo "$G" +} + +case "$0" in + *kill*) murder_shell ;; + *left*) G=$GLEFT ;; + *full*) G=$GFULL ;; + *next*) G=$( get_next_geom ) ;; + *) G=$GRIGHT ;; +esac + +urxvt -g "$G" "$@" -e sh -c "while true; do bash -login; done" &>/dev/null & +disown diff --git a/unibmptxt.pl b/unibmptxt.pl new file mode 100755 index 0000000..e20de65 --- /dev/null +++ b/unibmptxt.pl @@ -0,0 +1,875 @@ +#!/usr/bin/perl + +use warnings; +no warnings 'utf8'; +use utf8; + +@block4x4s = split "", " ▗▖▄▝▐▞▟▘▚▌▙▀▜▛█"; + +for($i = 0; $i < 95; $i++) { + <DATA>; # skip comment + for($j = 0; $j < 6; $j++) { + my $row = <DATA>; + chomp($row); + $row =~ s/X/1/g; + $row =~ s/\./0/g; + #warn @s; + $font[$i + 32][$j] = $row; + } + <DATA>; # skip blank +} + +if(!@ARGV) { + @ARGV = ( + " !\"#\$%&'()*+,-./", + "0123456789:;<=>?", + "\@ABCDEFGHIJKLMNO", + "PQRSTUVWXYZ[\\]^_", + "\`abcdefghijklmno", + "pqrstuvwxyz{|}~"); +} + +for $input (@ARGV) { + my @lines = (); + for(split "", $input) { + my $o = ord($_); + next if $o < 32 || $o > 126; + for(0..5) { + $lines[$_] .= $font[$o][$_]; + } + } + +# always want an even number of columns + if(length($lines[0]) % 1) { + $lines[$_] .= "0" for 0..5; + } + +#print "$_\n" for @lines; + + my @output = (); + for($y = 0; $y < 6; $y += 2) { + my $out = ""; + for($x = 0; $x < length($lines[0]); $x += 2) { + my $index = 0; + $index |= 8 if substr($lines[$y], $x, 1) eq '1'; + $index |= 4 if substr($lines[$y], $x + 1, 1) eq '1'; + $index |= 2 if substr($lines[$y + 1], $x, 1) eq '1'; + $index |= 1 if substr($lines[$y + 1], $x + 1, 1) eq '1'; + $out .= $block4x4s[$index]; + } + push @output, $out; + } + + print "$_\n" for @output; +} + +=for reference +# __DATA__ section originally made thus: +open my $f, "</home/urchlay/5x7.bdf" or die $!; + +$in_bitmap = 0; +@bitmap = (); +while(<$f>) { + chomp; + if(/^ENCODING\s+(\d+)/) { + $encoding = $1; + next; + } + + if($in_bitmap) { + if(/^ENDCHAR/) { + $in_bitmap = 0; + $bitmaps{$encoding} = [ @bitmap ]; + } else { + push @bitmap, $_; + #warn "encoding $encoding, byte $_"; + } + } else { + if(/^BITMAP/) { + $in_bitmap = 1; + @bitmap = (); + } + } +} + +## for(sort { $a <=> $b } keys %bitmaps) { +## print $_ . " => " . join(" ", @{$bitmaps{$_}}) . "\n"; +## } + +for($i = 32; $i < 127; $i++) { + print "# $i " . chr($i) . "\n"; + for(@{$bitmaps{$i}}) { + my $byte = hex($_); + my $bin = sprintf("%08b", $byte); + $bin =~ s/000$//; + $bin =~ s/0/./g; + $bin =~ s/1/X/g; + print $bin . "\n"; + } + print "\n"; +} +=cut + +# This stuff was taken from 5x7.bdf, but hand-edited to make it 6 rows +# high, proportional, and fix some of the uglier glyphs. +__DATA__ +# 32 +... +... +... +... +... +... + +# 33 ! +X. +X. +X. +.. +X. +.. + +# 34 " +X.X. +X.X. +.... +.... +.... +.... + +# 35 # +.X.X.. +XXXXX. +.X.X.. +XXXXX. +.X.X.. +...... + +# 36 $ +.XXXX. +X.X... +.XXX.. +..X.X. +XXXX.. +...... + +# 37 % +..... +X..X. +..X.. +.X... +X..X. +..... + +# 38 & +.X... +X.X.. +.X... +X.X.. +.X.X. +..... + +# 39 ' +X. +X. +.. +.. +.. +.. + +# 40 ( +.X. +X.. +X.. +X.. +.X. +... + +# 41 ) +X.. +.X. +.X. +.X. +X.. +... + +# 42 * +...... +X.X.X. +.XXX.. +X.X.X. +...... +...... + +# 43 + +.... +.X.. +XXX. +.X.. +.... +.... + +# 44 , +... +... +... +... +.X. +X.. + +# 45 - +.... +.... +XXX. +.... +.... +.... + +# 46 . +.. +.. +.. +.. +X. +.. + +# 47 / +..... +...X. +..X.. +.X... +X.... +..... + +# 48 0 +.XX.. +X..X. +X.XX. +X..X. +.XX.. +..... + +# 49 1 +.X.. +XX.. +.X.. +.X.. +XXX. +.... + +# 50 2 +.XX.. +X..X. +..X.. +.X... +XXXX. +..... + +# 51 3 +.XX.. +X..X. +. X.. +X..X. +.XX.. +..... + +# 52 4 +..X.. +.XX.. +X.X.. +XXXX. +..X.. +..... + +# 53 5 +XXXX. +X.... +XXX.. +...X. +XXX.. +..... + +# 54 6 +.XX.. +X.... +XXX.. +X..X. +.XX.. +..... + +# 55 7 +XXXX. +...X. +..X.. +.X... +.X... +..... + +# 56 8 +.XX.. +X..X. +.XX.. +X..X. +.XX.. +..... + +# 57 9 +.XX.. +X..X. +.XXX. +...X. +.XX.. +..... + +# 58 : +.. +X. +.. +X. +.. +.. + +# 59 ; +... +.X. +... +.X. +X.. +... + +# 60 < +..X. +.X.. +X... +.X.. +..X. +.... + +# 61 = +.... +XXX. +.... +XXX. +.... +.... + +# 62 > +X... +.X.. +..X. +.X.. +X... +.... + +# 63 ? +.XX.. +X..X. +..X.. +..... +..X.. +..... + +# 64 @ +.XX.. +X..X. +X.XX. +X.... +.XX.. +..... + +# 65 A +.XX.. +X..X. +XXXX. +X..X. +X..X. +..... + +# 66 B +XXX.. +X..X. +XXX.. +X..X. +XXX.. +..... + +# 67 C +.XX.. +X..X. +X.... +X..X. +.XX.. +..... + +# 68 D +XXX.. +X..X. +X..X. +X..X. +XXX.. +..... + +# 69 E +XXXX. +X.... +XXX.. +X.... +XXXX. +..... + +# 70 F +XXXX. +X.... +XXX.. +X.... +X.... +..... + +# 71 G +.XXX. +X.... +X.XX. +X..X. +.XXX. +..... + +# 72 H +X..X. +X..X. +XXXX. +X..X. +X..X. +..... + +# 73 I +XXX. +.X.. +.X.. +.X.. +XXX. +.... + +# 74 J +...X. +...X. +...X. +X..X. +.XX.. +..... + +# 75 K +X..X. +X.X.. +XX... +X.X.. +X..X. +..... + +# 76 L +X.... +X.... +X.... +X.... +XXXX. +..... + +# 77 M +X...X. +XX.XX. +X.X.X. +X.X.X. +X...X. +...... + +# 78 N +X..X. +XX.X. +X.XX. +X.XX. +X..X. +..... + +# 79 O +.XX.. +X..X. +X..X. +X..X. +.XX.. +..... + +# 80 P +XXX.. +X..X. +XXX.. +X.... +X.... +..... + +# 81 Q +.XX.. +X..X. +X..X. +X..X. +.XX.. +..XX. + +# 82 R +XXX.. +X..X. +XXX.. +X.X.. +X..X. +..... + +# 83 S +.XXX. +X.... +.XX.. +...X. +XXX.. +..... + +# 84 T +XXXXX. +..X... +..X... +..X... +..X... +...... + +# 85 U +X..X. +X..X. +X..X. +X..X. +.XX.. +..... + +# 86 V +X...X. +X...X. +X...X. +.X.X.. +..X... +...... + +# 87 W +X...X. +X...X. +X.X.X. +XX.XX. +X...X. +...... + +# 88 X +X..X. +X..X. +.XX.. +X..X. +X..X. +..... + +# 89 Y +X...X. +X...X. +.XXX.. +..X... +..X... +...... + +# 90 Z +XXXX. +...X. +.XX.. +X.... +XXXX. +..... + +# 91 [ +XX. +X.. +X.. +X.. +XX. +... + +# 92 \ +..... +X.... +.X... +..X.. +...X. +..... + +# 93 ] +XX. +.X. +.X. +.X. +XX. +.... + +# 94 ^ +.X.. +X.X. +.... +.... +.... +.... + +# 95 _ +..... +..... +..... +..... +XXXX. +..... + +# 96 ` +X.. +.X. +... +... +... +... + +# 97 a +..... +..... +.XXX. +X..X. +.XXX. +..... + +# 98 b +X.... +X.... +XXX.. +X..X. +XXX.. +..... + +# 99 c +.... +.... +.XX. +X... +.XX. +.... + +# 100 d +...X. +...X. +.XXX. +X..X. +.XXX. +..... + +# 101 e +..... +.XX.. +X..X. +X.X.. +.XXX. +..... + +# 102 f +..XX. +.X... +XXX.. +.X... +.X... +..... + +# 103 g +..... +.XXX. +X..X. +.XXX. +...X. +.XX.. + +# 104 h +X.... +X.... +XXX.. +X..X. +X..X. +..... + +# 105 i +.X.. +.... +XX.. +.X.. +XXX. +.... + +# 106 j +..X. +.... +..X. +..X. +X.X. +.X.. + +# 107 k +X... +X... +X.X. +XX.. +X.X. +.... + +# 108 l +XX.. +.X.. +.X.. +.X.. +XXX. +.... + +# 109 m +...... +...... +X.XX.. +XXXXX. +X.X.X. +...... + +# 110 n +..... +..... +XXX.. +X..X. +X..X. +..... + +# 111 o +..... +..... +.XX.. +X..X. +.XX.. +..... + +# 112 p +..... +..... +XXX.. +X..X. +XXX.. +X.... + +# 113 q +..... +..... +.XXX. +X..X. +.XXX. +...X. + +# 114 r +..... +..... +XXX.. +X..X. +X.... +..... + +# 115 s +..... +.XXX. +XX... +..XX. +XXX.. +..... + +# 116 t +.X... +.X... +XXX.. +.X... +..XX. +..... + +# 117 u +..... +..... +X..X. +X..X. +.XXX. +..... + +# 118 v +.... +.... +X.X. +X.X. +.X.. +.... + +# 119 w +...... +...... +X...X. +X.X.X. +XX.XX. +...... + +# 120 x +..... +..... +X..X. +.XX.. +X..X. +..... + +# 121 y +..... +..... +X..X. +.X.X. +..X.. +.X... + +# 122 z +..... +XXXX. +..X.. +.X... +XXXX. +..... + +# 123 { +..X. +.X.. +XX.. +.X.. +..X. +.... + +# 124 | +X. +X. +X. +X. +X. +.. + +# 125 } +X... +.X.. +.XX. +.X.. +X... +.... + +# 126 ~ +.X.X. +X.X.. +..... +..... +..... +..... + diff --git a/urxvt-change-font b/urxvt-change-font new file mode 100755 index 0000000..6556a2d --- /dev/null +++ b/urxvt-change-font @@ -0,0 +1,9 @@ +#!/bin/sh + +# Read default from X resources +DFLT="$( xrdb -query |grep '^URxvt\*font'|cut -f2 )" +DFLT="${DFLT:-xft:Deja Vu Sans Mono:size=13}" +NEWFONT="$@" +FONT=${NEWFONT:-$DFLT} +echo "Setting urxvt font to '$FONT'" +printf '\e]710;%s\007' "${1:-$FONT}" @@ -0,0 +1,12 @@ +#!/usr/bin/perl -CIOESA -w + +use charnames qw/:full/; + +#print ord($_), "\n" for @ARGV; + +for(@ARGV) { + for(split "") { + my $c = ord; + printf("%s\t%d\t%04x\t%s\n", $_, $c, $c, charnames::viacode($c)) for split ""; + } +} @@ -0,0 +1,53 @@ +#!/bin/bash + +usage() { + cat <<EOF +$SELF - edit X11 selection buffer + +Usage: $SELF [-n] + +Loads the current contents of the X11 selection (copy/paste) buffer +into an editor. After editing & exiting the editor, the results are +copied back into the selection buffer, for pasting elsewhere. + +The last line (only line, for 1-line selections) will have its newline +removed, if there is one. + +If the file is empty after editing, or if the editor exits with +non-zero (error) status, the selection buffer won't be altered. + +To start with an empty buffer rather than the current selection, use +the -n option. + +The editor to be run is set via VISUAL in the environment. If it's not +set, EDITOR is used if set. If neither is set, vi is used. If you're +going to run this without a terminal (e.g. using xbindkeys or a "Run +Program" dialog), you'll want to set VISUAL to something that doesn't +require a terminal (e.g. a GUI editor like gvim or gedit). + +Requires xsel and perl on the PATH. + +Written by B. Watson <yalhcru@gmail.com> and released under the WTFPL. +EOF + exit $1 +} + +set -e + +SELF="$( basename $0 )" +CMD="xsel -o" + +[ "$1" = "--help" ] && usage 0 +[ "$1" = "-n" ] && CMD=":" && shift +[ "$1" != "" ] && usage 1 + +TMPFILE="$( mktemp -t $SELF.XXXXXX )" +trap "rm -f \"$TMPFILE\"" EXIT + +$CMD > "$TMPFILE" +${VISUAL:-${EDITOR:-vi}} "$TMPFILE" + +# remove the newline(s) from the end of the file +perl -i -0777 -pe 's/\n*$//' "$TMPFILE" + +[ -s "$TMPFILE" ] && xsel -i < "$TMPFILE" @@ -0,0 +1,112 @@ +#!/usr/bin/perl + +=pod + +=head1 NAME + +wide.pl - print double-width characters + +=head1 SYNOPSIS + +=head2 From the shell: + +wide.pl <[args ...]> + +=head2 From within irssi: + +/script load wide.pl + +/wide [args] + +=head1 DESCRIPTION + +wide.pl converts printable ASCII characters to their double-width +equivalent from the Unicode 0xff block. See: + +https://en.wikipedia.org/wiki/Halfwidth_and_Fullwidth_Forms_(Unicode_block) + +Characters that don't have double-wide equivalents are simply printed +with a trailing space. + +This script can be run standalone or as an irssi /script. For things to work +properly in irssi, you'll need UTF-8 and Unicode support in irssi and in the +terminal you're using to run irssi. + +When run standalone with no arguments, reads from stdin and writes to stdout. +If arguments are given, they're treated as input (not filenames). Use shell +redirection to read from a file: wide.pl < message.txt + +=head1 AUTHOR + +Urchlay <yalhcru@gmail.com> + +=head1 LICENSE + +wide.pl is released under the WTFPL: Do WTF you want with this. + +=cut + +use warnings; +use strict; + +sub wide { + my $text = shift; + my $res = ""; + + for (split "", $text) { + my $c = ord($_); + if($c >= 0x21 && $c <= 0x7e) { + $res .= chr($c + 0xfee0); + } else { + $res .= "$_$_"; + } + } + + return $res; +} + +# main() if we're not running under irssi +if(__PACKAGE__ eq 'main') { + no warnings 'utf8'; + + exec "perldoc $0" if @ARGV && $ARGV[0] =~ /--?h(elp)?/; + + if(@ARGV) { + print wide($_) for @ARGV; + print "\n"; + } else { + while(<>) { + chomp; + print wide($_); + print "\n"; + } + } + + exit 0; +} + +# irssi stuff here +require Irssi; +Irssi->import(qw/command command_bind/); + +our $VERSION = "0.1"; +our %IRSSI = ( + authors => 'Urchlay', + contact => 'Urchlay on FreeNode', + name => 'wide', + description => 'print double-width characters', + license => 'WTFPL', + url => 'none', + ); + +sub cmd_wide { + my ($text, $srv, $chan) = @_; + + return unless $text; + return unless $srv; + return unless $chan; + + $chan->command('MSG ' . $chan->{name} . ' ' . wide($text)); +} + +command_bind("wide", \&cmd_wide); @@ -0,0 +1,13 @@ +#!/bin/sh + +WM="${1:-/etc/X11/xinit/xinitrc.fvwm2}" +case "$1" in + "") ;; + /*) ;; + *) WM=/etc/X11/xinit/xinitrc.$1 ;; +esac + +[ ! -x "$WM" ] && WM="$( which $1 )" + +echo startx $WM -- :1 +exec startx $WM -- :1 diff --git a/xcleanpaste b/xcleanpaste new file mode 100755 index 0000000..c122002 --- /dev/null +++ b/xcleanpaste @@ -0,0 +1,153 @@ +#!/usr/bin/perl -w + +=pod + +=head1 NAME + +xcleanpaste - join multi-line copy/paste into one long line + +=head1 SYNOPSIS + +B<xcleanpaste> [-n] [-u] [-e<line-ending>] [-v] [xsel-options] + +=head1 DESCRIPTION + +"Cleans" the X selection buffer: trims whitespace from the start +and end of every line, replaces all newlines with spaces, replaces +all tabs with 3 spaces each. Result is written back to the selection +buffer, where you can paste it into whatever application you want. + +This is useful even for single-line pastes: it removes tabs and any +newline at the end, so e.g. copying a command from a browser into the +shell won't trigger tab-completion or execute the command immediately. + +The selection buffer is read/written using xsel, which must be +installed and available on your PATH. + +xcleanpaste is best used by binding to a key using xbindkeys or +similar, though you can run it from the shell too. + +If you're using keybinding, you probably want at least separate keys +for xcleanpaste with no options and xcleanpaste with the -u option +(URL cleaner; see below). + +=head1 OPTIONS + +=over 4 + +=item B<-e><line-ending> + +Replace line endings with the given string rather than a space. Don't +use a space between the -e and the ending. Beware of shell quoting +rules. + +=item B<-n> + +Replace line endings with the string " \n " rather than a space. This is +space, backslash, lowercase n, space. Equivalent to B<-e ' \n '>. + +=item B<-u> + +Remove CGI arguments from any URLs found in the buffer. Some sites +including tracking info, e.g. https://site.blah/stuff?sessionID=12345, +which you shouldn't be pasting into anything others can see (e.g. IRC +or emails). + +=item B<-v> + +Verbose mode. Shows lines read and written from the xsel instances on +stderr. Not much use with xbindkeys though. + +=back + +Any other arguments are passed to xsel. This is probably only useful +for xsel's -p/-s/-b options (see xsel man page). + +=head1 EXAMPLE + +In B<~/.xbindkeys>: + + "xcleanpaste &" + Control+Alt + period + + "xcleanpaste -u &" + Control+Alt + slash + +If you copy these three lines: + + This is + a long URL: + https://long.url?with=lots&of=arguments + +Then press Ctrl+Alt+Period, then paste into some window, you will get: + + This is a long URL: https://long.url?with=lots&of=arguments + +If you instead press Ctrl+Alt+Slash, you'll get: + + This is a long URL: https://long.url + +=head1 AUTHOR + +xcleanpaste was written by B. Watson <yalhcru@gmail.com> and released +under the WTFPL: Do WTF you want with this. + +=cut + +( $SELF = $0 ) =~ s,.*/,,; + +@xselargs = (); +$line_ends = " "; +$url_clean = $verbose = 0; + +for(@ARGV) { + if(/^-?-h(?:elp)/) { + exec "perldoc $0"; + exit 1; # if the exec failed + } elsif(/^-v/) { + $verbose++; + } elsif(/^-n/) { + $line_ends = " \\n "; + } elsif(/^-u/) { + $url_clean = 1; + } elsif(/^-e(.*)$/) { + if(!defined($1) || $1 eq "") { + die("$SELF: no space allowed between -e option and its argument\n"); + } + $line_ends = $1; + } else { + push @xselargs, $_; + } +} + +$xsel_extra_args = join(" ", @xselargs); +warn "$SELF: xsel arguments: \"$xsel_extra_args\"\n" if $verbose; + +# We have to read the entire output of xsel -o into memory before +# spawning the xsel -i, because otherwise the 2nd xsel will obliterate +# the selection buffer the first one's still trying to read from. +open my $in, "xsel -o $xsel_extra_args|" or die $!; +while(<$in>) { + chomp; + warn "$SELF: read line $.: $_\n" if $verbose; + s,\s+$,,; # remove any trailing whitespace + s,^\s+,,; # remove any leading whitespace + s,[\r\n], ,g; # replace all CR or LF with a single space + s,\t, ,g; # replace all tabs with 3 spaces + if($url_clean) { + # get rid of ? and anything after it, in anything that looks like a URL + s,(https?:\/\/[^?\s]*)\?\S+,$1,g; + } + s/\S$/$&$line_ends/; # our ending LF became a space above; make it + # whatever the line ending is supposed to be + push @lines, $_; +} +close $in; + +$output = join("", @lines); +$output =~ s/\s+$//; # trim trailing whitespace from last line only +warn "$SELF: writing: $output\n" if $verbose; + +open my $out, "|xsel -i $xsel_extra_args" or die $!; +print $out $output; +close $out; |