aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2017-01-06 20:10:01 +1300
committerTom Ryder <tom@sanctum.geek.nz>2017-01-06 20:10:01 +1300
commit94331ff4049628e696d733420232d5b0cfef1919 (patch)
tree960c8ee85e03183022eb54e236745d4126fd1322
parentMerge branch 'master' into port/bsd/netbsd (diff)
parentRename keyboard trap func less ambiguously (diff)
downloaddotfiles-94331ff4049628e696d733420232d5b0cfef1919.tar.gz
dotfiles-94331ff4049628e696d733420232d5b0cfef1919.zip
Merge branch 'master' into port/bsd/netbsd
-rw-r--r--.gitignore7
-rw-r--r--IDEAS.markdown1
-rw-r--r--ISSUES.markdown11
-rw-r--r--Makefile64
-rw-r--r--README.markdown8
-rw-r--r--X/xbindkeysrc2
-rw-r--r--bash/bashrc8
-rwxr-xr-xbin/bcq4
-rw-r--r--bin/brnl.sed2
-rwxr-xr-xbin/clog5
-rw-r--r--bin/gwp.awk2
-rw-r--r--bin/htdec.sed4
-rw-r--r--bin/htenc.sed4
-rw-r--r--bin/jfp.sed4
-rwxr-xr-xbin/loc5
-rw-r--r--bin/med.awk2
-rw-r--r--bin/nlbr.sed2
-rw-r--r--bin/onl.awk15
-rwxr-xr-xbin/pp9
-rwxr-xr-xbin/pph5
-rw-r--r--bin/rfct.awk16
-rwxr-xr-xbin/rndl2
-rw-r--r--bin/sec.awk2
-rwxr-xr-xbin/sshi8
-rwxr-xr-xbin/stbl2
-rwxr-xr-xbin/xgo2
-rw-r--r--finger/pgpkey6
-rw-r--r--games/chkl.sed6
-rw-r--r--ksh/kshrc16
-rw-r--r--ksh/kshrc.d/bind.ksh28
-rw-r--r--man/man1/bcq.1df13
-rw-r--r--man/man1/brnl.1df20
-rw-r--r--man/man1/clog.1df3
-rw-r--r--man/man1/htdec.1df18
-rw-r--r--man/man1/htenc.1df18
-rw-r--r--man/man1/jfp.1df39
-rw-r--r--man/man1/loc.1df5
-rw-r--r--man/man1/nlbr.1df21
-rw-r--r--man/man1/onl.1df18
-rw-r--r--man/man1/pp.1df19
-rw-r--r--man/man1/pph.1df16
-rw-r--r--man/man6/chkl.6df32
-rw-r--r--sh/shrc.d/md.sh18
-rw-r--r--share/chkl.sample5
-rw-r--r--vim/vimrc16
-rw-r--r--zsh/zshrc8
46 files changed, 418 insertions, 103 deletions
diff --git a/.gitignore b/.gitignore
index 110f8c4b..a9f181be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,19 @@
+bin/brnl
bin/csmw
bin/ddup
bin/gwp
+bin/jfp
bin/han
+bin/htdec
+bin/htenc
bin/max
bin/mean
bin/med
bin/mftl
bin/min
bin/mode
+bin/nlbr
+bin/onl
bin/rfct
bin/rndi
bin/sd2u
@@ -19,6 +25,7 @@ bin/unf
bin/uts
games/acq
games/aesth
+games/chkl
games/drakon
games/kvlt
games/rot13
diff --git a/IDEAS.markdown b/IDEAS.markdown
index 0a256473..7f94b027 100644
--- a/IDEAS.markdown
+++ b/IDEAS.markdown
@@ -7,3 +7,4 @@ Ideas
* Wouldn't be too hard to add some HTTP BASIC auth to ix(1df) to make pastes
manageable
* Have eds(1df) accept stdin with the "starting content" for the script
+* Convert all the manual pages to mandoc maybe? <https://en.wikipedia.org/wiki/Mandoc>
diff --git a/ISSUES.markdown b/ISSUES.markdown
index 0b31661f..383d7906 100644
--- a/ISSUES.markdown
+++ b/ISSUES.markdown
@@ -7,15 +7,14 @@ Known issues
* OpenBSD doesn't have a `pandoc` package at all. It would be nice to find
some way of converting the README.markdown into a palatable troff format
with some more readily available (and preferably less heavyweight) tool.
-* The checks gscr(1df) makes to determine where it is are a bit naive (don't
+* The checks gscr(1df) makes to determine where it is are a bit naïve (don't
work with bare repos) and could probably be improved with some appropriate
git-reflog(1) calls
-* dr(1df) is probably more practical in awk
-* How come commands I fix with the fc builtin always seem to exit 1 even if
- they succeed? Did I do that or is it Bash?
+* dr(6df) is probably more practical in awk
* Running the block of git(1) commands in the prompt leaves five "stale"
jobspecs around that flee after a jobs builtin run; only saw this manifest
after 90dcadf; either I understand job specs really poorly or this may be a
bug in bash
-* md() does not handle e.g. "../..". If there's a tidy way of making it do so
- that would probably be worhwhile.
+* I can't find a clean way of detecting a restricted shell for ksh instances
+ to prevent trying to load anything fancy (works for Bash)
+ * Zsh, either! $options[restricted] is "off" within the startup file
diff --git a/Makefile b/Makefile
index 60fec019..06d5adf3 100644
--- a/Makefile
+++ b/Makefile
@@ -67,16 +67,22 @@ EMAIL := tom@sanctum.geek.nz
KEY := 0xC14286EA77BB8872
SENDMAIL := msmtp
-all : bin/csmw \
+BINS = bin/brnl \
+ bin/csmw \
bin/ddup \
bin/gwp \
bin/han \
+ bin/htdec \
+ bin/htenc \
+ bin/jfp \
bin/max \
bin/mean \
bin/med \
bin/mftl \
bin/min \
bin/mode \
+ bin/nlbr \
+ bin/onl \
bin/rfct \
bin/rndi \
bin/sd2u \
@@ -86,37 +92,22 @@ all : bin/csmw \
bin/tot \
bin/unf \
bin/uts \
- git/gitconfig \
- gnupg/gpg.conf
+
+GAMES = games/acq \
+ games/aesth \
+ games/chkl \
+ games/drakon \
+ games/kvlt \
+ games/rot13 \
+ games/strik \
+ games/zs
+
+all : $(BINS) git/gitconfig gnupg/gpg.conf
clean distclean :
rm -f \
- bin/csmw \
- bin/ddup \
- bin/gwp \
- bin/han \
- bin/max \
- bin/mean \
- bin/med \
- bin/mftl \
- bin/min \
- bin/mode \
- bin/rfct \
- bin/rndi \
- bin/sd2u \
- bin/sec \
- bin/slsf \
- bin/su2d \
- bin/tot \
- bin/unf \
- bin/uts \
- games/acq \
- games/aesth \
- games/drakon \
- games/kvlt \
- games/rot13 \
- games/strik \
- games/zs \
+ $(BINS) \
+ $(GAMES) \
git/gitconfig \
gnupg/gpg.conf \
man/man7/dotfiles.7df \
@@ -197,9 +188,7 @@ install-bash-completion : install-bash
install -pm 0644 -- bash/bash_completion "$(HOME)"/.config/bash_completion
install -pm 0644 -- bash/bash_completion.d/* "$(HOME)"/.bash_completion.d
-install-bin : bin/csmw bin/ddup bin/gwp bin/han bin/max bin/mean bin/med \
- bin/mftl bin/min bin/mode bin/rfct bin/rndi bin/sd2u bin/sec bin/slsf \
- bin/su2d bin/tot bin/unf bin/uts install-bin-man
+install-bin : $(BINS) install-bin-man
install -m 0755 -d -- "$(HOME)"/.local/bin
for name in bin/* ; do \
[ -x "$$name" ] || continue ; \
@@ -229,8 +218,7 @@ install-finger :
install -pm 0644 -- finger/project "$(HOME)"/.project
install -pm 0644 -- finger/pgpkey "$(HOME)"/.pgpkey
-install-games : games/acq games/aesth games/drakon games/kvlt games/rot13 \
- games/strik games/zs check-games install-games-man
+install-games : $(GAMES) install-games-man
install -m 0755 -d -- "$(HOME)"/.local/games
for name in games/* ; do \
[ -x "$$name" ] || continue ; \
@@ -412,10 +400,10 @@ check : check-bash \
check-bash :
check/bash
-check-bin :
+check-bin : $(BINS)
check/bin
-check-games :
+check-games : $(GAMES)
check/games
check-man :
@@ -448,10 +436,10 @@ lint : check \
lint-bash :
lint/bash
-lint-bin :
+lint-bin : $(BINS)
lint/bin
-lint-games :
+lint-games : $(GAMES)
lint/games
lint-ksh :
diff --git a/README.markdown b/README.markdown
index 39bc3666..97823267 100644
--- a/README.markdown
+++ b/README.markdown
@@ -409,12 +409,16 @@ Installed by the `install-bin` target:
* `min(1df)` prints the minimum.
* `mode(1df)` prints the first encountered mode.
* `tot(1df)` totals the set.
+* Two quick-and-dirty HTML text node content encoding tools:
+ * `htenc(1df)` encodes.
+ * `htdec(1df)` decodes.
* `ap(1df)` reads arguments for a given command from the standard input,
prompting if appropriate
* `apf(1df)` prepends arguments to a command with ones read from a file,
intended as a framework for shell wrappers or functions.
* `ax(1df)` evaluates an awk expression given on the command line; this is
intended as a quick way to test how Awk would interpret a given expression.
+* `bcq(1df)` runs `bc(1)`, quieting it down if need be.
* `bel(1df)` prints a terminal bell character.
* `bl(1df)` generates a given number of blank lines.
* `bp(1df)` runs `br(1df)` after prompting for an URL
@@ -460,6 +464,7 @@ Installed by the `install-bin` target:
repository.
* `ix(1df)` posts its input to the ix.io pastebin.
* `jfc(1df)` adds and commits lazily to a Git repository.
+* `jfp(1df)` prints its input, excluding any shebang on the first line only.
* `jfcd(1df)` watches a directory for changes and runs `jfc(1df)` if it sees
any.
* `loc(1df)` is a quick-search wrapped around `find(1)`.
@@ -471,7 +476,10 @@ Installed by the `install-bin` target:
* `mkcp(1df)` creates a directory and copies preceding arguments into it.
* `mkmv(1df)` creates a directory and moves preceding arguments into it.
* `motd(1df)` shows the system MOTD.
+* `onl(1df)` crunches input down to one printable line.
* `pa(1df)` prints its arguments, one per line.
+* `pp(1df)` prints the full path of each argument using `$PWD`.
+* `pph(1df)` runs `pp(1df)` and includes a leading `$HOSTNAME:`.
* `paz(1df)` print its arguments terminated by NULL chars.
* `pit(1df)` runs its input through a pager if its standard output looks like
a terminal.
diff --git a/X/xbindkeysrc b/X/xbindkeysrc
index 22f1ce98..00855b09 100644
--- a/X/xbindkeysrc
+++ b/X/xbindkeysrc
@@ -28,5 +28,5 @@
"exec amixer -q sset Master 5%- unmute"
XF86AudioLowerVolume
-"exec urxvtcd -e bc"
+"exec urxvtcd -e bcq"
XF86Calculator
diff --git a/bash/bashrc b/bash/bashrc
index 088182ef..3070c00c 100644
--- a/bash/bashrc
+++ b/bash/bashrc
@@ -4,6 +4,11 @@ case $- in
*) return ;;
esac
+# Don't do anything if restricted, not even sourcing the ENV file
+# Testing $- for "r" doesn't work
+# shellcheck disable=SC2128
+[ -n "$BASH_VERSINFO" ] && shopt -q restricted_shell && return
+
# If ENV is set, source it to get all the POSIX-compatible interactive stuff;
# we should be able to do this even if we're running a truly ancient Bash
[ -n "$ENV" ] && . "$ENV"
@@ -17,9 +22,6 @@ esac
((10#${BASH_VERSINFO[1]%%[!0-9]*} < 5)) &&
return
-# Don't do anything if running a restricted shell
-shopt -q restricted_shell && return
-
# Keep around 32K lines of history in file
HISTFILESIZE=$((1 << 15))
diff --git a/bin/bcq b/bin/bcq
new file mode 100755
index 00000000..7b950b56
--- /dev/null
+++ b/bin/bcq
@@ -0,0 +1,4 @@
+#!/bin/sh
+# Fire up bc(1), hushing it if it looks like GNU
+[ -e "$HOME"/.cache/bc/quiet ] && set -- --quiet "$@"
+exec bc "$@"
diff --git a/bin/brnl.sed b/bin/brnl.sed
new file mode 100644
index 00000000..00a33d80
--- /dev/null
+++ b/bin/brnl.sed
@@ -0,0 +1,2 @@
+# Remove HTML linebreaks from content (undo nlbr(1df))
+s_<br>$__
diff --git a/bin/clog b/bin/clog
index d52ab4c5..037f24c7 100755
--- a/bin/clog
+++ b/bin/clog
@@ -1,7 +1,10 @@
#!/bin/sh
# Record a timestamped message to a logfile, defaulting to ~/.clog
+self=clog
+command -v rlwrap >/dev/null 2>&1 &&
+ set -- rlwrap -C "$self" "$@"
{
date
- cat -
+ "$@" cat -
printf '%s\n' --
} >>"${CLOG:-"$HOME"/.clog}"
diff --git a/bin/gwp.awk b/bin/gwp.awk
index 32fe97f2..976b5b84 100644
--- a/bin/gwp.awk
+++ b/bin/gwp.awk
@@ -23,7 +23,7 @@ BEGIN {
# Bailout function
function fail(str) {
- printf "%s: %s\n", self, str > "/dev/stderr"
+ printf "%s: %s\n", self, str | "cat >&2"
exit(1)
}
diff --git a/bin/htdec.sed b/bin/htdec.sed
new file mode 100644
index 00000000..6f9d6977
--- /dev/null
+++ b/bin/htdec.sed
@@ -0,0 +1,4 @@
+# Quick-and-dirty HTML text decoding
+s_\&lt;_<_g
+s_\&gt;_>_g
+s_\&amp;_\&_g
diff --git a/bin/htenc.sed b/bin/htenc.sed
new file mode 100644
index 00000000..0429b525
--- /dev/null
+++ b/bin/htenc.sed
@@ -0,0 +1,4 @@
+# Quick-and-dirty HTML text encoding
+s_&_\&amp;_g
+s_<_\&lt;_g
+s_>_\&gt;_g
diff --git a/bin/jfp.sed b/bin/jfp.sed
new file mode 100644
index 00000000..938c4e4d
--- /dev/null
+++ b/bin/jfp.sed
@@ -0,0 +1,4 @@
+#!/bin/sed -f
+1 {
+ /^\#\!/d
+}
diff --git a/bin/loc b/bin/loc
index 16d355f2..d92dc886 100755
--- a/bin/loc
+++ b/bin/loc
@@ -10,9 +10,10 @@ fi
# Iterate through each search term and run an appropriate find(1) command
for pat ; do
- # Skip dotfiles and dotdirs, print anything that matches the term as a
- # substring (and stop iterating through it)
+ # Skip dotfiles, dotdirs, and symbolic links; print anything that matches
+ # the term as a substring (and stop iterating through it)
find . \
-name .\* ! -name . -prune -o \
+ -type l -prune -o \
-name \*"$pat"\* -prune -print
done
diff --git a/bin/med.awk b/bin/med.awk
index 8167f8dd..aee120cb 100644
--- a/bin/med.awk
+++ b/bin/med.awk
@@ -1,7 +1,7 @@
# Get the median of a list of numbers
{ vals[NR] = $1 }
NR > 1 && vals[NR] < vals[NR-1] && !warn++ {
- printf "med: Input not sorted!\n" > "/dev/stderr"
+ printf "med: Input not sorted!\n" | "cat >&2"
}
END {
# Error out if we read no values at all
diff --git a/bin/nlbr.sed b/bin/nlbr.sed
new file mode 100644
index 00000000..6ba1a3ef
--- /dev/null
+++ b/bin/nlbr.sed
@@ -0,0 +1,2 @@
+# Add HTML linebreaks to content
+s_$_<br>_
diff --git a/bin/onl.awk b/bin/onl.awk
new file mode 100644
index 00000000..466b8451
--- /dev/null
+++ b/bin/onl.awk
@@ -0,0 +1,15 @@
+# Flatten input into one single-space separated line with no unprintable chars
+
+# For each line of input ...
+{
+ # Strip out non-printable characters and rebuild the fields
+ gsub(/[[:cntrl:]]/, "")
+
+ # Print each field, without a newline; add a leading space if it's not the
+ # very first one
+ for (i = 1; i <= NF; i++)
+ printf (f++) ? OFS "%s" : "%s", $i
+}
+
+# Print a newline to close the line
+END { print "" }
diff --git a/bin/pp b/bin/pp
new file mode 100755
index 00000000..d9fe6488
--- /dev/null
+++ b/bin/pp
@@ -0,0 +1,9 @@
+#!/bin/sh
+# Print the full path to each argument; path need not exist
+for arg ; do
+ case $arg in
+ /*) path=$arg ;;
+ *) path=$PWD/$arg ;;
+ esac
+ printf '%s\n' "$path"
+done
diff --git a/bin/pph b/bin/pph
new file mode 100755
index 00000000..684aaafd
--- /dev/null
+++ b/bin/pph
@@ -0,0 +1,5 @@
+#!/bin/sh
+# Run pp(1df) on args, prefix with machine hostname
+hostname=$(hostname -s) || exit
+pp "$@" |
+sed 's_^_'"$hostname":'_'
diff --git a/bin/rfct.awk b/bin/rfct.awk
index ac8a2a87..256841a7 100644
--- a/bin/rfct.awk
+++ b/bin/rfct.awk
@@ -1,8 +1,16 @@
# Format an RFC in text format for terminal reading
# A record is a paragraph
-BEGIN { RS = "" }
+BEGIN {
+ RS = ""
+ ORS = "\n\n"
+}
-# Print the block followed by two newlines, as long as it has at least one
-# alphanumeric character and no pagebreak (^L, 0x0C) characters
-/[a-zA-Z0-9]/ && !/ / { printf "%s\n\n", $0 }
+{
+ # Strip out control characters, except tab and newline
+ gsub(/[^[:print:]\n\t]/, "")
+
+ # If there's anything left, print it
+ if (length)
+ print
+}
diff --git a/bin/rndl b/bin/rndl
index 7d2c3041..c09c2c78 100755
--- a/bin/rndl
+++ b/bin/rndl
@@ -36,7 +36,7 @@ lc=$(sed -- '$=;d' "$@") || exit
# If there were none, bail
case $lc in
''|0)
- printf 2>&1 'rndl: No lines found on input\n'
+ printf >&2 'rndl: No lines found on input\n'
exit 2
;;
esac
diff --git a/bin/sec.awk b/bin/sec.awk
index 3ebf02b6..001b017d 100644
--- a/bin/sec.awk
+++ b/bin/sec.awk
@@ -6,7 +6,7 @@ BEGIN { FS = ":0*" }
# If no fields, too many fields, or illegal characters, warn, skip line, accrue
# errors
!NF || NF > 3 || /[^0-9:]/ {
- print "sec: Bad format" > "/dev/stderr"
+ print "sec: Bad format" | "cat >&2"
err = 1
next
}
diff --git a/bin/sshi b/bin/sshi
index bf710b8a..80e00a10 100755
--- a/bin/sshi
+++ b/bin/sshi
@@ -7,9 +7,9 @@ if [ -z "$SSH_CONNECTION" ] ; then
exit 1
fi
-# Print the two variables into a subshell so we can chop them up with read
-printf '%s\n' "$SSH_CONNECTION" "${SSH_TTY:-unknown}" | (
-
+# Print the two variables into a compound command so we can `read` them
+printf '%s\n' "$SSH_CONNECTION" "${SSH_TTY:-unknown}" |
+{
# Read connection details from first line
read -r ci cp si sp
@@ -25,4 +25,4 @@ printf '%s\n' "$SSH_CONNECTION" "${SSH_TTY:-unknown}" | (
"${ch:-"$ci"}" "$cp" \
"${sh:-"$si"}" "$sp" \
"$tty"
-)
+}
diff --git a/bin/stbl b/bin/stbl
index 940fc3bb..34a06251 100755
--- a/bin/stbl
+++ b/bin/stbl
@@ -3,7 +3,7 @@
# Check arguments
if [ "$#" -eq 0 ] ; then
- printf 2>&1 'stbl: Need a filename\n'
+ printf >&2 'stbl: Need a filename\n'
exit 2
fi
diff --git a/bin/xgo b/bin/xgo
index 49861aa8..46d90f2e 100755
--- a/bin/xgo
+++ b/bin/xgo
@@ -3,7 +3,7 @@
# Check arguments
if [ "$#" -eq 0 ] ; then
- printf 2>&1 'xgo: At least one URL required\n'
+ printf >&2 'xgo: At least one URL required\n'
fi
# Iterate over the URL arguments
diff --git a/finger/pgpkey b/finger/pgpkey
index b228a50e..6d2cbeec 100644
--- a/finger/pgpkey
+++ b/finger/pgpkey
@@ -1,5 +1,5 @@
-pub 4096R/0xC14286EA77BB8872 2013-03-12 [expires: 2017-04-17]
+pub 4096R/0xC14286EA77BB8872 2013-03-12 [expires: 2018-01-02]
Key fingerprint = FA09 C06E 1B67 0CD0 B2F5 DE60 C142 86EA 77BB 8872
uid [ultimate] Thomas Ryder (tyrmored, tejr) <tom@sanctum.geek.nz>
-sub 4096R/0x96C2CD91E67AC61D 2013-03-12 [expires: 2017-04-17]
-sub 4096R/0xB5AF5F8925926609 2013-03-12 [expires: 2017-04-17]
+sub 4096R/0x96C2CD91E67AC61D 2013-03-12 [expires: 2018-01-02]
+sub 4096R/0xB5AF5F8925926609 2013-03-12 [expires: 2018-01-02]
diff --git a/games/chkl.sed b/games/chkl.sed
new file mode 100644
index 00000000..40c35cee
--- /dev/null
+++ b/games/chkl.sed
@@ -0,0 +1,6 @@
+#!/bin/sed -f
+# Change an ASCII checklist with [/], [x], and [ ] boxes to a Unicode one
+/^#/d
+s_^\[ \]_☐_
+s_^\[/\]_☑_
+s_^\[[xX]\]_☒_
diff --git a/ksh/kshrc b/ksh/kshrc
index cf7812d6..5d481bb4 100644
--- a/ksh/kshrc
+++ b/ksh/kshrc
@@ -1,7 +1,21 @@
-# Emacs-style key bindings
+# Emacs-style key bindings; these are present in ksh88 and pdksh
set -o braceexpand
set -o emacs
+# Track locations of binaries
+set -o trackall
+
+# Use subshells to test these newer options, as ksh93 seems to get very upset
+# if you try to set an option and it doesn't exist
+
+# Try to get "**" as a recursive glob
+(set -o globstar) 2>/dev/null &&
+ set -o globstar
+
+# Try to get !-style history expansion
+(set -o histexpand) 2>/dev/null &&
+ set -o histexpand
+
# Save history
HISTFILE=$HOME/.ksh_history
HISTSIZE=$((1 << 10))
diff --git a/ksh/kshrc.d/bind.ksh b/ksh/kshrc.d/bind.ksh
new file mode 100644
index 00000000..34cb5f5a
--- /dev/null
+++ b/ksh/kshrc.d/bind.ksh
@@ -0,0 +1,28 @@
+# Try to bind ^I to complete words and ^L to clear the screen
+case $KSH_VERSION in
+
+ # ksh93 is lovely, but complex; rebind ^L so it does the same as Alt-^L
+ *'93'*)
+ keybd_trap() {
+ # shellcheck disable=SC2154
+ case ${.sh.edchar} in
+ $'\f') .sh.edchar=$'\e\f' ;;
+ esac
+ }
+ trap keybd_trap KEYBD
+ ;;
+
+ # More straightforward with mksh; bind keys to the appropriate emacs mode
+ # editing commands
+ *'MIRBSD KSH'*)
+ bind '^I'='complete'
+ bind '^L'='clear-screen'
+ ;;
+
+ # Similar with pdksh; there's a "complete" command, but not a "clear" one,
+ # so we fake it with clear(1) and some yanking
+ *'PD KSH'*)
+ bind '^I'='complete'
+ bind -m '^L'='^Uclear^J^Y'
+ ;;
+esac
diff --git a/man/man1/bcq.1df b/man/man1/bcq.1df
new file mode 100644
index 00000000..55b44a69
--- /dev/null
+++ b/man/man1/bcq.1df
@@ -0,0 +1,13 @@
+.TH BCQ 1df "January 2017" "Manual page for bcq"
+.SH NAME
+.B bcq
+\- run bc(1), quieting it if need be
+.SH SYNOPSIS
+.B bcq
+.SH DESCRIPTION
+.B bcq
+starts bc(1), checking ~/.cache/bc/quiet to see if a --quiet option is
+available, adding it if so to elide the annoying GNU boilerplate for an
+interactive session.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/brnl.1df b/man/man1/brnl.1df
new file mode 100644
index 00000000..e15eadce
--- /dev/null
+++ b/man/man1/brnl.1df
@@ -0,0 +1,20 @@
+.TH BRNL 1df "January 2017" "Manual page for brnl"
+.SH NAME
+.B brnl
+\- strip trailing HTML linebreaks
+.SH SYNOPSIS
+.B brnl
+FILE
+.br
+.B brnl
+FILE1 FILE...
+.br
+command |
+.B brnl
+.SH DESCRIPTION
+.B brnl
+strips trailing HTML linebreaks (<br>) from content. It reverses nlbr(1df).
+.SH SEE ALSO
+htenc(1df), htdec(1df), nlbr(1df)
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/clog.1df b/man/man1/clog.1df
index a0e6d117..0e3e7b87 100644
--- a/man/man1/clog.1df
+++ b/man/man1/clog.1df
@@ -13,5 +13,8 @@ getting real tired of all this overengineering
receives a message on stdin, timestamps it with a leading date(1), and writes
it to the file with path in environment variable CLOG, defaulting to ~/.clog,
terminating each entry with two hyphens.
+,P
+If rlwrap(1) is found, it will be used for the line editing. If not, just the
+terminal's cooked mode will be used.
.SH AUTHOR
Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/htdec.1df b/man/man1/htdec.1df
new file mode 100644
index 00000000..0242312a
--- /dev/null
+++ b/man/man1/htdec.1df
@@ -0,0 +1,18 @@
+.TH HTDEC 1df "January 2017" "Manual page for htdec"
+.SH NAME
+.B htdec
+\- quick-and-dirty HTML to text decoding for text nodes
+.SH SYNOPSIS
+.B htdec
+/usr/share/lovecraft/the-silver-key.html > the-silver-key.txt
+.br
+curl http://example.com/netstat.html |
+.B htdec
+.SH DESCRIPTION
+.B htdec
+unescapes left angle quotes, right angle quotes, and ampersands to put HTML
+text node content into plain text.
+.SH SEE ALSO
+htenc(1df), brnl(1df), nlbr(1df)
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/htenc.1df b/man/man1/htenc.1df
new file mode 100644
index 00000000..24093f8c
--- /dev/null
+++ b/man/man1/htenc.1df
@@ -0,0 +1,18 @@
+.TH HTENC 1df "January 2017" "Manual page for htenc"
+.SH NAME
+.B htenc
+\- quick-and-dirty text to HTML encoding for text nodes
+.SH SYNOPSIS
+.B htenc
+/usr/share/lovecraft/the-silver-key.txt > the-silver-key.html
+.br
+netstat -aunt |
+.B htenc > netstat.html
+.SH DESCRIPTION
+.B htenc
+escapes ampersands, left angle quotes, and right angle quotes to put text into
+a form that should be suitable to include in XML/HTML text nodes.
+.SH SEE ALSO
+htdec(1df), brnl(1df), nlbr(1df)
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/jfp.1df b/man/man1/jfp.1df
new file mode 100644
index 00000000..6e9e18f2
--- /dev/null
+++ b/man/man1/jfp.1df
@@ -0,0 +1,39 @@
+.TH JFP 1df "January 2017" "Manual page for jfp"
+.SH NAME
+.B jfp
+\- print input, excluding any shebang on the first line
+.SH SYNOPSIS
+.B jfp
+FILE [FILE2 ...]
+.br
+.B jfp
+< FILE
+.P
+#!/usr/bin/env jfp
+.br
+All this content will be printed verbatim,
+.br
+except for the first line,
+.br
+because it's a shebang.
+.SH DESCRIPTION
+.B jfp
+prints all the input given to it except for the first line if it starts with a
+shebang "#!". This means it can be used in a shebang to simply echo the entire
+remaining contents of the script.
+.SH NOTES
+Can you guess what it stands for?
+.P
+A portable way to do the same thing could be using a heredoc with cat(1):
+.P
+ #!/bin/sh
+ cat <<'EOD'
+ All this content will be printed verbatim...
+ ...except for the first line...
+ ...because it's a shebang.
+ EOD
+.P
+The only snag there is having to check the token word doesn't appear in the
+document.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/loc.1df b/man/man1/loc.1df
index 2c3c3a80..a70d2d9b 100644
--- a/man/man1/loc.1df
+++ b/man/man1/loc.1df
@@ -9,7 +9,8 @@ PATTERN1 [PATTERN2...]
.B loc
is a simple wrapper around find(1) which searches in the current directory tree
for filenames matching a pattern, and prints them to stdout, newline-separated.
-It skips dotfiles, and doesn't recurse further into a directory if it matches
-the terms. It is intended only for interactive use as a shortcut.
+It skips dotfiles and symbolic links, and doesn't recurse further into a
+directory if it matches the terms. It is intended only for interactive use as a
+shortcut.
.SH AUTHOR
Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/nlbr.1df b/man/man1/nlbr.1df
new file mode 100644
index 00000000..3cdde6c1
--- /dev/null
+++ b/man/man1/nlbr.1df
@@ -0,0 +1,21 @@
+.TH NLBR 1df "January 2017" "Manual page for nlbr"
+.SH NAME
+.B nlbr
+\- add trailing HTML linebreaks
+.SH SYNOPSIS
+.B nlbr
+FILE
+.br
+.B nlbr
+FILE1 FILE...
+.br
+command |
+.B nlbr
+.SH DESCRIPTION
+.B nlbr
+adds trailing HTML linebreaks (<br>) to content. Good for running after
+htenc(1df).
+.SH SEE ALSO
+htenc(1df), htdec(1df), brnl(1df)
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/onl.1df b/man/man1/onl.1df
new file mode 100644
index 00000000..7e84b9ba
--- /dev/null
+++ b/man/man1/onl.1df
@@ -0,0 +1,18 @@
+.TH ONL 1df "January 2017" "Manual page for onl"
+.SH NAME
+.B onl
+\- force standard input onto one printable line
+.SH USAGE
+.B onl
+FILE1 [FILE2 ...]
+.br
+.B onl
+< FILE
+.br
+program |
+.B onl
+.SH DESCRIPTION
+Condense input down to one line with only printable characters, no leading or
+trailing spaces, and a single space in place of multiple spaces or tabs.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/pp.1df b/man/man1/pp.1df
new file mode 100644
index 00000000..322e7b48
--- /dev/null
+++ b/man/man1/pp.1df
@@ -0,0 +1,19 @@
+.TH PP 1df "January 2017" "Manual page for pp"
+.SH NAME
+.B pp
+\- print the full path to each argument
+.SH SYNOPSIS
+.B pp
+/arg arg2 ./arg3
+.SH DESCRIPTION
+.B pp
+uses $PWD to print the full path to each of its arguments, unless they begin
+with a slash, in which case they are printed verbatim.
+.P
+The path need not actually exist.
+.SH CAVEATS
+Newlines in filenames will still work, but the results won't really make sense
+as they'll be indistinguishable from newlines separating the files. This is for
+generating human-readable file lists, not for machines.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/pph.1df b/man/man1/pph.1df
new file mode 100644
index 00000000..0ad98fc5
--- /dev/null
+++ b/man/man1/pph.1df
@@ -0,0 +1,16 @@
+.TH PPH 1df "January 2017" "Manual page for pp"
+.SH NAME
+.B pp
+\- print the full path to each argument, hostname prepended
+.SH SYNOPSIS
+.B pp
+/arg arg2 ./arg3
+.SH DESCRIPTION
+.B pph
+runs pp(1df) on the arguments to print the full path to each one, and also
+prepends the machine's hostname and a colon to each line.
+.SH CAVEATS
+Newlines in filenames will mess this up. This is for generating human-readable
+file lists, not for machines.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man6/chkl.6df b/man/man6/chkl.6df
new file mode 100644
index 00000000..091ee9ed
--- /dev/null
+++ b/man/man6/chkl.6df
@@ -0,0 +1,32 @@
+.TH CHKL 6df "January 2017" "Manual page for chkl"
+.SH NAME
+.B chkl
+\- format an ASCII checklist with Unicode symbols
+.SH USAGE
+.B chkl
+.br
+[/] rekt
+.br
+[ ] not rekt
+.br
+^D
+.SH DESCRIPTION
+.B chkl
+replaces ASCII approximations for checkboxes in ticked, crossed, or blank state
+at the start of lines with appropriate Unicode symbols:
+.IP ☐ 0.2i
+Unicode Character 'BALLOT BOX' (U+2610)
+.IP ☑
+Unicode Character 'BALLOT BOX WITH CHECK' (U+2611)
+.IP ☒
+Unicode Character 'BALLOT BOX WITH X' (U+2612)
+.P
+Lines with a leading # will be ignored.
+.SH SEE ALSO
+<http://www.fileformat.info/info/unicode/char/2610/index.htm>
+.br
+<http://www.fileformat.info/info/unicode/char/2611/index.htm>
+.br
+<http://www.fileformat.info/info/unicode/char/2612/index.htm>
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/sh/shrc.d/md.sh b/sh/shrc.d/md.sh
index 7085d258..6fd3d7ca 100644
--- a/sh/shrc.d/md.sh
+++ b/sh/shrc.d/md.sh
@@ -10,20 +10,12 @@ md() {
# If first arg unset or empty, assume the user means the current dir
[ -n "$1" ] || set -- "$PWD"
- # If specified path is . or .., quietly expand it
- case $1 in
- .) set -- "${PWD%/}" ;;
- ..)
- set -- "${PWD%/}"
- set -- "${1%/*}"
- ;;
- esac
+ # Jump to the dir and emit PWD from a subshell to get an absolute path
+ set -- "$(cd -- "$1" && printf %s "$PWD")"
- # If specified path not a directory, refuse to mark it
- if ! [ -d "$1" ] ; then
- printf >&2 'md(): Not a directory\n'
- return 2
- fi
+ # If that turned up empty, we have failed; the cd call probably threw an
+ # error for us too
+ [ -n "$1" ] || return
# Save the specified path in the marked directory var
# shellcheck disable=SC2034
diff --git a/share/chkl.sample b/share/chkl.sample
new file mode 100644
index 00000000..63076fa7
--- /dev/null
+++ b/share/chkl.sample
@@ -0,0 +1,5 @@
+[/] sh
+[ ] bash
+[ ] ksh93
+[ ] pdksh
+[x] zsh
diff --git a/vim/vimrc b/vim/vimrc
index a454246e..1c1f2b26 100644
--- a/vim/vimrc
+++ b/vim/vimrc
@@ -14,22 +14,6 @@ endif
" Load plugins and indentation for file types
if has('autocmd')
filetype indent plugin on
-
- " Shortcuts to quickly switch to common file types; handy when using
- " editing abstractions like sudoedit(8)
- nnoremap _ap :setlocal filetype=apache<CR>
- nnoremap _bi :setlocal filetype=bindzone<CR>
- nnoremap _cs :setlocal filetype=css<CR>
- nnoremap _ht :setlocal filetype=html<CR>
- nnoremap _js :setlocal filetype=javascript<CR>
- nnoremap _md :setlocal filetype=markdown<CR>
- nnoremap _pl :setlocal filetype=perl<CR>
- nnoremap _ph :setlocal filetype=php<CR>
- nnoremap _py :setlocal filetype=python<CR>
- nnoremap _rb :setlocal filetype=ruby<CR>
- nnoremap _sh :setlocal filetype=sh<CR>
- nnoremap _vi :setlocal filetype=vim<CR>
- nnoremap _xm :setlocal filetype=xml<CR>
endif
" Use backup features if on a UNIX-like system and not using sudo(8)
diff --git a/zsh/zshrc b/zsh/zshrc
index 2376e568..a97c0a73 100644
--- a/zsh/zshrc
+++ b/zsh/zshrc
@@ -1,14 +1,16 @@
# Emacs keybindings even if EDITOR is vi(1)
bindkey -e
+# If ENV is set, source it to get all the POSIX-compatible interactive stuff
+[[ -n $ENV ]] && source "$ENV"
+
# History settings
setopt histignorealldups sharehistory
HISTFILE=$HOME/.zsh_history
SAVEHIST=$((1 << 12))
-HISTSIZE=$((1 << 10))
-# Load POSIX shell startup files and then Bash-specific ones
-for sh in "$ENV" "$HOME"/.zshrc.d/*.zsh ; do
+# Load Zsh-specific startup files
+for sh in "$HOME"/.zshrc.d/*.zsh ; do
[[ -e $sh ]] && source "$sh"
done
unset -v sh