aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2021-06-07 01:13:31 +0200
committerJohn Ankarström <john@ankarstrom.se>2021-06-07 01:13:41 +0200
commit10c638d1824950d80df52a691b562d772d6e25e2 (patch)
tree1e1c80329f7ed6a9b46b806484f1e014dedb27ff
parente3e38fab30514c3922b630ea1cb884fcc1e78e29 (diff)
downloaddwim-10c638d1824950d80df52a691b562d772d6e25e2.tar.gz
stuff
-rwxr-xr-xdwim146
-rw-r--r--dwim.1102
2 files changed, 138 insertions, 110 deletions
diff --git a/dwim b/dwim
index d5c8646..a9b56df 100755
--- a/dwim
+++ b/dwim
@@ -5,71 +5,79 @@
use v5.24;
use warnings;
use strict;
-use Path::ExpandTilde;
use subs qw/path env handle fail run arguments/;
-my ($phrase, %o) = arguments "usage: $0 parse\n", 1, d => 0;
-$phrase = `xsel -o` if not defined $phrase;
+my ($DEBUG, $handler, $phrase);
-my @OPENER = ("xtopen");
-my @EDITOR = (@OPENER, "vi");
-my @PDF_VIEWER = ("xpdf");
-my @MAN_VIEWER = (@OPENER, "man");
-my @MAILER = (@OPENER, "mutt");
-my @BROWSER = (@OPENER, "w3m -title");
-my @FILE_BROWSER = (@OPENER, "noice");
-my @MAILDIR_VIEWER = (@OPENER, "mutt -f");
-my $MAILROOT = env MAILROOT => "/home/john/mail/";
+while ($_ = shift @ARGV) {
+ if (/^-d$/) {
+ $DEBUG = 1;
+ } elsif (/^-/) {
+ die "usage: $0 [-d] [phrase]\n";
+ } else {
+ $phrase = $_;
+ }
+}
+
+$phrase = `xsel -o` if not defined $phrase;
-our $handler;
+my @OPENER = ('xtopen');
+my @EDITOR = (@OPENER, 'vi');
+my @PDF_VIEWER = ('xpdf');
+my @MAN_VIEWER = (@OPENER, 'man');
+my @MAILER = (@OPENER, 'mutt');
+my @BROWSER = (@OPENER, 'w3m -title');
+my @FILE_BROWSER = (@OPENER, 'noice');
+my @MAILDIR_VIEWER = (@OPENER, 'mutt -f');
+my $MAILROOT = env MAILROOT => '/home/john/mail/';
for ($phrase) {
if (/^(https?:\/?\/?\S+)$/) {
- handle "web address";
- run @BROWSER, "$1"
+ handle 'web address';
+ run @BROWSER, $1
}
if (/^(mailto:\S+)$/ or /^(\S+@.+\.\w+)$/) {
- handle "e-mail address";
- run @MAILER, "$1"
+ handle 'e-mail address';
+ run @MAILER, $1
}
if (/^(.+?):(\d+).*?$/) {
- handle "file:line (like grep -n)";
+ handle 'file:line (like grep -n)';
my $p = path $1;
- run @EDITOR, "+$2", "$p"
+ run @EDITOR, "+$2", $p
}
if (/^(.+) line (\d+)\.?$/) {
- handle "FILE line LINE (like perl)";
+ handle 'FILE line LINE (like perl)';
my $p = path $1;
- run @EDITOR, "+$2", "$p"
+ run @EDITOR, "+$2", $p
}
if (/^(.+):(.+)$/) {
- handle "file:query (like grep)";
+ handle 'file:query (like grep)';
my $p = path $1;
- run @EDITOR, "+/$2", "$p" if -e $p;
- fail "file not found" if $o{d};
+ run @EDITOR, "+/$2", $p if -e $p;
+ fail 'file not found' if $DEBUG;
# otherwise fall through
}
- if (/^(\S+)\((\S+)\)[,.]?/) {
- handle "manpage(section)";
+ if (/^(\S+)\((\d+)\)[):,.]*$/) {
+ handle 'manual(section)';
run @MAN_VIEWER, $2, $1;
}
- if (/^(\S+)\.([1-9])/) {
- handle "manpage.section";
+ if (/^([A-Za-z]+)\.([1-9])$/) {
+ handle 'manual.section';
my $p = path "$1.$2";
run @MAN_VIEWER, $p if -e $p;
run @MAN_VIEWER, $2, $1;
}
if (/^<(\S+)>$/) {
- handle "<header.h>";
+ handle '<header.h>';
open my $h, 'find / -maxdepth 3 -type d -name include 2>&-|'
- or fail "could not search include directories";
+ or fail 'could not search include directories';
while (<$h>) {
chomp;
if (-e "$_/$1") {
@@ -78,22 +86,17 @@ for ($phrase) {
}
}
close $h;
- fail "header file not found";
- }
-
- if (/^(\S+-[\d.]+_\d+)$/) {
- handle "xbps package";
- run @OPENER, "in-shell", "sudo", "xbps-install", "-S", $1;
+ fail 'header file not found';
}
if (/^(\S+)$/) {
- handle "maildir / directory / file";
+ handle 'maildir / directory / file';
my $p = path $1;
- run @MAILDIR_VIEWER, "$p" if $p =~ /^$MAILROOT/; # maildir
- run @FILE_BROWSER, "$p" if -d $p; # directory
- run @PDF_VIEWER, "$p" if -e $p and $p =~ /\.pdf$/; # pdf
- run @EDITOR, "$p" if -e $p; # file
- fail "file not found" if $o{d};
+ run @MAILDIR_VIEWER, $p if $p =~ /^$MAILROOT/; # maildir
+ run @FILE_BROWSER, $p if -d $p; # directory
+ run @PDF_VIEWER, $p if -e $p and $p =~ /\.pdf$/; # pdf
+ run @EDITOR, $p if -e $p; # file
+ fail 'file not found' if $DEBUG;
# otherwise fall through
}
@@ -103,16 +106,19 @@ for ($phrase) {
sub path {
my $n = shift;
- $n = expand_tilde($n);
+ $n =~ s,^~([^/]+),/home/$1,;
+ $n =~ s,^~,/home/$ENV{USER},;
return $n if $n =~ /^\// or $n =~ /^~/;
- my $d = `xtitle`;
- chomp $d;
- $d =~ s/.*\(([^(]+)\)$/$1/;
- $d =~ s,^~([^/]+),/home/$1,;
- $d =~ s,^~,/home/$ENV{USER},;
- die "couldn't retrieve current directory\n"
- if ! -d $d and ! -d ($d = dirname($d));
- return "$d/$n";
+ for (`xtitle`) {
+ chomp;
+ s/.*\(([^(]+)\)$/$1/;
+ s,^~([^/]+),/home/$1,;
+ s,^~,/home/$ENV{USER},;
+ die "couldn't retrieve current directory\n"
+ if ! -d $_ and ! -d ($_ = dirname($_));
+ return "$_/$n";
+ }
+ die "couldn't retrieve current directory: xtitle not installed\n";
}
# take K => V and return environment variable K if defined, otherwise V
@@ -125,7 +131,7 @@ sub env {
sub handle {
$handler = shift;
- print STDERR "$handler MATCHED\n" if $o{d};
+ print STDERR "$handler MATCHED\n" if $DEBUG;
}
sub fail {
@@ -134,12 +140,13 @@ sub fail {
}
sub run {
- if ($o{d}) {
+ if ($DEBUG) {
my @argv = @_;
s/(\s)/\\$1/g for @argv; # escape whitespace
print STDERR "@argv\n";
}
- exec @_;
+ system "@_ &";
+ exit;
}
sub dirname {
@@ -147,34 +154,3 @@ sub dirname {
$path =~ s,/[^/]+,,;
return $path;
}
-
-# parse ARGV and return list of positionals and hash of option values
-sub arguments {
- my $usage = shift; # usage string
- my $n = shift; # number of positional arguments
- my %options = @_; # option specification
-
- # parse options (end upon --)
-
- while ($_ = shift @ARGV) {
- last if /^--$/;
- unshift @ARGV, $_ and last if not /^-/;
-
- s/^-//;
- if (defined $options{$_}) { $options{$_} = 1 }
- else { die $usage; }
- }
-
- # fill @positionals with $n strings (with undef upon empty ARGV)
-
- my @positionals;
- my $i = 0;
- while (++$i <= $n) {
- if ($_ = shift @ARGV) { push @positionals, $_ }
- else { push @positionals, undef }
- }
-
- die $usage if @ARGV; # all processing should be done
-
- return @positionals, %options;
-}
diff --git a/dwim.1 b/dwim.1
index 99776e2..d2e95fa 100644
--- a/dwim.1
+++ b/dwim.1
@@ -3,49 +3,101 @@
.Os
.Sh NAME
.Nm dwim
-.Nd do what i mean with a given phrase (file, URL etc.)
+.Nd do what I mean with a given phrase (file, URL etc.)
.
.Sh SYNOPSIS
.Nm dwim
-.Ar phrase
+.Op Fl d
+.Op Ar phrase
.
.Sh DESCRIPTION
+.Pp
.Nm dwim
is a program similar to Plan 9's plumber.
It takes a string
.Ar ( phrase )
and matches it against a number of regular expressions,
which are connected to handlers, specifying what to do with the phrase.
-.
+.Pp
+If no
+.Ar phrase
+is given, the current X selection is retrieved from
+.Xr xsel 1 .
+This is surprisingly useful.
+If you assign a shortcut key to invoke
+.Nm dwim
+in your window manager,
+you can select a string of text,
+press the shortcut key and
+.Nm
+will act on the selected text.
+.Pp
+If the
+.Li xtitle
+program is installed on the system,
+.Nm
+will try to figure out the current working directory
+from the window title.
+The following title formats are recognized:
+.Bl -enum -offset indent -compact
+.It
+.Em path
+.It
+.Em program
+.Em ( path )
+.El
+.Pp
+Tilde expansion is supported.
.Sh EXAMPLES
.Ss Without X selection
Open
-.Li message-window.lisp
-on line 164
-in
-.Li $EDITOR :
-.
+.Em Makefile
+in the configured text editor:
.Bd -literal
-$ grep 'def.*indicator ' *.lisp
-message-window.lisp:164:(defun show-frame-indicator (group &optional force)
-$ dwim message-window.lisp:164
+$ ls
+LICENSE Makefile README.md repl repl.1 repl.c
+$ dwim Makefile
.Ed
-.
.Ss With X selection
-Open
-.Li Makefile
-in
-.Li $EDITOR :
-.
+.Pp
+If we represent the current X selection with bold text,
+the following procedure opens
+.Em message-window.lisp
+on line 164
+in the configured text editor:
.Bd -literal
-$ ls
-LICENSE Makefile README.md repl repl.1 repl.c
-# (select Makefile)
+$ grep -n 'def.*indicator ' *.lisp
+\f(CBmessage-window.lisp:164:(defun\fP show-frame-indicator (group &optional force)
$ dwim
.Ed
-.
-.Sh EXTENDING
-It is a simple Perl script that is easily extensible.
-.Sh AUTHOR
+.Sh CONFIGURATION
+.Nm
+is configured by editing the source code.
+It is a simple Perl script,
+which uses regular expressions to parse phrases.
+Default programs are defined at the top of the script.
+The following associations are defined by default:
+.Bl -tag -width 18n -offset indent -compact
+.It OPENER
+.Li xtopen
+(change this to
+.Li xterm -e
+or equivalent)
+.It EDITOR
+.Li OPENER vi
+.It PDF_VIEWER
+.Li xpdf
+.It MAN_VIEWER
+.Li OPENER man
+.It MAILER
+.Li OPENER mutt
+.It BROWSER
+.Li OPENER w3m -title
+.It FILE_BROWSER
+.Li OPENER noice
+.It MAILDIR_VIEWER
+.Li OPENER mutt -f
+.El
+.Sh AUTHORS
.An -nosplit
-.An John Ankarström Aq Mt john@ankarstrom.se
+.An John Ankarström Aq Mt "john (at) ankarstrom.se"