From 99315219aba0481466c8bb236548284ccec5a1d5 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 1 Jun 2019 13:54:57 +0200 Subject: dwim.pl This is the Perl version of dwim. It is much easier to work with and extend, thanks to Perl's excellent regex support. The "phrase" (either $ARGV[0] or the primary X selection) is matched against regular expressions in the for loop (a primitive switch statement). This is the place to add handlers. Options are specified through environment variables, defined with default values in the section before the handlers. The `path` subroutine transforms a relative path to an absolute path based on the title of the current window. It depends on the `xtitle` program, and for it to work, you must instruct your shell (or editor) to set the terminal's title to the current directory (or currently edited file). (As such, `path` doesn't work with other programs than terminals and editors.) --- dwim | 1 + dwim.pl | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dwim.sh | 39 ------------------------------------- 3 files changed, 69 insertions(+), 39 deletions(-) create mode 120000 dwim create mode 100755 dwim.pl delete mode 100755 dwim.sh diff --git a/dwim b/dwim new file mode 120000 index 0000000..06baf07 --- /dev/null +++ b/dwim @@ -0,0 +1 @@ +dwim.pl \ No newline at end of file diff --git a/dwim.pl b/dwim.pl new file mode 100755 index 0000000..462fdbb --- /dev/null +++ b/dwim.pl @@ -0,0 +1,68 @@ +#!/usr/bin/perl + +# dwim (do what i mean) is my own plan9-like plumber + +use v5.24; +use warnings; +use strict; +use Path::ExpandTilde; + +die "usage: $0 phrase\n" if scalar @ARGV > 1; +my $p; +$p = $ARGV[0] if defined $ARGV[0]; +$p = `xsel -o` if not defined $ARGV[0]; + +our $OPENER = $ENV{OPENER}; +our $EDITOR = $ENV{EDITOR}; +our $MAILER = $ENV{MAILER}; +our $MAILROOT = $ENV{MAILROOT}; +$OPENER = "u" if not defined $OPENER; +$EDITOR = "vi" if not defined $EDITOR; +$MAILER = "mutt" if not defined $MAILER; +$MAILROOT = "/home/john/mail/" if not defined $MAILROOT; + +for ($p) { + # web address + if (/^(https?:\/\/.+)$/) { + exec "firefox", "$1" + } + + # e-mail address + if (/^(mailto:\/\/.+)$/ or /^(.+@.+\.\w+)$/) { + exec $MAILER, "$1" + } + + # file:line + if (/^(.+):(\d+)(:.*?)?$/) { + my $f = path($1); + exec $OPENER, $EDITOR, "-c", ":$2", "$f" + } + + # file:query (if file exists) + if (/^(.+):(.+)$/) { + my $f = path($1); + exec $OPENER, $EDITOR, "-c", "/$2", "$f" if -e $f; + # otherwise fall through + } + + # maildir (if it matches) or file (if it exists) + if (/^([^\s]+)$/) { + my $f = path($1); + exec $OPENER, $MAILER, "-f", "$f" if $f =~ /^$MAILROOT/; # maildir + exec $OPENER, $EDITOR, "$f" if -e $f; #file + # otherwise fall through + } + + # otherwise + die "no handler matched by: $p\n" +} + +sub path { + my $f = shift; + $f = expand_tilde($f); + return $f if $f =~ /^\// or $f =~ /^~/; + my $t = `xtitle`; + chomp $t; + die "couldn't retrieve directory\n" if ! -d $t and ! -d ($t = dirname $t); + return "$t/$f"; +} diff --git a/dwim.sh b/dwim.sh deleted file mode 100755 index 64f7773..0000000 --- a/dwim.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# dwim (do what i mean) is my own plan9-like plumber - -err() { echo "$@" 1>&2; exit 1; } -usage="$0 phrase" - -[ $# -gt 1 ] && err "$usage" -[ $# -eq 1 ] && p=$1 || p=$(xsel -o) -[ -z "$p" ] && err "$usage" - -[ -z "$OPENER" ] && OPENER=u - -case "$p" in -*:*) - file=${p%%:*} - line=${p#*:}; line=${line%:} - - dir= - case "$file" in - /*) ;; - ~*) ;; - *) - dir=$(xtitle)/ - [ ! -d "$dir" ] && err "couldn't retrieve directory" - ;; - esac - - exec "$OPENER" "$EDITOR" -c ":$line" "$dir$file" - ;; -/*) - exec "$OPENER" "$EDITOR" "${p%:}" - ;; -~*) - exec "$OPENER" "$EDITOR" "${p%:}" - ;; -esac - -err "no handler matched" -- cgit v1.2.3