From e2468cb0f96864259bfd4518a72b2291054e325e Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Mon, 22 May 2017 11:02:12 +1200 Subject: Avoid awk(1) fork in pph(1df) --- bin/pph.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/pph.sh b/bin/pph.sh index 268b6ad7..ce516c16 100644 --- a/bin/pph.sh +++ b/bin/pph.sh @@ -1,4 +1,5 @@ # Run pp(1df) on args, prefix with machine hostname hn=$(hostname -s) || exit -pp "$@" | -awk -v hn="$hn" '{ print hn ":" $0 }' +pp "$@" | while IFS= read -r path ; do + printf '%s:%s\n' "$hn" "$path" +done -- cgit v1.2.3 From 45b5ac8b510400bcccbf893dee2229757533d7a7 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 23 May 2017 13:21:15 +1200 Subject: Fix up completions for td(1df) Hung on null completion --- bash/bash_completion.d/td.bash | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/bash/bash_completion.d/td.bash b/bash/bash_completion.d/td.bash index eb29992b..db232dd6 100644 --- a/bash/bash_completion.d/td.bash +++ b/bash/bash_completion.d/td.bash @@ -4,16 +4,23 @@ _td() { dir=${TODO_DIR:-"$HOME"/Todo} local fn while IFS= read -rd '' fn ; do + [[ -n $fn ]] || continue COMPREPLY[${#COMPREPLY[@]}]=$fn done < <( shopt -s extglob nullglob shopt -u dotglob - local -a fns + declare -a fns fns=("$dir"/"${COMP_WORDS[COMP_CWORD]}"*) fns=("${fns[@]#"$dir"/}") - ((${#fns[@]})) || exit 1 - printf '%s\0' "${fns[@]##"$dir"/}" + + # Print quoted entries, null-delimited, if there was at least one; + # otherwise, just print a null character to stop this hanging in Bash + # 4.4 + if ((${#fns[@]})) ; then + printf '%q\0' "${fns[@]}" + else + printf '\0' + fi ) - return } complete -F _td td -- cgit v1.2.3 From 6c4d2555443bd0dd62125fcb311a88b1db871548 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 23 May 2017 14:01:57 +1200 Subject: Restore functional copy-mode vi keys --- tmux/tmux.conf.m4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tmux/tmux.conf.m4 b/tmux/tmux.conf.m4 index ffac0243..3a1d2425 100644 --- a/tmux/tmux.conf.m4 +++ b/tmux/tmux.conf.m4 @@ -41,6 +41,8 @@ bind-key Tab last-pane # Use the vi mode for tmux interaction behaviour in copy and choice modes set-window-option -g mode-keys vi +bind-key -T copy-mode-vi v send -X begin-selection +bind-key -T copy-mode-vi y send -X copy-selection-and-cancel # Detach with Alt-M, no prefix required bind-key -n M-m detach -- cgit v1.2.3 From e37fe24c2505aba368fad31dea5c1c8e6df780cc Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 23 May 2017 21:42:12 +1200 Subject: Correct mftl.awk invocation --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 3afc6900..0f4c85be 100644 --- a/README.markdown +++ b/README.markdown @@ -54,7 +54,7 @@ to figure out which shell’s configuration files to install, falling back on `install-sh`. The remaining dotfiles can be installed with the other `install-*` targets. Try -`sh bin/mftl.sh Makefile` in the project's root directory to see a list. +`awk -f bin/mftl.awk Makefile` in the project's root directory to see a list. Tools ----- -- cgit v1.2.3 From 21654c68addf7b11d8e5918085c24001a170e8aa Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 23 May 2017 21:50:45 +1200 Subject: Explicitly mention ksh93 --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 0f4c85be..418e92fe 100644 --- a/README.markdown +++ b/README.markdown @@ -64,7 +64,7 @@ Configuration is included for: * Bourne-style POSIX shells, sharing a `.profile`, an `ENV` file, and some helper functions: * [GNU Bash](https://www.gnu.org/software/bash/) (2.05a or higher) - * [Korn shell](http://www.kornshell.com/) (including `pdksh`, `mksh`) + * [Korn shell](http://www.kornshell.com/) (`ksh93`, `pdksh`, `mksh`) * [Yash](https://yash.osdn.jp/index.html.en) * [Z shell](https://www.zsh.org/) * [Abook](http://abook.sourceforge.net/) -- curses address book program -- cgit v1.2.3 From 8547a2e1ea9135381e1538401ef4da60fb379d99 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 23 May 2017 21:53:10 +1200 Subject: Remove mysql() function Clumsy interaction too close to default behaviour anyway --- README.markdown | 3 --- sh/shrc.d/mysql.sh | 25 ------------------------- 2 files changed, 28 deletions(-) delete mode 100644 sh/shrc.d/mysql.sh diff --git a/README.markdown b/README.markdown index 418e92fe..8bfd8c51 100644 --- a/README.markdown +++ b/README.markdown @@ -220,8 +220,6 @@ in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include: available. * `la()` runs `ls -A` if it can, or `ls -a` otherwise. * `ll()` runs `ls -Al` if it can, or `ls -al` otherwise. -* `mysql()` allows shortcuts to MySQL configuration files stored in - `~/.mysql`. * `path()` manages the contents of `PATH` conveniently. * `scp()` tries to detect forgotten hostnames in `scp(1)` command calls. * `sudo()` forces `-H` for `sudo(8)` calls so that `$HOME` is never @@ -260,7 +258,6 @@ files, for things I really do get tired of typing repeatedly: * `gpg(1)` long options * `make(1)` targets read from a `Makefile` * `man(1)` page titles -* `mysql(1)` databases from `~/.mysql/*.cnf` * `pass(1)` entries * `ssh(1)` hostnames from `~/.ssh/config` diff --git a/sh/shrc.d/mysql.sh b/sh/shrc.d/mysql.sh deleted file mode 100644 index abb496d2..00000000 --- a/sh/shrc.d/mysql.sh +++ /dev/null @@ -1,25 +0,0 @@ -# If a file ~/.mysql/$1.cnf exists, call mysql(1) using that file, discarding -# the rest of the arguments. Otherwise just run MySQL with given args. Use -# restrictive permissions on these files. Doesn't allow filenames beginning -# with hyphens. -# -# Examples: -# -# [client] -# host=dbhost.example.com -# user=foo -# password=SsJ2pICe226jM -# -# [mysql] -# database=bar -# -mysql() { - case $1 in - -*) ;; - *) - [ -f "$HOME/.mysql/$1".cnf ] && - set -- --defaults-extra-file="$HOME/.mysql/$1".cnf - ;; - esac - command mysql "$@" -} -- cgit v1.2.3 From 38c80d1027afc4f06ec06a53047be5985f156bab Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 01:00:04 +1200 Subject: Update submodules --- vim/bundle/pathogen | 2 +- vim/bundle/unimpaired | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vim/bundle/pathogen b/vim/bundle/pathogen index 0f471006..379b8f70 160000 --- a/vim/bundle/pathogen +++ b/vim/bundle/pathogen @@ -1 +1 @@ -Subproject commit 0f4710063ecc98d77dc03698c4a917a3215bdf09 +Subproject commit 379b8f70822c4a89370575c3967f33cb116087ea diff --git a/vim/bundle/unimpaired b/vim/bundle/unimpaired index 0f72c70b..7bbbca73 160000 --- a/vim/bundle/unimpaired +++ b/vim/bundle/unimpaired @@ -1 +1 @@ -Subproject commit 0f72c70b672aeadaaab94e430267b1435c1b2441 +Subproject commit 7bbbca73233b1492a8c3d16f91f34340eccc9b30 -- cgit v1.2.3 From 5a659f01a45e4c2cd1dafbc910c823415798dcea Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 13:32:52 +1200 Subject: Remove Yash support I never use it --- Makefile | 20 ++------------------ README.markdown | 7 +------ check/login-shell.sh | 2 -- check/yash.sh | 5 ----- install/install-login-shell.sh | 2 -- ksh/shrc.d/ksh.sh | 2 +- lint/yash.sh | 1 - yash/yash_profile | 2 -- yash/yashrc | 14 -------------- yash/yashrc.d/ver.yash | 4 ---- 10 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 check/yash.sh delete mode 100644 lint/yash.sh delete mode 100644 yash/yash_profile delete mode 100644 yash/yashrc delete mode 100644 yash/yashrc.d/ver.yash diff --git a/Makefile b/Makefile index 999b90ac..e5cb262b 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,6 @@ install-vim-pathogen \ install-vim-plugins \ install-x \ - install-yash \ install-zsh \ check \ check-bash \ @@ -54,7 +53,6 @@ check-sh \ check-urxvt \ check-xinit \ - check-yash \ check-zsh \ lint \ lint-bash \ @@ -63,8 +61,7 @@ lint-ksh \ lint-sh \ lint-urxvt \ - lint-xinit \ - lint-yash + lint-xinit .SUFFIXES: .SUFFIXES: .awk .bash .pl .sed .sh @@ -446,12 +443,6 @@ install-x: check-xinit cp -p -- X/Xresources $(HOME)/.Xresources cp -p -- X/Xresources.d/* $(HOME)/.Xresources.d -install-yash: install-yash install-sh - mkdir -p -- $(HOME)/.yashrc.d - cp -p -- yash/yash_profile $(HOME)/.yash_profile - cp -p -- yash/yashrc $(HOME)/.yashrc - cp -p -- yash/yashrc.d/* $(HOME)/.yashrc.d - install-zsh: check-zsh install-sh mkdir -p -- $(HOME)/.profile.d $(HOME)/.zshrc.d cp -p -- zsh/profile.d/* $(HOME)/.profile.d @@ -491,9 +482,6 @@ check-urxvt: check-xinit: sh check/xinit.sh -check-yash: - sh check/yash.sh - check-zsh: sh check/zsh.sh @@ -503,8 +491,7 @@ lint: lint-bash \ lint-ksh \ lint-sh \ lint-urxvt \ - lint-xinit \ - lint-yash + lint-xinit lint-bash: check-bash sh lint/bash.sh @@ -526,6 +513,3 @@ lint-urxvt: check-urxvt lint-xinit: check-xinit sh lint/xinit.sh - -lint-yash: check-yash - sh lint/yash.sh diff --git a/README.markdown b/README.markdown index 8bfd8c51..06e585ef 100644 --- a/README.markdown +++ b/README.markdown @@ -65,7 +65,6 @@ Configuration is included for: some helper functions: * [GNU Bash](https://www.gnu.org/software/bash/) (2.05a or higher) * [Korn shell](http://www.kornshell.com/) (`ksh93`, `pdksh`, `mksh`) - * [Yash](https://yash.osdn.jp/index.html.en) * [Z shell](https://www.zsh.org/) * [Abook](http://abook.sourceforge.net/) -- curses address book program * [cURL](https://curl.haxx.se/) -- Command-line tool for transferring data @@ -239,7 +238,7 @@ non-POSIX features, as compatibility allows: * `vared()` allows interactively editing a variable with Readline, emulating a Zsh function I like by the same name (Bash). * `ver()` prints the current shell's version information (Bash, Korn Shell, - Yash, Z shell). + Z shell). #### Completion @@ -276,10 +275,6 @@ These are experimental; they are mostly used to tinker with MirBSD `mksh`, AT&T `ksh93`, and OpenBSD `pdksh`. All shells in this family default to a yellow prompt if detected. -#### Yash - -Just enough configuration to coax it into reading `~/.profile` and `~/.shrc`. - #### Zsh These are experimental; I do not like Zsh much at the moment. The files started diff --git a/check/login-shell.sh b/check/login-shell.sh index 20327b94..2972d98d 100644 --- a/check/login-shell.sh +++ b/check/login-shell.sh @@ -4,8 +4,6 @@ case ${SHELL##*/} in target=check-bash ;; ksh|ksh88|ksh93|mksh|pdksh) target=check-ksh ;; - yash) - target=check-yash ;; zsh) target=check-zsh ;; esac diff --git a/check/yash.sh b/check/yash.sh deleted file mode 100644 index c8722f3d..00000000 --- a/check/yash.sh +++ /dev/null @@ -1,5 +0,0 @@ -for yash in yash/* ; do - [ -f "$yash" ] || continue - yash -n "$yash" || exit -done -printf 'All yash scripts parsed successfully.\n' diff --git a/install/install-login-shell.sh b/install/install-login-shell.sh index b7292a77..f38aa0c1 100644 --- a/install/install-login-shell.sh +++ b/install/install-login-shell.sh @@ -4,8 +4,6 @@ case ${SHELL##*/} in target=install-bash ;; ksh|ksh88|ksh93|mksh|pdksh) target=install-ksh ;; - yash) - target=install-yash ;; zsh) target=install-zsh ;; esac diff --git a/ksh/shrc.d/ksh.sh b/ksh/shrc.d/ksh.sh index aa5c4cbc..b591f37c 100644 --- a/ksh/shrc.d/ksh.sh +++ b/ksh/shrc.d/ksh.sh @@ -9,7 +9,7 @@ # makes other shells throw tantrums. # Does the name of our shell have "ksh" in it at all? This is in no way -# guaranteed. It's just a heuristic that e.g. Bash and Yash shouldn't pass. +# guaranteed. It's just a heuristic that e.g. Bash shouldn't pass. case $0 in *ksh*) ;; *) return ;; diff --git a/lint/yash.sh b/lint/yash.sh deleted file mode 100644 index d783e077..00000000 --- a/lint/yash.sh +++ /dev/null @@ -1 +0,0 @@ -find yash -type f -print -exec shellcheck -e SC1090 -s sh -- {} + diff --git a/yash/yash_profile b/yash/yash_profile deleted file mode 100644 index d37f35a1..00000000 --- a/yash/yash_profile +++ /dev/null @@ -1,2 +0,0 @@ -# Load ~/.profile, because Yash won't by itself, no matter how you invoke it -[ -e "$HOME"/.profile ] && . "$HOME"/.profile diff --git a/yash/yashrc b/yash/yashrc deleted file mode 100644 index c2b2df26..00000000 --- a/yash/yashrc +++ /dev/null @@ -1,14 +0,0 @@ -# Clear away all aliases; we do this here rather than in $ENV because the ksh -# family of shells relies on aliases to implement certain POSIX utilities like -# fc(1) and type(1) -unalias -a - -# Load POSIX interactive shell startup files, because Yash won't do it if not -# invoked as sh(1) -[ -e "$ENV" ] && . "$ENV" - -# Load Bash-specific startup files -for sh in "$HOME"/.yashrc.d/*.yash ; do - [ -e "$sh" ] && . "$sh" -done -unset -v sh diff --git a/yash/yashrc.d/ver.yash b/yash/yashrc.d/ver.yash deleted file mode 100644 index 8bd06e4d..00000000 --- a/yash/yashrc.d/ver.yash +++ /dev/null @@ -1,4 +0,0 @@ -# Shortcut to show current shell version -ver() { - printf '%s\n' "${YASH_VERSION:-unknown}" -} -- cgit v1.2.3 From 7813bda9325299603d29fd2d1affafc29fc9e667 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 15:57:22 +1200 Subject: Correct title of pvi(1df) man page --- man/man1/pvi.1df | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man1/pvi.1df b/man/man1/pvi.1df index 990ea589..6a21e6e8 100644 --- a/man/man1/pvi.1df +++ b/man/man1/pvi.1df @@ -1,4 +1,4 @@ -.TH PED 1df "May 2017" "Manual page for pvi" +.TH PVI 1df "May 2017" "Manual page for pvi" .SH NAME .B pvi \- stop a pipe for $EDITOR intervention -- cgit v1.2.3 From 1c7cf90afae80918b82d823af59484f84391814f Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 15:57:34 +1200 Subject: Add dam(1df) --- .gitignore | 1 + Makefile | 1 + README.markdown | 1 + bin/dam.sh | 25 +++++++++++++++++++++++++ man/man1/dam.1df | 15 +++++++++++++++ 5 files changed, 43 insertions(+) create mode 100644 bin/dam.sh create mode 100644 man/man1/dam.1df diff --git a/.gitignore b/.gitignore index bafd0f1e..59f79713 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ bin/clog bin/clrd bin/clwr bin/csmw +bin/dam bin/d2u bin/ddup bin/dmp diff --git a/Makefile b/Makefile index e5cb262b..da41016b 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,7 @@ BINS = bin/ap \ bin/clrd \ bin/clwr \ bin/csmw \ + bin/dam \ bin/d2u \ bin/ddup \ bin/dmp \ diff --git a/README.markdown b/README.markdown index 06e585ef..1738af22 100644 --- a/README.markdown +++ b/README.markdown @@ -469,6 +469,7 @@ Installed by the `install-bin` target: line. * `csmw(1df)` prints an English list of monospace-quoted words read from the input. +* `dam(1df)` buffers all its input before emitting it as output. * `ddup(1df)` removes duplicate lines from unsorted input. * `dmp(1df)` copies a pass(1) entry selected by `dmenu(1)` to the X CLIPBOARD. diff --git a/bin/dam.sh b/bin/dam.sh new file mode 100644 index 00000000..03424515 --- /dev/null +++ b/bin/dam.sh @@ -0,0 +1,25 @@ +# Store up all input before emitting it unchanged as output +self=dam + +# Create a temporary directory with name in $td, and handle POSIX-ish traps to +# remove it when the script exits. +td= +cleanup() { + [ -n "$td" ] && rm -fr -- "$td" + if [ "$1" != EXIT ] ; then + trap - "$1" + kill "-$1" "$$" + fi +} +for sig in EXIT HUP INT TERM ; do + # shellcheck disable=SC2064 + trap "cleanup $sig" "$sig" +done +td=$(mktd "$self") || exit + +# We'll operate on stdin in the temp directory; write the script's stdin to it +# with cat(1) +cat -- "${@:-}" >"$td"/stdin + +# Only when that write is finished do we finally spit it all back out again +cat -- "$td"/stdin diff --git a/man/man1/dam.1df b/man/man1/dam.1df new file mode 100644 index 00000000..b9821960 --- /dev/null +++ b/man/man1/dam.1df @@ -0,0 +1,15 @@ +.TH DAM 1df "May 2017" "Manual page for dam" +.SH NAME +.B dam +\- read all input before emitting as output +.SH SYNOPSIS +prog1 | +.B +dam +| prog2 +.SH DESCRIPTION +.B dam +stores all its input in a temporary file before emitting it as output, behaving +like a fully-buffered cat(1), and with some of the functionality of sponge(1). +.SH AUTHOR +Tom Ryder -- cgit v1.2.3 From 49fc3b26cc4ddb419f0c6945a9faf4e307af0013 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 16:02:57 +1200 Subject: Add missing dash --- bin/dam.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/dam.sh b/bin/dam.sh index 03424515..a80cae4a 100644 --- a/bin/dam.sh +++ b/bin/dam.sh @@ -19,7 +19,7 @@ td=$(mktd "$self") || exit # We'll operate on stdin in the temp directory; write the script's stdin to it # with cat(1) -cat -- "${@:-}" >"$td"/stdin +cat -- "${@:--}" >"$td"/stdin # Only when that write is finished do we finally spit it all back out again cat -- "$td"/stdin -- cgit v1.2.3 From 6ff90f1b613fa01098d2ad7fe38a56444c4fa1a7 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 16:12:35 +1200 Subject: Change dam(1df) to a sed script --- bin/dam.sed | 8 ++++++++ bin/dam.sh | 25 ------------------------- man/man1/dam.1df | 5 +++-- 3 files changed, 11 insertions(+), 27 deletions(-) create mode 100644 bin/dam.sed delete mode 100644 bin/dam.sh diff --git a/bin/dam.sed b/bin/dam.sed new file mode 100644 index 00000000..86fb03f9 --- /dev/null +++ b/bin/dam.sed @@ -0,0 +1,8 @@ +# Store up all input before emitting it unchanged as output +1h +1!H +$ { + g + p +} +d diff --git a/bin/dam.sh b/bin/dam.sh deleted file mode 100644 index a80cae4a..00000000 --- a/bin/dam.sh +++ /dev/null @@ -1,25 +0,0 @@ -# Store up all input before emitting it unchanged as output -self=dam - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# We'll operate on stdin in the temp directory; write the script's stdin to it -# with cat(1) -cat -- "${@:--}" >"$td"/stdin - -# Only when that write is finished do we finally spit it all back out again -cat -- "$td"/stdin diff --git a/man/man1/dam.1df b/man/man1/dam.1df index b9821960..78f5210c 100644 --- a/man/man1/dam.1df +++ b/man/man1/dam.1df @@ -9,7 +9,8 @@ dam | prog2 .SH DESCRIPTION .B dam -stores all its input in a temporary file before emitting it as output, behaving -like a fully-buffered cat(1), and with some of the functionality of sponge(1). +buffers all its input before emitting it as output. Useful if you don't +actually want a line-by-line flow between programs, such as pasting a complete +document into a sed(1) pipeline on the terminal. .SH AUTHOR Tom Ryder -- cgit v1.2.3 From 3220403ff11e8d39ff5b0e8831de1d15969f51c2 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 16:55:13 +1200 Subject: Exit 2 with usage errors from gwp(1df) --- bin/gwp.awk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/gwp.awk b/bin/gwp.awk index 976b5b84..f1e3b3bd 100644 --- a/bin/gwp.awk +++ b/bin/gwp.awk @@ -24,7 +24,7 @@ BEGIN { # Bailout function function fail(str) { printf "%s: %s\n", self, str | "cat >&2" - exit(1) + exit(2) } # If there's more than one filename, precede the print of the current line with -- cgit v1.2.3 From cadc05f5acb0b495b93b15981a404077e0d2dee3 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 16:56:00 +1200 Subject: Add trs(1df) --- .gitignore | 1 + Makefile | 1 + README.markdown | 1 + bin/trs.awk | 36 ++++++++++++++++++++++++++++++++++++ man/man1/trs.1df | 23 +++++++++++++++++++++++ 5 files changed, 62 insertions(+) create mode 100644 bin/trs.awk create mode 100644 man/man1/trs.1df diff --git a/.gitignore b/.gitignore index 59f79713..e2f5a857 100644 --- a/.gitignore +++ b/.gitignore @@ -104,6 +104,7 @@ bin/tl bin/tlcs bin/tm bin/tot +bin/trs bin/try bin/u2d bin/umake diff --git a/Makefile b/Makefile index da41016b..1f620612 100644 --- a/Makefile +++ b/Makefile @@ -177,6 +177,7 @@ BINS = bin/ap \ bin/tlcs \ bin/tm \ bin/tot \ + bin/trs \ bin/try \ bin/u2d \ bin/umake \ diff --git a/README.markdown b/README.markdown index 1738af22..4cd8ebd0 100644 --- a/README.markdown +++ b/README.markdown @@ -532,6 +532,7 @@ Installed by the `install-bin` target: to use Taskwarrior, but found it too complex and buggy. * `tm(1df)` runs `tmux(1)` with `attach-session -d` if a session exists, and `new-session` if it doesn't. +* `trs(1df)` replaces strings (not regular expression) in its input. * `try(1df)` repeats a command up to a given number of times until it succeeds, only printing error output if all three attempts failed. Good for tolerating blips or temporary failures in `cron(8)` scripts. diff --git a/bin/trs.awk b/bin/trs.awk new file mode 100644 index 00000000..5966c520 --- /dev/null +++ b/bin/trs.awk @@ -0,0 +1,36 @@ +# Substitute one string for another in input (no regex) +BEGIN { + # Name self + self = "trs" + + # No wordsplitting required + FS = "" + + # Two and only two arguments required + if (ARGC != 3) + fail("Need a string and a replacement") + + # Get arguments and blank them so awk doesn't try to read them as files + str = ARGV[1] + rep = ARGV[2] + ARGV[1] = ARGV[2] = "" + + # String length is relevant here + if (!(len = length(str))) + fail("String to replace cannot be null") +} + +# Bailout function +function fail(str) { + printf "%s: %s\n", self, str | "cat >&2" + exit(2) +} + +# Run on each line +{ + lin = "" + for (buf = $0; ind = index(buf, str); buf = substr(buf, ind + len)) + lin = lin substr(buf, 1, ind - 1) rep + lin = lin buf + print lin +} diff --git a/man/man1/trs.1df b/man/man1/trs.1df new file mode 100644 index 00000000..fa5d2d19 --- /dev/null +++ b/man/man1/trs.1df @@ -0,0 +1,23 @@ +.TH TRS 1df "May 2017" "Manual page for trs" +.SH NAME +.B trs +\- string version of tr(1) +.SH SYNOPSIS +.B trs +STRING REPLACEMENT +< file +.br +program | +.B trs +STRING REPLACEMENT +.SH DESCRIPTION +.B trs +replaces the string given in its first argument with the string given in its +second, with no regex metacharacters, in a way that should work on all POSIX +implementations. It is thereby the string complement for tr(1). +.P +The first argument cannot be a null string. The second argument can be blank +(but must still be specified) to implicitly delete all occurrences of the +string. +.SH AUTHOR +Tom Ryder -- cgit v1.2.3 From 4b780b8415db74508729991e5a2014bc7a54ff17 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 24 May 2017 22:06:49 +1200 Subject: Correct gt() error output --- sh/shrc.d/gt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sh/shrc.d/gt.sh b/sh/shrc.d/gt.sh index d18a4ab8..c90af073 100644 --- a/sh/shrc.d/gt.sh +++ b/sh/shrc.d/gt.sh @@ -4,7 +4,7 @@ gt() { # Check argument count if [ "$#" -gt 1 ] ; then - printf >&2 'gd(): Too many arguments\n' + printf >&2 'gt(): Too many arguments\n' return 2 fi -- cgit v1.2.3 From 3f9a35e5babdc63d32408851296d235fa632834b Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Thu, 25 May 2017 01:00:04 +1200 Subject: Update submodules --- vim/bundle/pathogen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vim/bundle/pathogen b/vim/bundle/pathogen index 379b8f70..3ec671e1 160000 --- a/vim/bundle/pathogen +++ b/vim/bundle/pathogen @@ -1 +1 @@ -Subproject commit 379b8f70822c4a89370575c3967f33cb116087ea +Subproject commit 3ec671e112c760e68eee1e3cc5eeb9408448dab4 -- cgit v1.2.3 From b4b144c3f8aa98a26b9a59c204ec0d5b4619ef72 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Thu, 25 May 2017 18:21:23 +1200 Subject: Shorter/saner implementation for bd() Avoids subshell mess and consequent trailing-space workaround --- sh/shrc.d/bd.sh | 85 ++++++++++++++++++++------------------------------------- 1 file changed, 29 insertions(+), 56 deletions(-) diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index bf64a9aa..02da6773 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -3,68 +3,41 @@ bd() { # Check argument count if [ "$#" -gt 1 ] ; then - printf >&2 'bd(): Too many arguments' + printf >&2 'bd(): Too many arguments\n' return 2 fi - # Set positional parameters to an option terminator and what will hopefully - # end up being a target directory - set -- "$( + # Look at argument given + case $1 in - # The requested pattern is the first argument, defaulting to just the - # parent directory - req=${1:-..} + # If it has a leading slash or is . or .., don't touch the arguments + /*|.|..) ;; - # Strip trailing slashes if a trailing slash is not the whole pattern - [ "$req" = / ] || req=${req%/} + # Otherwise, we'll try to find a matching ancestor and then shift the + # initial request off the argument list + *) - # What to do now depends on the request - case $req in + # Push the current directory onto the stack + set -- "$1" "$PWD" - # Just go straight to the root or dot directories if asked - (/|.|..) - dirname=$req - ;; - - # Anything with a leading / needs to anchor to the start of the - # path. A strange request though. Why not just use cd? - (/*) - dirname=$req - case $PWD in - ("$dirname"/*) ;; - (*) dirname='' ;; + # Keep chopping at the current directory until it's empty or it + # matches the request + while [ -n "$2" ] ; do + set -- "$1" "${2%/*}" + case $2 in + (*/"$1") break ;; esac - ;; - - # In all other cases, iterate through the PWD to find a match, or - # whittle the target down to an empty string trying - (*) - dirname=$PWD - while [ -n "$dirname" ] ; do - dirname=${dirname%/*} - case $dirname in - (*/"$req") break ;; - esac - done - ;; - esac - - # Check we have a target after all that - if [ -z "$dirname" ] ; then - printf >&2 'bd(): Directory name not in path\n' - exit 1 - fi - - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${dirname%/}" - )" - - # Remove trailing slash - set -- "${1%/}" - - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return - - # Try to change into the determined directory - command cd -- "$@" + done + + # If the first argument ended up empty, we have no match + if [ -z "$2" ] ; then + printf >&2 'bd(): No match\n' + return 1 + fi + shift + ;; + esac + + # We have a match; try and change into it + command cd -- "$1" } -- cgit v1.2.3 From e199448d724746af892a67608c88fb2ddc075c72 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Thu, 25 May 2017 18:31:36 +1200 Subject: Even terser/nicer bd() --- sh/shrc.d/bd.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index 02da6773..5b2c3d59 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -22,18 +22,18 @@ bd() { # Keep chopping at the current directory until it's empty or it # matches the request - while [ -n "$2" ] ; do - set -- "$1" "${2%/*}" + while set -- "$1" "${2%/*}" ; do case $2 in - (*/"$1") break ;; + */"$1") break ;; + */*) ;; + *) + printf >&2 'bd(): No match\n' + return 1 + ;; esac done # If the first argument ended up empty, we have no match - if [ -z "$2" ] ; then - printf >&2 'bd(): No match\n' - return 1 - fi shift ;; esac -- cgit v1.2.3 From 9ed69d70d9201817c7f36c7f210ce163e84eb54b Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 00:39:02 +1200 Subject: Reimplement sd() without subshell --- sh/shrc.d/bd.sh | 6 ++--- sh/shrc.d/sd.sh | 80 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index 5b2c3d59..2dc21173 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -7,8 +7,8 @@ bd() { return 2 fi - # Look at argument given - case $1 in + # Look at argument given; default to going up one level + case ${1:-..} in # If it has a leading slash or is . or .., don't touch the arguments /*|.|..) ;; @@ -18,7 +18,7 @@ bd() { *) # Push the current directory onto the stack - set -- "$1" "$PWD" + set -- "${1%/}" "$PWD" # Keep chopping at the current directory until it's empty or it # matches the request diff --git a/sh/shrc.d/sd.sh b/sh/shrc.d/sd.sh index 4d63b7d6..561a77f4 100644 --- a/sh/shrc.d/sd.sh +++ b/sh/shrc.d/sd.sh @@ -40,48 +40,50 @@ sd() { return 2 fi - # Change positional parameters to what will hopefully be a completed - # substitution - set -- "$( + # Read sole optional argument + case $1 in - # Set the positional parameters to either the requested directory, or - # all siblings of the current directory if no request - spec=$1 - set -- - if [ -n "$spec" ] ; then - set -- "$@" ../"$spec" - else - for sib in ../.* ../* ; do - case ${sib#../} in - (.|..|"${PWD##*/}") continue ;; - esac - set -- "$@" "$sib" - done - fi + # If blank, get a full list of directories at this level; include + # dotfiles, but not the . and .. entries, using glob tricks to avoid + # Bash ruining things with `dotglob` + '') + set -- ../[!.]*/ + [ -e "$1" ] || shift + set -- ../.[!.]*/ "$@" + [ -e "$1" ] || shift + set -- ../..?*/ "$@" + [ -e "$1" ] || shift + ;; - # We should have exactly one sibling - case $# in - (1) ;; - (0) - printf >&2 'sd(): No siblings\n' - exit 1 - ;; - (*) - printf >&2 'sd(): More than one sibling\n' - exit 1 - ;; - esac + # If not, get that directory, and the current one; shift it off if it + # doesn't exist + *) + set -- ../"${1%/}"/ ../"${PWD##*/}"/ + [ -e "$1" ] || shift + ;; + esac - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${1%/}" - )" + # We should now have two parameters: the current directory and the matched + # sibling + case $# in + 2) ;; + 0|1) + printf >&2 'sd(): No match\n' + return 1 + ;; + *) + printf >&2 'sd(): Multiple matches\n' + return 1 + ;; + esac - # Remove trailing slash - set -- "${1%/}" + # Find which of these two is not the current directory and set that as our + # sole parameter + case $1 in + ../"${PWD##*/}"/) set -- "$2" ;; + *) set -- "$1" ;; + esac - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return - - # Try to change into the determined directory - command cd -- "$@" + # Try and change into the first parameter + command cd -- "$1" } -- cgit v1.2.3 From cd114eec94fd07e831ef6c70b7732408d0a59e90 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 17:48:49 +1200 Subject: Correct default behaviour for bd() with no args --- sh/shrc.d/bd.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index 2dc21173..7901e115 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -1,14 +1,17 @@ # Move back up the directory tree to the first directory matching the name bd() { - # Check argument count - if [ "$#" -gt 1 ] ; then - printf >&2 'bd(): Too many arguments\n' - return 2 - fi + # Check argument count; default to ".." + case $# in + 0) set -- .. ;; + 1) ;; + *) + printf >&2 'bd(): Too many arguments\n' + return 2 + esac # Look at argument given; default to going up one level - case ${1:-..} in + case $1 in # If it has a leading slash or is . or .., don't touch the arguments /*|.|..) ;; -- cgit v1.2.3 From 520f9e174aa0569a95469a7d2b746582bdf0c18c Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:23:54 +1200 Subject: More bd() improvements Including rigorous trailing-slash handling --- sh/shrc.d/bd.sh | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index 7901e115..9b877faf 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -1,31 +1,48 @@ # Move back up the directory tree to the first directory matching the name bd() { - # Check argument count; default to ".." - case $# in - 0) set -- .. ;; - 1) ;; - *) - printf >&2 'bd(): Too many arguments\n' - return 2 - esac + # Check arguments; default to ".." + if [ "$#" -gt 1 ] ; then + printf >&2 'bd(): Too many arguments\n' + return 2 + fi + set -- "${1:-..}" # Look at argument given; default to going up one level case $1 in - # If it has a leading slash or is . or .., don't touch the arguments - /*|.|..) ;; + # If it's slash, dot, or dot-dot, we'll just go there, like `cd` would + /|.|..) ;; + + # Anything else with a slash anywhere is an error + */*) + printf >&2 'bd(): Illegal slash\n' + return 2 + ;; # Otherwise, we'll try to find a matching ancestor and then shift the # initial request off the argument list *) # Push the current directory onto the stack - set -- "${1%/}" "$PWD" + set -- "$1" "$PWD" # Keep chopping at the current directory until it's empty or it # matches the request - while set -- "$1" "${2%/*}" ; do + while : ; do + + # Make certain there are no trailing slashes to foul us up + while : ; do + case $2 in + */) set -- "$1" "${2%/}" ;; + *) break ;; + esac + done + + # Strip a path element + set -- "$1" "${2%/*}" + + # Check whether we're arrived case $2 in */"$1") break ;; */*) ;; -- cgit v1.2.3 From 2d0fefe4cde7831c7e49641df217ee0354751a63 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:24:13 +1200 Subject: Reimplement ud() More fault-tolerant and no subshell or temporary vars --- sh/shrc.d/ud.sh | 62 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/sh/shrc.d/ud.sh b/sh/shrc.d/ud.sh index 79f4b5e7..a3997702 100644 --- a/sh/shrc.d/ud.sh +++ b/sh/shrc.d/ud.sh @@ -2,48 +2,46 @@ # like cd .., cd ../.., etc ud() { - # Check argument count - if [ "$#" -gt 1 ] ; then + # Check arguments; default to 1 and $PWD + if [ "$#" -gt 2 ] ; then printf >&2 'ud(): Too many arguments\n' return 2 fi + set -- "${1:-1}" "${2:-"$PWD"}" + set -- "$1" "$2" - # Check first argument, number of steps upward, default to 1. - # "0" is weird, but valid; "-1" however makes no sense at all - if [ "${1:-1}" -lt 0 ] ; then + # Check first argument, number of steps upward. "0" is weird, but valid; + # "-1" however makes no sense at all + if [ "$1" -lt 0 ] ; then printf >&2 'ud(): Invalid step count\n' return 2 fi - # Change the positional parameters from the number of steps given to a - # "../../.." string - set -- "$( - - # Append /.. to the target (default PWD) the specified number of times - dirname=${2:-"$PWD"} - i=0 - steps=${1:-1} - while [ "$i" -lt "$steps" ] ; do - dirname=${dirname%/}/.. - i=$((i+1)) + # Check second argument, starting path, for relativity and anchor it if + # need be + case $2 in + /*) ;; + *) set -- "$1" "$PWD"/"$2" ;; + esac + + # Chop an element off the target the specified number of times + while [ "$1" -gt 0 ] ; do + + # Make certain there are no trailing slashes to foul us up + while : ; do + case $2 in + */) set -- "$1" "${2%/}" ;; + *) break ;; + esac done - # Check we have a target after all that - if [ -z "$dirname" ] ; then - printf >&2 'ud(): Destination construction failed\n' - exit 1 - fi + # Strip a path element + set -- "$(($1-1))" "${2%/*}" + done - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${dirname%/}" - )" + # Shift off the count, which should now be zero + shift - # Remove trailing slash - set -- "${1%/}" - - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return - - # Try to change into the determined directory - command cd -- "$@" + # Try to change into the determined directory, or the root if blank + command cd -- "${1:-/}" } -- cgit v1.2.3 From 62f7ea87871b861a079a64ef0e278370865498e4 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:34:16 +1200 Subject: Still tinkering with ?d.sh scripts --- sh/shrc.d/pd.sh | 49 ++++++++++++++++++++----------------------------- sh/shrc.d/rd.sh | 2 -- sh/shrc.d/sd.sh | 2 -- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/sh/shrc.d/pd.sh b/sh/shrc.d/pd.sh index ce43837b..e3a6daaa 100644 --- a/sh/shrc.d/pd.sh +++ b/sh/shrc.d/pd.sh @@ -2,39 +2,30 @@ # use when you've got a file path in a variable, or in history, or in Alt+., # and want to quickly move to its containing directory. In the absence of an # argument, this just shifts up a directory, i.e. `cd ..` +# +# Note this is equivalent to `ud 1`. pd() { - # Check argument count + # Check arguments; default to $PWD if [ "$#" -gt 1 ] ; then printf >&2 'pd(): Too many arguments\n' return 2 fi - - # Change the positional parameters from the target to its containing - # directory - set -- "$( - - # Figure out target dirname - dirname=${1:-..} - dirname=${dirname%/} - dirname=${dirname%/*} - - # Check we have a target after that - if [ -z "$dirname" ] ; then - printf >&2 'ud(): Destination construction failed\n' - exit 1 - fi - - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${dirname%/}" - )" - - # Remove trailing slash - set -- "${1%/}" - - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return - - # Try to change into the determined directory - command cd -- "$@" + set -- "${1:-"$PWD"}" + + # Make certain there are no trailing slashes to foul us up, and anchor path + # if relative + while : ; do + case $1 in + */) set -- "${1%/}" ;; + /*) break ;; + *) set -- "$PWD"/"$1" ;; + esac + done + + # Strip a path element + set -- "${1%/*}" + + # Try to change into the determined directory, or root if empty + command cd -- "${1:-/}" } diff --git a/sh/shrc.d/rd.sh b/sh/shrc.d/rd.sh index 3b699c0d..c4c1c063 100644 --- a/sh/shrc.d/rd.sh +++ b/sh/shrc.d/rd.sh @@ -1,4 +1,3 @@ -# # Replace the first instance of the first argument string with the second # argument string in $PWD, and make that the target of the cd builtin. This is # to emulate a feature of the `cd` builtin in Zsh that I like, but that I think @@ -12,7 +11,6 @@ # $ rd usr opt # $ pwd # /opt/bin -# rd() { # Check argument count diff --git a/sh/shrc.d/sd.sh b/sh/shrc.d/sd.sh index 561a77f4..af82b67e 100644 --- a/sh/shrc.d/sd.sh +++ b/sh/shrc.d/sd.sh @@ -1,4 +1,3 @@ -# # Shortcut to switch to another directory with the same parent, i.e. a sibling # of the current directory. # @@ -31,7 +30,6 @@ # /tmp/tmp.ZSunna5Eup/a # # Seems to work for symbolic links. -# sd() { # Check argument count -- cgit v1.2.3 From 5fe1ba3c7cbf48f65b5287de6cd36112c16ab4a6 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:35:58 +1200 Subject: Remove solved issue This was fixed in 6c4d255 --- ISSUES.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/ISSUES.markdown b/ISSUES.markdown index 4116adda..a69e07df 100644 --- a/ISSUES.markdown +++ b/ISSUES.markdown @@ -23,4 +23,3 @@ Known issues my own stuff in there * Completion for custom functions e.g. `sd` should ideally respect `completion-ignore-case` setting -* Copy-mode configuration for tmux needs to be reinstated. -- cgit v1.2.3 From f1bff51c5bc41ace7ddfd35bef76a7e09066aa8d Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:37:15 +1200 Subject: Add an issue --- ISSUES.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ISSUES.markdown b/ISSUES.markdown index a69e07df..83358762 100644 --- a/ISSUES.markdown +++ b/ISSUES.markdown @@ -23,3 +23,5 @@ Known issues my own stuff in there * Completion for custom functions e.g. `sd` should ideally respect `completion-ignore-case` setting +* Would be good to remove the remaining subshell expansions in sh/shrc.d if + possible, have already removed them from bd/pd/sd/ud() -- cgit v1.2.3 From 330374feeeca822525beff73354162a3dc33b3a0 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:38:25 +1200 Subject: Remove an implemented idea This was done in fd70519 --- IDEAS.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/IDEAS.markdown b/IDEAS.markdown index 67283ce2..f73e94b6 100644 --- a/IDEAS.markdown +++ b/IDEAS.markdown @@ -8,7 +8,6 @@ Ideas * Have eds(1df) accept stdin with the "starting content" for the script * Convert all the manual pages to mandoc maybe? * edio(1df), like vipe(1) -* Detect appropriate shell family to install in Makefile * qmp(1df)--quick man page * ad() could be more intelligent; if there's only one directory that matches the *whole pattern*, we can assume it's safe to use that one, rather than -- cgit v1.2.3 From 5fe86cf87d93d4f768e5bf7404cdfbc3908d9023 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:39:40 +1200 Subject: Remove implemented idea This was implemented in 13a4187 --- IDEAS.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/IDEAS.markdown b/IDEAS.markdown index f73e94b6..083df51b 100644 --- a/IDEAS.markdown +++ b/IDEAS.markdown @@ -7,7 +7,6 @@ Ideas manageable * Have eds(1df) accept stdin with the "starting content" for the script * Convert all the manual pages to mandoc maybe? -* edio(1df), like vipe(1) * qmp(1df)--quick man page * ad() could be more intelligent; if there's only one directory that matches the *whole pattern*, we can assume it's safe to use that one, rather than -- cgit v1.2.3 From 361f31b086ebe67a0d9e1733c579c6b8498b0c99 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:40:34 +1200 Subject: Correct comment spelling error --- bash/bash_completion.d/sd.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bash/bash_completion.d/sd.bash b/bash/bash_completion.d/sd.bash index aeee1615..aeb76fa0 100644 --- a/bash/bash_completion.d/sd.bash +++ b/bash/bash_completion.d/sd.bash @@ -7,7 +7,7 @@ _sd() { # Current directory can't be root directory [[ $PWD != / ]] || return 1 - # Build list of matching sibiling directories + # Build list of matching sibling directories local dirname while IFS= read -rd '' dirname ; do [[ -n $dirname ]] || continue -- cgit v1.2.3 From df7182774a97fd330f0ce6358ae4c2454b121f9e Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:45:23 +1200 Subject: Remove hare-brained no-op line --- sh/shrc.d/ud.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/sh/shrc.d/ud.sh b/sh/shrc.d/ud.sh index a3997702..06234569 100644 --- a/sh/shrc.d/ud.sh +++ b/sh/shrc.d/ud.sh @@ -8,7 +8,6 @@ ud() { return 2 fi set -- "${1:-1}" "${2:-"$PWD"}" - set -- "$1" "$2" # Check first argument, number of steps upward. "0" is weird, but valid; # "-1" however makes no sense at all -- cgit v1.2.3 From 0eca7eafffbd667b7e5f4d2423adb54ea5582165 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:45:37 +1200 Subject: Tidy/golf gt() down a bit --- sh/shrc.d/gt.sh | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/sh/shrc.d/gt.sh b/sh/shrc.d/gt.sh index c90af073..95ab4c2f 100644 --- a/sh/shrc.d/gt.sh +++ b/sh/shrc.d/gt.sh @@ -3,26 +3,24 @@ gt() { # Check argument count - if [ "$#" -gt 1 ] ; then - printf >&2 'gt(): Too many arguments\n' + if [ "$#" -ne 1 ] ; then + printf >&2 'gt(): Need one argument\n' return 2 fi - # Strip trailing slash - set -- "${1%/}" - - # If target doesn't have a leading slash, add PWD prefix - case $1 in - /*) ;; - *) set -- "${PWD%/}"/"$1" - esac + # Make certain there are no trailing slashes to foul us up, and anchor path + # if relative + while : ; do + case $1 in + */) set -- "${1%/}" ;; + /*) break ;; + *) set -- "$PWD"/"$1" ;; + esac + done # If target isn't a directory, chop to its parent [ -d "$1" ] || set -- "${1%/*}" - # If target is now empty, go to the root - [ -n "$1" ] || set -- / - - # Try to change into the determined directory - command cd -- "$@" + # Try to change into the determined directory, or root if empty + command cd -- "${1:-/}" } -- cgit v1.2.3 From 1bca0a6205c0c22bc0e23c642f47da18d5164766 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:46:48 +1200 Subject: Remove ad() It has no real advantages over and isn't as clever as just cd /a*/b*/c* --- IDEAS.markdown | 3 -- README.markdown | 2 -- bash/bash_completion.d/ad.bash | 2 -- sh/shrc.d/ad.sh | 80 ------------------------------------------ 4 files changed, 87 deletions(-) delete mode 100644 bash/bash_completion.d/ad.bash delete mode 100644 sh/shrc.d/ad.sh diff --git a/IDEAS.markdown b/IDEAS.markdown index 083df51b..4cac76f7 100644 --- a/IDEAS.markdown +++ b/IDEAS.markdown @@ -8,8 +8,5 @@ Ideas * Have eds(1df) accept stdin with the "starting content" for the script * Convert all the manual pages to mandoc maybe? * qmp(1df)--quick man page -* ad() could be more intelligent; if there's only one directory that matches - the *whole pattern*, we can assume it's safe to use that one, rather than - stopping each time any node has more than one match * The solution to chn(1df) not running in parallel is probably backgrounded processes and mkfifo(1). diff --git a/README.markdown b/README.markdown index 4cd8ebd0..9d16abe5 100644 --- a/README.markdown +++ b/README.markdown @@ -189,8 +189,6 @@ in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include: * `pmd()` prints the marked directory. * `xd()` swaps the current and marked directories. * Ten other directory management and navigation functions: - * `ad()` is a `cd` shortcut accepting targets like `/u/l/b` for - `/usr/local/bin`, as long as they are unique. * `bd()` changes into a named ancestor of the current directory. * `gt()` changes into a directory or into a file's directory. * `lgt()` runs `gt()` on the first result from a `loc(1df)` search. diff --git a/bash/bash_completion.d/ad.bash b/bash/bash_completion.d/ad.bash deleted file mode 100644 index 390fcb00..00000000 --- a/bash/bash_completion.d/ad.bash +++ /dev/null @@ -1,2 +0,0 @@ -# Completion function for ad(); just directories -complete -A directory ad diff --git a/sh/shrc.d/ad.sh b/sh/shrc.d/ad.sh deleted file mode 100644 index 55866683..00000000 --- a/sh/shrc.d/ad.sh +++ /dev/null @@ -1,80 +0,0 @@ -# Find an abbreviated path -ad() { - - # Check argument count - if [ "$#" -ne 1 ] ; then - printf >&2 'ad(): Need just one argument\n' - return 2 - fi - - # Change the positional parameters from the abbreviated request - # to any matched directory - set -- "$( - - # Clean up and anchor the request - req=${1%/}/ - case $req in - (/*) ;; - (*) req=${PWD%/}/${req#/} ;; - esac - - # Start building the target directory; go through the request piece by - # piece until it is used up - dir= - while [ -n "$req" ] ; do - - # Chop the next front bit off the request and add it to the dir - dir=${dir%/}/${req%%/*} - req=${req#*/} - - # If that exists, all is well and we can keep iterating - [ -d "$dir" ] && continue - - # Set the positional parameters to a glob expansion of the - # abbreviated directory given - set -- "$dir"* - - # Iterate through the positional parameters filtering out - # directories; we need to run right through the whole list to check - # that we have at most one match - entd= - for ent ; do - [ -d "$ent" ] || continue - - # If we already found a match and have found another one, bail - # out - if [ -n "$entd" ] ; then - printf >&2 'ad(): More than one matching dir for %s*:\n' \ - "$dir" - printf >&2 '%s\n' "$@" - exit 1 - fi - - # Otherwise, this can be our first one - entd=$ent - done - - # If we found no match, bail out - if [ -z "$entd" ] ; then - printf >&2 'ad(): No matching dirs: %s*\n' "$dir" - exit 1 - fi - - # All is well, tack on what we have found and keep going - dir=$entd - - done - - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${dir%/}" - )" - - # Remove trailing slash - set -- "${1%/}" - - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return - - # Try to change into the determined directory - command cd -- "$@" -} -- cgit v1.2.3 From a9784dda9f9707342bed9fed1c07ed2336c73e0e Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 26 May 2017 20:55:55 +1200 Subject: Make a caveat of swr(1df) clearer --- bin/swr.sh | 2 +- man/man1/swr.1df | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/swr.sh b/bin/swr.sh index 47c84b86..5bad63ae 100644 --- a/bin/swr.sh +++ b/bin/swr.sh @@ -1,4 +1,4 @@ -# Transparently wrap scp(1) targets on the command line +# Transparently wrap scp(1) targets to read (not write) on the command line self=swr # Create a temporary directory with name in $td, and handle POSIX-ish traps to diff --git a/man/man1/swr.1df b/man/man1/swr.1df index 8792b0ed..4c40a6f0 100644 --- a/man/man1/swr.1df +++ b/man/man1/swr.1df @@ -1,7 +1,7 @@ .TH SWR 1df "January 2017" "Manual page for swr" .SH NAME .B swr -\- run a command including remote file arguments for scp(1) retrieval +\- run a command including remote file arguments for scp(1) reading .SH SYNOPSIS .B swr cat remote:.ssh/authorized_keys @@ -18,6 +18,9 @@ circumstances. This even works for the first argument (i.e. the command), provided that it will run on the local system once copied in. .SH CAVEATS +You can't write to remote files with it. The arguments only work as input +streams, so e.g. "cp .vimrc remote:.vimrc" won't do what you expect. +.P This only works for simple commands; you can't put shell syntax into any of the arguments. .P -- cgit v1.2.3 From 8571498f0f8c27b35a2ed813ace1b0c04e2c1dfd Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 20:01:34 +1200 Subject: Add history filename squashing to rlwrap(1) calls --- bin/clog.sh | 2 +- bin/osc.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/clog.sh b/bin/clog.sh index b17ff1c5..b62d4f94 100644 --- a/bin/clog.sh +++ b/bin/clog.sh @@ -7,7 +7,7 @@ set -- # If we have rlwrap, quietly use it command -v rlwrap >/dev/null 2>&1 && - set -- rlwrap -C "$self" "$@" + set -- rlwrap --history-filename=/dev/null -C "$self" "$@" # Write the date, the standard input (rlwrapped if applicable), and two dashes # to $CLOG, defaulting to ~/.clog. diff --git a/bin/osc.sh b/bin/osc.sh index ba35d9b7..b145b5cd 100644 --- a/bin/osc.sh +++ b/bin/osc.sh @@ -17,7 +17,7 @@ serv=${2:-https} set -- ## If we have rlwrap, use it, but don't complain if we don't if command -v rlwrap >/dev/null 2>&1 ; then - set -- "$@" rlwrap + set -- "$@" rlwrap --history-filename=/dev/null fi ## The actual openssl(1ssl) and subcommand call set -- "$@" openssl s_client -- cgit v1.2.3 From 1a672fccf7d8c9b41e02d86c1f7f39a5d025aaf6 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 21:17:34 +1200 Subject: More refinements to bd() --- sh/shrc.d/bd.sh | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index 9b877faf..1b253e3d 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -20,44 +20,27 @@ bd() { return 2 ;; - # Otherwise, we'll try to find a matching ancestor and then shift the - # initial request off the argument list + # Otherwise, add and keep chopping at the current directory until it's + # empty or it matches the request, then shift the request off *) - - # Push the current directory onto the stack set -- "$1" "$PWD" - - # Keep chopping at the current directory until it's empty or it - # matches the request while : ; do - - # Make certain there are no trailing slashes to foul us up - while : ; do - case $2 in - */) set -- "$1" "${2%/}" ;; - *) break ;; - esac - done - - # Strip a path element - set -- "$1" "${2%/*}" - - # Check whether we're arrived case $2 in - */"$1") break ;; - */*) ;; - *) - printf >&2 'bd(): No match\n' - return 1 - ;; + */"$1"|'') break ;; + */) set -- "$1" "${2%/}" ;; + *) set -- "$1" "${2%/*}" ;; esac done - - # If the first argument ended up empty, we have no match shift ;; esac + # If we have nothing to change into, there's an error + if [ -z "$1" ] ; then + printf >&2 'bd(): No match\n' + return 1 + fi + # We have a match; try and change into it command cd -- "$1" } -- cgit v1.2.3 From 05eac418f012b9d92f1955cab3d19a5cb9aef760 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 21:24:17 +1200 Subject: Add safety to bd() Handle case if PWD does not start with a slash--a big "Shouldn't Happen", but easy enough to be worth handling, since it would loop infinitely otherwise --- sh/shrc.d/bd.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sh/shrc.d/bd.sh b/sh/shrc.d/bd.sh index 1b253e3d..29bde513 100644 --- a/sh/shrc.d/bd.sh +++ b/sh/shrc.d/bd.sh @@ -28,7 +28,8 @@ bd() { case $2 in */"$1"|'') break ;; */) set -- "$1" "${2%/}" ;; - *) set -- "$1" "${2%/*}" ;; + */*) set -- "$1" "${2%/*}" ;; + *) set -- "$1" '' ;; esac done shift -- cgit v1.2.3 From 5db5287e727a2c73278bd33b9728a3cef1a741eb Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 21:33:02 +1200 Subject: Use -z rather than !-n --- sh/shrc.d/gd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sh/shrc.d/gd.sh b/sh/shrc.d/gd.sh index fa5776f2..9f6a43e7 100644 --- a/sh/shrc.d/gd.sh +++ b/sh/shrc.d/gd.sh @@ -8,7 +8,7 @@ gd() { fi # Complain if mark not actually set yet - if ! [ -n "$PMD" ] ; then + if [ -z "$PMD" ] ; then printf >&2 'gd(): Mark not set\n' return 1 fi -- cgit v1.2.3 From 1302b279bf2b1b2ae76ea8251a32e480d64f2f7a Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 21:33:09 +1200 Subject: Remove redundant `|| return` from gd() It will do that implicitly anyway --- sh/shrc.d/gd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sh/shrc.d/gd.sh b/sh/shrc.d/gd.sh index 9f6a43e7..10135d01 100644 --- a/sh/shrc.d/gd.sh +++ b/sh/shrc.d/gd.sh @@ -14,5 +14,5 @@ gd() { fi # Go to the marked directory - cd -- "$PMD" || return + cd -- "$PMD" } -- cgit v1.2.3 From cbbec36d4403dbed6d61232e86b5d4995c8da1fe Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 22:52:40 +1200 Subject: More error-resistant sd() --- sh/shrc.d/hgrep.sh | 6 ++-- sh/shrc.d/pmd.sh | 2 +- sh/shrc.d/sd.sh | 86 ++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 62 insertions(+), 32 deletions(-) diff --git a/sh/shrc.d/hgrep.sh b/sh/shrc.d/hgrep.sh index 1c4c3ec5..fe297ab3 100644 --- a/sh/shrc.d/hgrep.sh +++ b/sh/shrc.d/hgrep.sh @@ -6,11 +6,11 @@ hgrep() { if [ "$#" -eq 0 ] ; then printf >&2 'hgrep(): Need a pattern\n' - exit 2 + return 2 fi - if ! [ -n "$HISTFILE" ] ; then + if [ -z "$HISTFILE" ] ; then printf >&2 'hgrep(): No HISTFILE\n' - exit 2 + return 2 fi grep "$@" "$HISTFILE" } diff --git a/sh/shrc.d/pmd.sh b/sh/shrc.d/pmd.sh index c96a50bd..4b0cd5bd 100644 --- a/sh/shrc.d/pmd.sh +++ b/sh/shrc.d/pmd.sh @@ -1,6 +1,6 @@ # Print the marked directory pmd() { - if ! [ -n "$PMD" ] ; then + if [ -z "$PMD" ] ; then printf >&2 'pmd(): Mark not set\n' return 1 fi diff --git a/sh/shrc.d/sd.sh b/sh/shrc.d/sd.sh index af82b67e..8b12c170 100644 --- a/sh/shrc.d/sd.sh +++ b/sh/shrc.d/sd.sh @@ -41,45 +41,75 @@ sd() { # Read sole optional argument case $1 in - # If blank, get a full list of directories at this level; include - # dotfiles, but not the . and .. entries, using glob tricks to avoid - # Bash ruining things with `dotglob` + # Slashes aren't allowed + */*) + printf >&2 'bd(): Illegal slash\n' + return 2 + ;; + + # If blank, we try to find if there's just one sibling, and change to + # that if so '') + # First a special case: root dir + case $PWD in + *[!/]*) ;; + *) + printf >&2 'sd(): No siblings\n' + return 1 + ;; + esac + + # Get a full list of directories at this level; include dotfiles, + # but not the . and .. entries, using glob tricks to avoid Bash + # ruining things with `dotglob` set -- ../[!.]*/ [ -e "$1" ] || shift set -- ../.[!.]*/ "$@" [ -e "$1" ] || shift set -- ../..?*/ "$@" [ -e "$1" ] || shift - ;; - # If not, get that directory, and the current one; shift it off if it - # doesn't exist - *) - set -- ../"${1%/}"/ ../"${PWD##*/}"/ - [ -e "$1" ] || shift - ;; - esac + # Check the number of matches + case $# in - # We should now have two parameters: the current directory and the matched - # sibling - case $# in - 2) ;; - 0|1) - printf >&2 'sd(): No match\n' - return 1 - ;; - *) - printf >&2 'sd(): Multiple matches\n' - return 1 + # One match? Must be $PWD, so no siblings--throw in 0 just in + # case, but that Shouldn't Happen (TM) + 0|1) + printf >&2 'sd(): No siblings\n' + return 1 + ;; + + # Two matches; hopefully just one sibling, but which is it? + 2) + + # Push PWD onto the stack, strip trailing slashes + set -- "$1" "$2" "$PWD" + while : ; do + case $3 in + */) set -- "$1" "$2" "${3%/}" ;; + *) break ;; + esac + done + + # Pick whichever of our two parameters doesn't look like + # PWD as our sole parameter + case $1 in + ../"${3##*/}"/) set -- "$2" ;; + *) set -- "$1" ;; + esac + ;; + + # Anything else? Multiple siblings--user will need to specify + *) + printf >&2 'sd(): Multiple siblings\n' + return 1 + ;; + esac ;; - esac - # Find which of these two is not the current directory and set that as our - # sole parameter - case $1 in - ../"${PWD##*/}"/) set -- "$2" ;; - *) set -- "$1" ;; + # If not, simply set our target to that directory, and let `cd` do the + # complaining if it doesn't exist + *) set -- ../"$1" ;; esac # Try and change into the first parameter -- cgit v1.2.3 From ee2a3a4d87665fb8b79363b1f78250908ec78b94 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 22:53:36 +1200 Subject: Revert "Remove redundant `|| return` from gd()" This reverts commit 1302b279bf2b1b2ae76ea8251a32e480d64f2f7a. This was added because of Shellcheck being fussy --- sh/shrc.d/gd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sh/shrc.d/gd.sh b/sh/shrc.d/gd.sh index 10135d01..9f6a43e7 100644 --- a/sh/shrc.d/gd.sh +++ b/sh/shrc.d/gd.sh @@ -14,5 +14,5 @@ gd() { fi # Go to the marked directory - cd -- "$PMD" + cd -- "$PMD" || return } -- cgit v1.2.3 From 5f714e85e2d97bf820b86db924eb00f459d731eb Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 27 May 2017 23:51:52 +1200 Subject: Simplify rd() a lot Including removing the pesky subshell --- sh/shrc.d/rd.sh | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/sh/shrc.d/rd.sh b/sh/shrc.d/rd.sh index c4c1c063..9633713a 100644 --- a/sh/shrc.d/rd.sh +++ b/sh/shrc.d/rd.sh @@ -23,42 +23,17 @@ rd() { ;; esac - # Set the positional parameters to an option terminator and what will - # hopefully end up being the substituted directory name - set -- "$( - - # Current path: e.g. /foo/ayy/bar/ayy - cur=$PWD - # Pattern to replace: e.g. ayy - pat=$1 - # Text with which to replace pattern: e.g. lmao - # This can be a null string or unset, in order to *remove* the pattern - rep=$2 - - # /foo/ - curtc=${cur%%"$pat"*} - # /bar/ayy - curlc=${cur#*"$pat"} - # /foo/lmao/bar/ayy - new=${curtc}${rep}${curlc} - - # Check that a substitution resulted in an actual change and that we - # ended up with a non-null target, or print an error to stderr - if [ "$cur" = "$curtc" ] || [ -z "$new" ] ; then + # Check there's something to substitute, and do it + case $PWD in + *"$1"*) + set -- "${PWD%%"$1"*}""$2""${PWD#*"$1"}" + ;; + *) printf >&2 'rd(): Substitution failed\n' - exit 1 - fi - - # Print the target with trailing slash to work around newline stripping - printf '%s/' "${new%/}" - )" - - # Remove trailing slash - set -- "${1%/}" - - # If the subshell printed nothing, return with failure - [ -n "$1" ] || return + return 1 + ;; + esac # Try to change into the determined directory - command cd -- "$@" + command cd -- "$1" } -- cgit v1.2.3 From 3550103bbfdbb5675a961dafd6fe13fd58866f15 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 28 May 2017 00:21:09 +1200 Subject: Resolve issue Satisfied the remaining subshells are needed --- ISSUES.markdown | 2 -- 1 file changed, 2 deletions(-) diff --git a/ISSUES.markdown b/ISSUES.markdown index 83358762..a69e07df 100644 --- a/ISSUES.markdown +++ b/ISSUES.markdown @@ -23,5 +23,3 @@ Known issues my own stuff in there * Completion for custom functions e.g. `sd` should ideally respect `completion-ignore-case` setting -* Would be good to remove the remaining subshell expansions in sh/shrc.d if - possible, have already removed them from bd/pd/sd/ud() -- cgit v1.2.3 From 8b398553a6d6667c004b5fd2125501613471a2b5 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 28 May 2017 12:56:15 +1200 Subject: Add mw(1df) --- .gitignore | 1 + Makefile | 1 + README.markdown | 2 ++ bin/mw.awk | 10 ++++++++++ man/man1/mw.1df | 25 +++++++++++++++++++++++++ 5 files changed, 39 insertions(+) create mode 100644 bin/mw.awk create mode 100644 man/man1/mw.1df diff --git a/.gitignore b/.gitignore index e2f5a857..4d9ef923 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ bin/mktd bin/mode bin/motd bin/murl +bin/mw bin/nlbr bin/onl bin/osc diff --git a/Makefile b/Makefile index 1f620612..d570e6b8 100644 --- a/Makefile +++ b/Makefile @@ -132,6 +132,7 @@ BINS = bin/ap \ bin/mode \ bin/motd \ bin/murl \ + bin/mw \ bin/nlbr \ bin/onl \ bin/osc \ diff --git a/README.markdown b/README.markdown index 9d16abe5..6b0ff38e 100644 --- a/README.markdown +++ b/README.markdown @@ -502,6 +502,8 @@ 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. +* `mw(1df)` prints alphabetic space-delimited words from the input one per + line. * `onl(1df)` crunches input down to one printable line. * `osc(1df)` implements a `netcat(1)`-like wrapper for `openssl(1)`'s `s_client` subcommand. diff --git a/bin/mw.awk b/bin/mw.awk new file mode 100644 index 00000000..f51b8272 --- /dev/null +++ b/bin/mw.awk @@ -0,0 +1,10 @@ +# Crude approach to get alphabetic words one per line from input, not sorted or +# deduplicated +BEGIN { + RS = "(--|['_-]?[^[:alnum:]'_-]+['_-]?)" +} +{ + for (i = 1; i <= NF; i++) + if ($i ~ /[[:alpha:]]/) + print $i +} diff --git a/man/man1/mw.1df b/man/man1/mw.1df new file mode 100644 index 00000000..51623600 --- /dev/null +++ b/man/man1/mw.1df @@ -0,0 +1,25 @@ +.TH MW 1df "May 2017" "Manual page for mw" +.SH NAME +.B mw +\- get space-delimited alphabetic words from input, one per line +.SH SYNOPSIS +.B mw FILE1 +[FILE2...] +.br +prog1 | +.B mw +.SH DESCRIPTION +.B mw +separates the input into space-delimited words and prints them one per line, +with no deduplication or sorting. It's a fairly naïve approach to the problem +but it works fine as a crude initial approach. +.SH NOTES +This was written after watching that lovely old AT&T video where members of the +Unix team (specifically Brian Kernighan and Lorinda Cherry) demonstrate piping +programs together; Kernighan demonstrates `makewords` during his example. +.P + +.SH SEE ALSO +ddup(1df), sort(1), uniq(1) +.SH AUTHOR +Tom Ryder -- cgit v1.2.3 From c1a8107b028c02ddb7c8d13f5803b5d84d52b070 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 28 May 2017 13:08:23 +1200 Subject: Tweak FS a bit for mw(1df) --- bin/mw.awk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/mw.awk b/bin/mw.awk index f51b8272..84332fac 100644 --- a/bin/mw.awk +++ b/bin/mw.awk @@ -1,7 +1,7 @@ # Crude approach to get alphabetic words one per line from input, not sorted or # deduplicated BEGIN { - RS = "(--|['_-]?[^[:alnum:]'_-]+['_-]?)" + RS = "(--|['_-]*[^[:alnum:]'_-]+['_-]*)" } { for (i = 1; i <= NF; i++) -- cgit v1.2.3 From 3df8bf4b48f87d181cf3e289085c30dab38c494c Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 28 May 2017 13:27:13 +1200 Subject: Add p(1df) --- .gitignore | 1 + Makefile | 1 + README.markdown | 2 ++ bin/p.sh | 1 + man/man1/p.1df | 27 +++++++++++++++++++++++++++ 5 files changed, 32 insertions(+) create mode 100644 bin/p.sh create mode 100644 man/man1/p.1df diff --git a/.gitignore b/.gitignore index 4d9ef923..a539a8f8 100644 --- a/.gitignore +++ b/.gitignore @@ -63,6 +63,7 @@ bin/mw bin/nlbr bin/onl bin/osc +bin/p bin/pa bin/paz bin/ped diff --git a/Makefile b/Makefile index d570e6b8..f35e1917 100644 --- a/Makefile +++ b/Makefile @@ -141,6 +141,7 @@ BINS = bin/ap \ bin/ped \ bin/pit \ bin/plmu \ + bin/p \ bin/pp \ bin/pph \ bin/pst \ diff --git a/README.markdown b/README.markdown index 6b0ff38e..c35d3790 100644 --- a/README.markdown +++ b/README.markdown @@ -507,6 +507,8 @@ Installed by the `install-bin` target: * `onl(1df)` crunches input down to one printable line. * `osc(1df)` implements a `netcat(1)`-like wrapper for `openssl(1)`'s `s_client` subcommand. +* `p(1df)` prints concatenated standard input; `cat(1)` as it should always + have been * `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:`. diff --git a/bin/p.sh b/bin/p.sh new file mode 100644 index 00000000..5b59986e --- /dev/null +++ b/bin/p.sh @@ -0,0 +1 @@ +exec cat -- "${@:--}" diff --git a/man/man1/p.1df b/man/man1/p.1df new file mode 100644 index 00000000..2d291fc1 --- /dev/null +++ b/man/man1/p.1df @@ -0,0 +1,27 @@ +.TH P 1df "May 2017" "Manual page for p" +.SH NAME +.B p +\- print standard input to standard output +.SH SYNOPSIS +.B p +FILE1 [FILE2...] +.br +prog1 | +.B +p +.br +prog1 | +.B +p +FILE1 - FILE2 +.SH DESCRIPTION +.B p +prints concatenated standard input from files to, and nothing else; cat(1) as +it always should have been--no flags, and hence no need for end-of-options for +filenames that start with a dash. +.P +Quicker to type, too. +.SH SEE ALSO +cat(1) +.SH AUTHOR +Tom Ryder -- cgit v1.2.3 From af85480289c13f091f18a97312e59c599fc1c697 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 28 May 2017 13:29:23 +1200 Subject: Add a note --- man/man1/p.1df | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man/man1/p.1df b/man/man1/p.1df index 2d291fc1..cafd8798 100644 --- a/man/man1/p.1df +++ b/man/man1/p.1df @@ -21,6 +21,9 @@ it always should have been--no flags, and hence no need for end-of-options for filenames that start with a dash. .P Quicker to type, too. +.P +Still treats an "-" argument as a shorthand for "standard input" though, +because I like that and it's POSIX. .SH SEE ALSO cat(1) .SH AUTHOR -- cgit v1.2.3 From 30bd54d5da1c7b766fad61c71c7cb24ac79ce06e Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 28 May 2017 13:41:28 +1200 Subject: Add a pome --- man/man1/p.1df | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/man/man1/p.1df b/man/man1/p.1df index cafd8798..3a06078b 100644 --- a/man/man1/p.1df +++ b/man/man1/p.1df @@ -24,6 +24,18 @@ Quicker to type, too. .P Still treats an "-" argument as a shorthand for "standard input" though, because I like that and it's POSIX. +.SH POETRY + "Prophet!" said I, "thing of evil!--prophet still, if bird or devil!-- +.br + Whether Tempter sent, or whether tempest tossed thee here ashore, +.br + Desolate yet all undaunted, on this desert land enchanted-- +.br + On this home by Horror haunted--tell me truly, I implore-- +.br + Is there--is there balm in Gilead?--tell me--tell me, I implore!" +.br + Quoth the Raven "Nevermore." .SH SEE ALSO cat(1) .SH AUTHOR -- cgit v1.2.3 From fd958555e213e1bf04b8538c2ae1d19d32fa6c02 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 28 May 2017 13:43:17 +1200 Subject: Format the quotes a bit more nicely --- man/man1/edda.1df | 10 +++++----- man/man1/p.1df | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/man/man1/edda.1df b/man/man1/edda.1df index c501e571..55a12f45 100644 --- a/man/man1/edda.1df +++ b/man/man1/edda.1df @@ -13,15 +13,15 @@ each of the files given as arguments. Example: w EOF .SH WISDOM -"Each man who is wise and would wise be called, + Each man who is wise and would wise be called, .br - Must ask and answer aright. + Must ask and answer aright. .br - Let one know thy secret, but never a second; + Let one know thy secret, but never a second; .br - If three, a thousand shall know." + If three, a thousand shall know." .P - -- Poetic Edda, Hávamál, 63 + -- Poetic Edda, Hávamál, 63 .br .SH SEE ALSO ed(1) diff --git a/man/man1/p.1df b/man/man1/p.1df index 3a06078b..803fd4c6 100644 --- a/man/man1/p.1df +++ b/man/man1/p.1df @@ -34,8 +34,9 @@ because I like that and it's POSIX. On this home by Horror haunted--tell me truly, I implore-- .br Is there--is there balm in Gilead?--tell me--tell me, I implore!" -.br +.P Quoth the Raven "Nevermore." + -- Poe .SH SEE ALSO cat(1) .SH AUTHOR -- cgit v1.2.3 From 19aa20ea90c3671b29bf1e2237cc5d3bc92990d7 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Mon, 29 May 2017 01:00:04 +1200 Subject: Update submodules --- vim/bundle/pathogen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vim/bundle/pathogen b/vim/bundle/pathogen index 3ec671e1..17f6f4d5 160000 --- a/vim/bundle/pathogen +++ b/vim/bundle/pathogen @@ -1 +1 @@ -Subproject commit 3ec671e112c760e68eee1e3cc5eeb9408448dab4 +Subproject commit 17f6f4d585062ffdcf99b4af80aee3c706b4038f -- cgit v1.2.3 From f2d19bb3ab31fd94eb521859e2f44d99579ed840 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 13:40:25 +1200 Subject: Add an idea --- IDEAS.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/IDEAS.markdown b/IDEAS.markdown index 4cac76f7..3b0f1c75 100644 --- a/IDEAS.markdown +++ b/IDEAS.markdown @@ -10,3 +10,5 @@ Ideas * qmp(1df)--quick man page * The solution to chn(1df) not running in parallel is probably backgrounded processes and mkfifo(1). +* Write something like hcat(1df) or tcat(1df) that includes filename headings + for each concatenated file. -- cgit v1.2.3 From 880277e86857e75168707001155180923b601756 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 18:11:45 +1200 Subject: Add "downloads.sh" profile event Looks for ~/.downloads, checks each named dir, if there are any files in it, warns you once per dir including a count. This is to prompt me into sorting my downloads directory. --- sh/profile.d/downloads.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 sh/profile.d/downloads.sh diff --git a/sh/profile.d/downloads.sh b/sh/profile.d/downloads.sh new file mode 100644 index 00000000..eb2a9b54 --- /dev/null +++ b/sh/profile.d/downloads.sh @@ -0,0 +1,13 @@ +[ -f "$HOME"/.downloads ] || return +( + while IFS= read -r dir ; do + case $dir in + '#'*) continue ;; + esac + [ -d "$dir" ] || continue + set -- "$dir"/* + [ -e "$1" ] || shift + [ "$#" -gt 0 ] || continue + printf 'You have %u unsorted files in %s.\n' "$#" "$dir" + done < "$HOME"/.downloads +) -- cgit v1.2.3 From 8ca2f8db01b8660a235bede6987bd31e5cc63c14 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 18:14:01 +1200 Subject: Some extra newlines --- sh/profile.d/downloads.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sh/profile.d/downloads.sh b/sh/profile.d/downloads.sh index eb2a9b54..4c57ddfd 100644 --- a/sh/profile.d/downloads.sh +++ b/sh/profile.d/downloads.sh @@ -8,6 +8,6 @@ set -- "$dir"/* [ -e "$1" ] || shift [ "$#" -gt 0 ] || continue - printf 'You have %u unsorted files in %s.\n' "$#" "$dir" + printf '\nYou have %u unsorted files in %s.\n\n' "$#" "$dir" done < "$HOME"/.downloads ) -- cgit v1.2.3 From 656da025bb037b816b2e7be9102a6705772207b8 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 18:15:39 +1200 Subject: Conditions for downloads.sh --- sh/profile.d/downloads.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sh/profile.d/downloads.sh b/sh/profile.d/downloads.sh index 4c57ddfd..fb8dd64a 100644 --- a/sh/profile.d/downloads.sh +++ b/sh/profile.d/downloads.sh @@ -1,4 +1,19 @@ +# Only if shell is interactive +case $- in + *i*) ;; + *) return ;; +esac + +# Only if not in a tmux window +[ -z "$TMUX" ] || return + +# Not if ~/.hushlogin exists +[ -e "$HOME"/.hushlogin ] && return + +# Not if ~/.downloads doesn't [ -f "$HOME"/.downloads ] || return + +# Count files in each directory, report if greater than zero ( while IFS= read -r dir ; do case $dir in -- cgit v1.2.3 From 15c3cf609f3d4df1f9d43b0eda20d8bd4297e364 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 19:44:21 +1200 Subject: Adjust man page indent --- man/man1/edda.1df | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/man/man1/edda.1df b/man/man1/edda.1df index 55a12f45..8c71f3ec 100644 --- a/man/man1/edda.1df +++ b/man/man1/edda.1df @@ -8,10 +8,10 @@ Duplicate any data on stdin into a temporary file, and run ed(1) options over each of the files given as arguments. Example: .P - $ edda /etc/app.d/*.conf <<'EOF' - ,s/foo/bar/g - w - EOF + $ edda /etc/app.d/*.conf <<'EOF' + ,s/foo/bar/g + w + EOF .SH WISDOM Each man who is wise and would wise be called, .br -- cgit v1.2.3 From f156a9f4199842c7a4d19cdabd1c6e932b0123b4 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 19:44:30 +1200 Subject: Adjust p(1df) man page --- man/man1/p.1df | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/man/man1/p.1df b/man/man1/p.1df index 803fd4c6..1a539e34 100644 --- a/man/man1/p.1df +++ b/man/man1/p.1df @@ -34,8 +34,9 @@ because I like that and it's POSIX. On this home by Horror haunted--tell me truly, I implore-- .br Is there--is there balm in Gilead?--tell me--tell me, I implore!" -.P +.br Quoth the Raven "Nevermore." +.P -- Poe .SH SEE ALSO cat(1) -- cgit v1.2.3 From 4d99ffcec10c522229d9325a8691fc595c6098e9 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 19:45:36 +1200 Subject: Restore a missing word --- man/man1/p.1df | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/man1/p.1df b/man/man1/p.1df index 1a539e34..2f9f3c45 100644 --- a/man/man1/p.1df +++ b/man/man1/p.1df @@ -16,9 +16,9 @@ p FILE1 - FILE2 .SH DESCRIPTION .B p -prints concatenated standard input from files to, and nothing else; cat(1) as -it always should have been--no flags, and hence no need for end-of-options for -filenames that start with a dash. +prints concatenated standard input from files to standard output, and nothing +else; cat(1) as it always should have been--no flags, and hence no need for +end-of-options for filenames that start with a dash. .P Quicker to type, too. .P -- cgit v1.2.3 From dae63c5bb36f05ee733ce298ed6d3a3cf5fadf96 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 19:49:43 +1200 Subject: Correct a path in bcq(1df) man page --- man/man1/bcq.1df | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man1/bcq.1df b/man/man1/bcq.1df index 55b44a69..64e2048b 100644 --- a/man/man1/bcq.1df +++ b/man/man1/bcq.1df @@ -6,7 +6,7 @@ .B bcq .SH DESCRIPTION .B bcq -starts bc(1), checking ~/.cache/bc/quiet to see if a --quiet option is +starts bc(1), checking ~/.cache/sh/opt/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 -- cgit v1.2.3 From 3a96724544969ca1d6e61b2e7b3cde9aed4be243 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 19:52:45 +1200 Subject: Correct a troff macro in clog(1df) man page --- man/man1/clog.1df | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man1/clog.1df b/man/man1/clog.1df index 0e3e7b87..43193076 100644 --- a/man/man1/clog.1df +++ b/man/man1/clog.1df @@ -13,7 +13,7 @@ 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 +.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 -- cgit v1.2.3 From 3a15bc2a248c14136d32751d7fda3499a6865800 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 19:57:27 +1200 Subject: Unbold example arguments in fgscr(1df) man page --- man/man1/fgscr.1df | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/man/man1/fgscr.1df b/man/man1/fgscr.1df index 80da3798..cc273b89 100644 --- a/man/man1/fgscr.1df +++ b/man/man1/fgscr.1df @@ -5,7 +5,8 @@ .SH SYNOPSIS .B fgscr .br -.B fgscr /path1 /path2 +.B fgscr +/path1 /path2 .SH DESCRIPTION .B fgscr searches for Git repositories recursively with the given ancestor directory -- cgit v1.2.3 From 4cbf95d7b61eff5f31e113a105283356c51bd5fe Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 19:58:44 +1200 Subject: Correct copy-paste error in fnl(1df) man page --- man/man1/fnl.1df | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man1/fnl.1df b/man/man1/fnl.1df index 6c34f19c..d085df6b 100644 --- a/man/man1/fnl.1df +++ b/man/man1/fnl.1df @@ -1,7 +1,7 @@ .TH FNL 1df "August 2016" "Manual page for fnl" .SH NAME .B fnl -\- list the biggest files in the given directory +\- run a command and put stdout and stderr into temporary files .SH SYNOPSIS .B fnl command arg1 ... -- cgit v1.2.3 From 63461b89b2343ed459f1d9cf8000be7dfc4f15b5 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 31 May 2017 20:09:33 +1200 Subject: Correction/referencing for pp/pph(1df) --- man/man1/pp.1df | 2 ++ man/man1/pph.1df | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/man/man1/pp.1df b/man/man1/pp.1df index 322e7b48..0bb55cd1 100644 --- a/man/man1/pp.1df +++ b/man/man1/pp.1df @@ -15,5 +15,7 @@ The path need not actually exist. 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 SEE ALSO +pph(1df) .SH AUTHOR Tom Ryder diff --git a/man/man1/pph.1df b/man/man1/pph.1df index 0ad98fc5..f68b394d 100644 --- a/man/man1/pph.1df +++ b/man/man1/pph.1df @@ -1,9 +1,9 @@ -.TH PPH 1df "January 2017" "Manual page for pp" +.TH PPH 1df "January 2017" "Manual page for pph" .SH NAME -.B pp +.B pph \- print the full path to each argument, hostname prepended .SH SYNOPSIS -.B pp +.B pph /arg arg2 ./arg3 .SH DESCRIPTION .B pph @@ -12,5 +12,7 @@ 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 SEE ALSO +pp(1df) .SH AUTHOR Tom Ryder -- cgit v1.2.3 From 9cb768020c4efaec2a69251c4ef46dfe35f2ce26 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Thu, 1 Jun 2017 01:00:04 +1200 Subject: Update submodules --- vim/bundle/pathogen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vim/bundle/pathogen b/vim/bundle/pathogen index 17f6f4d5..ddfb1f14 160000 --- a/vim/bundle/pathogen +++ b/vim/bundle/pathogen @@ -1 +1 @@ -Subproject commit 17f6f4d585062ffdcf99b4af80aee3c706b4038f +Subproject commit ddfb1f14d7597e6aedc749be06b559a673c437ab -- cgit v1.2.3 From 7b49385f30020777db82732760e667e90b9ae0f8 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Thu, 1 Jun 2017 11:07:19 +1200 Subject: Add skip-pager to ~/.my.cnf I usually don't want it --- mysql/my.cnf | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql/my.cnf b/mysql/my.cnf index e0df3c23..900cf1a9 100644 --- a/mysql/my.cnf +++ b/mysql/my.cnf @@ -3,3 +3,4 @@ default-character-set=utf8 no-auto-rehash prompt='(\u@\h:\d) mysql> ' safe-updates +skip-pager -- cgit v1.2.3 From 56c8ada346bde4ea44e199020c03afd731727bd6 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Jun 2017 18:28:57 +1200 Subject: Simplify some awk --- bin/rfct.awk | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/bin/rfct.awk b/bin/rfct.awk index 256841a7..4467f206 100644 --- a/bin/rfct.awk +++ b/bin/rfct.awk @@ -6,11 +6,8 @@ BEGIN { ORS = "\n\n" } -{ - # Strip out control characters, except tab and newline - gsub(/[^[:print:]\n\t]/, "") +# Strip out control characters, except tab and newline +{ gsub(/[^[:print:]\n\t]/, "") } - # If there's anything left, print it - if (length) - print -} +# If there's anything left, print it +length($0) -- cgit v1.2.3 From cde3c255ff7024181a54b19e5ec1dac3ab892836 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Jun 2017 20:30:20 +1200 Subject: Add mi5(1df) --- .gitignore | 1 + IDEAS.markdown | 2 ++ Makefile | 1 + README.markdown | 2 ++ bin/mi5.awk | 50 ++++++++++++++++++++++++++++++++++++++++++++ man/man1/mi5.1df | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 119 insertions(+) create mode 100644 bin/mi5.awk create mode 100644 man/man1/mi5.1df diff --git a/.gitignore b/.gitignore index a539a8f8..68ac0a0a 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ bin/jfc bin/jfcd bin/jfp bin/loc +bin/mi5 bin/max bin/maybe bin/mean diff --git a/IDEAS.markdown b/IDEAS.markdown index 3b0f1c75..61f1049d 100644 --- a/IDEAS.markdown +++ b/IDEAS.markdown @@ -12,3 +12,5 @@ Ideas processes and mkfifo(1). * Write something like hcat(1df) or tcat(1df) that includes filename headings for each concatenated file. +* mi5(1df) could be made to handle comment delimiters and $1 $2 expansions + without too much pain (substr/index counting) diff --git a/Makefile b/Makefile index f35e1917..a562b0b1 100644 --- a/Makefile +++ b/Makefile @@ -119,6 +119,7 @@ BINS = bin/ap \ bin/jfcd \ bin/jfp \ bin/loc \ + bin/mi5 \ bin/max \ bin/maybe \ bin/mean \ diff --git a/README.markdown b/README.markdown index c35d3790..bd0b6682 100644 --- a/README.markdown +++ b/README.markdown @@ -498,6 +498,8 @@ Installed by the `install-bin` target: success, it exits with success or failure. Good for quick tests. * `mex(1df)` makes given filenames in `$PATH` executable. +* `mi5(1df)` pre-processes a crude but less painful macro expansion file + format into m4. * `mftl(1df)` finds usable-looking targets in Makefiles. * `mkcp(1df)` creates a directory and copies preceding arguments into it. * `mkmv(1df)` creates a directory and moves preceding arguments into it. diff --git a/bin/mi5.awk b/bin/mi5.awk new file mode 100644 index 00000000..c05955ff --- /dev/null +++ b/bin/mi5.awk @@ -0,0 +1,50 @@ +# Crude m4 preprocessor +BEGIN { mac = 0 } + +# Print an m4 opener as the first byte +NR == 1 { printf "`" } + +# Blocks +NF == 1 && $1 == "<%" && !mac { + mac = 1 + printf "'" + next +} +NF == 1 && $1 == "%>" && mac { + mac = 0 + printf "`" + next +} + +# If processing macros, strip leading and trailing whitespace and skip blank +# lines +mac { + sub(/^ */, "") + sub(/ *$/, "") +} +mac && !NF { next } + +# Inlines +mac { + print $0 "dnl" +} +!mac { + + # Don't let apostrophes close the comment + gsub(/'/, "''`") + + # Don't let $ signs confound expansion + gsub(/\$/, "$'`") + + # Replace m5 opener with m4 closer + gsub(/<% */, "'") + + # Replace m5 closer with m4 opener + gsub(/ *%>/, "`") + print +} + +# Print an m4 closer and newline deleter as the last bytes +END { + print "'dnl" +} diff --git a/man/man1/mi5.1df b/man/man1/mi5.1df new file mode 100644 index 00000000..dd215d0c --- /dev/null +++ b/man/man1/mi5.1df @@ -0,0 +1,63 @@ +.TH MI5 1df "June 2017" "Manual page for mi5" +.SH NAME +.B mi5 +\- m4 inverted preprocessor +.SH SYNOPSIS +.B mi5 +FILE > out.m4 +.br +.B mi5 +FILE1 FILE2 > out.m4 +.br +prog | +.B mi5 > out.m4 +.br +.SH DESCRIPTION +.B mi5 +is a simple and crude m4 preprocessor to make using m4 slightly more bearable +and predictable for its author, who wants badly to like m4 but doesn't. It's +primarily intended for situations where the majority of a file is simple static +text, and only a few simple macros need to be defined and expanded, which +covers almost every usage case for the author. It's written to work with any +POSIX m4. +.P +mi5 inverts m4's usual approach by approaching most of the file as if it were +part of an m4 comment, with <% and %> as the delimiters to specify markers in +which macro expansion should occur. This makes m4 work in a way reminiscent of +templating libraries or languages like PHP. +.P +Macros can be expanded as blocks: +.P + <% + define(`FOO', `bar') + define(`BAZ', include(`include/quux.inc') + ?> +.P +For this format, "dnl" macros to delete newlines for each declaration are +inserted for you. Blank lines are skipped, and leading and trailing spaces are +ignored. The above code therefore produces no actual output, as it only has two +define calls. +.P +For inline expansion, the syntax is similar, but the behaviour slightly different: +.P + The value of the FOO macro is <% FOO %>. +.P +Spaces immediately after the opening delimiter and before the closing delimiter +are ignored, but spaces produced within the macro are preserved. +.P +Ideally, you do macro definition in an mi5 block at the top of your file, and +very simple macro expansion in an mi5 inline. +.SH CAVEATS +Only very simple macro expansions work in inline calls at the moment. This can +be fixed by the author tokenizing the line properly, which he'll do Real Soon +Now (TM). Specifically, neither comment delimiters nor macro parameters work. +The latter is because of a nasty corner-case in m4 where parameter expansions +$1, $2, $*, etc are expanded +.B even within comments, +one of m4's darkest corners. The workaround is to do as much logic as you can +in a block, defining your result as a single simple macros, and then expanding +that inline. +.SH SEE ALSO +bp(1df), xargs(1) +.SH AUTHOR +Tom Ryder -- cgit v1.2.3 From bae8dea461ddbceb4f345d2f230460e7234af76d Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Jun 2017 20:45:22 +1200 Subject: Move existing .m4 to .m4.mi5 Along with accompanying Makefile rules and .gitignorances --- .gitignore | 3 ++ Makefile | 8 +++- git/gitconfig.m4 | 64 ------------------------- git/gitconfig.m4.mi5 | 64 +++++++++++++++++++++++++ gnupg/gpg.conf.m4 | 52 -------------------- gnupg/gpg.conf.m4.mi5 | 52 ++++++++++++++++++++ tmux/tmux.conf.m4 | 130 -------------------------------------------------- tmux/tmux.conf.m4.mi5 | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 256 insertions(+), 247 deletions(-) delete mode 100644 git/gitconfig.m4 create mode 100644 git/gitconfig.m4.mi5 delete mode 100644 gnupg/gpg.conf.m4 create mode 100644 gnupg/gpg.conf.m4.mi5 delete mode 100644 tmux/tmux.conf.m4 create mode 100644 tmux/tmux.conf.m4.mi5 diff --git a/.gitignore b/.gitignore index 68ac0a0a..873b60a1 100644 --- a/.gitignore +++ b/.gitignore @@ -137,7 +137,10 @@ games/strik games/xyzzy games/zs git/gitconfig +git/gitconfig.m4 gnupg/gpg.conf +gnupg/gpg.conf.m4 man/man7/dotfiles.7df tmux/tmux.conf +tmux/tmux.conf.m4 urxvt/ext/select diff --git a/Makefile b/Makefile index a562b0b1..11bcf6f0 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ lint-xinit .SUFFIXES: -.SUFFIXES: .awk .bash .pl .sed .sh +.SUFFIXES: .awk .bash .mi5 .pl .sed .sh NAME = 'Tom Ryder' EMAIL = tom@sanctum.geek.nz @@ -218,9 +218,12 @@ clean distclean: $(BINS) \ $(GAMES) \ git/gitconfig \ + git/gitconfig.m4 \ gnupg/gpg.conf \ + gnupg/gpg.conf.m4 \ man/man8/dotfiles.7df \ tmux/tmux.conf \ + tmux/tmux.conf.m4 \ urxvt/ext/select git/gitconfig: git/gitconfig.m4 @@ -270,6 +273,9 @@ tmux/tmux.conf: tmux/tmux.conf.m4 sh bin/shb.sh sh < $< > $@ chmod +x ./$@ +.mi5: + awk -f bin/mi5.awk < $< > $@ + install: install-bin \ install-curl \ install-ex \ diff --git a/git/gitconfig.m4 b/git/gitconfig.m4 deleted file mode 100644 index f533f02f..00000000 --- a/git/gitconfig.m4 +++ /dev/null @@ -1,64 +0,0 @@ -[advice] - statusHints = false - detachedHead = false - implicitIdentity = false - pushUpdateRejected = false - -[alias] - amend = commit --amend - ls = log --oneline - others = ls-files --others --exclude-standard - fuckit = "!git clean -dfx ; git reset --hard" - -[color] - ui = true - -[commit] - status = false - -[core] - compression = 9 - -[diff] - algorithm = patience - tool = vimdiff - -[difftool] - prompt = false - -[fetch] - output = compact - prune = true - -[grep] - extendRegexp = true - lineNumber = true - -[log] - date = local - decorate = short - -[merge] - ff = false - -[pager] - diff = cat - -[pull] - ff = only - -[push] - default = current - -[sendemail] - confirm = compose - smtpServer = DF_SENDMAIL - -[status] - short = true - showUntrackedFiles = all - -[user] - name = DF_NAME - email = DF_EMAIL - signingKey = DF_KEY diff --git a/git/gitconfig.m4.mi5 b/git/gitconfig.m4.mi5 new file mode 100644 index 00000000..bce64d6c --- /dev/null +++ b/git/gitconfig.m4.mi5 @@ -0,0 +1,64 @@ +[advice] + statusHints = false + detachedHead = false + implicitIdentity = false + pushUpdateRejected = false + +[alias] + amend = commit --amend + ls = log --oneline + others = ls-files --others --exclude-standard + fuckit = "!git clean -dfx ; git reset --hard" + +[color] + ui = true + +[commit] + status = false + +[core] + compression = 9 + +[diff] + algorithm = patience + tool = vimdiff + +[difftool] + prompt = false + +[fetch] + output = compact + prune = true + +[grep] + extendRegexp = true + lineNumber = true + +[log] + date = local + decorate = short + +[merge] + ff = false + +[pager] + diff = cat + +[pull] + ff = only + +[push] + default = current + +[sendemail] + confirm = compose + smtpServer = <% DF_SENDMAIL %> + +[status] + short = true + showUntrackedFiles = all + +[user] + name = <% DF_NAME %> + email = <% DF_EMAIL %> + signingKey = <% DF_KEY %> diff --git a/gnupg/gpg.conf.m4 b/gnupg/gpg.conf.m4 deleted file mode 100644 index 29534991..00000000 --- a/gnupg/gpg.conf.m4 +++ /dev/null @@ -1,52 +0,0 @@ -# Retrieve certs automatically if possible -auto-key-locate cert pka - -# Prevent boilerplate about needing key decryption, which is handled by the -# agent; the gpg function in my Bash scripts overrides this for certain -# commands where it interferes -batch - -# Use SHA512 as the hash when making key signatures -cert-digest-algo SHA512 - -# Specify the hash algorithms to be used for new keys as available -default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed - -# In the absence of any other recipient, encrypt messages for myself -default-recipient-self - -# Show complete dates and use proper column separation for --with-colon listing mode -fixed-list-mode - -# Use 16-character key IDs as the default 8-character key IDs can be forged -keyid-format 0xlong - -# Use a pool of servers which support HKPS (encrypted key retrieval) -keyserver DF_KEYSERVER - -# Retrieve keys automatically; check the keyserver port cert; use whichever -# server is proffered from the pool -keyserver-options auto-key-retrieve check-cert no-honor-keyserver-url ca-certfile=DF_HOME/.gnupg/sks-keyservers.net/sks-keyservers.netCA.pem - -# Include trust/validity for UIDs in listings -list-options show-uid-validity - -# Suppress the copyright message -no-greeting - -# Use SHA512 as my message digest, overriding GnuPG's efforts to use the lowest -# common denominator in hashing algorithms -personal-digest-preferences SHA512 - -# Suppress a lot of output; sometimes I add --verbose to undo this -quiet - -# Use the GPG agent for key management and decryption -use-agent - -# Include trust/validity for UIDs when verifying signatures -verify-options pka-lookups show-uid-validity - -# Assume "yes" is the answer to most questions, that is, don't keep asking me -# to confirm something I've asked to be done -yes diff --git a/gnupg/gpg.conf.m4.mi5 b/gnupg/gpg.conf.m4.mi5 new file mode 100644 index 00000000..d8f14c09 --- /dev/null +++ b/gnupg/gpg.conf.m4.mi5 @@ -0,0 +1,52 @@ +# Retrieve certs automatically if possible +auto-key-locate cert pka + +# Prevent boilerplate about needing key decryption, which is handled by the +# agent; the gpg function in my Bash scripts overrides this for certain +# commands where it interferes +batch + +# Use SHA512 as the hash when making key signatures +cert-digest-algo SHA512 + +# Specify the hash algorithms to be used for new keys as available +default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed + +# In the absence of any other recipient, encrypt messages for myself +default-recipient-self + +# Show complete dates and use proper column separation for --with-colon listing mode +fixed-list-mode + +# Use 16-character key IDs as the default 8-character key IDs can be forged +keyid-format 0xlong + +# Use a pool of servers which support HKPS (encrypted key retrieval) +keyserver DF_KEYSERVER + +# Retrieve keys automatically; check the keyserver port cert; use whichever +# server is proffered from the pool +keyserver-options auto-key-retrieve check-cert no-honor-keyserver-url ca-certfile=<% DF_HOME %>/.gnupg/sks-keyservers.net/sks-keyservers.netCA.pem + +# Include trust/validity for UIDs in listings +list-options show-uid-validity + +# Suppress the copyright message +no-greeting + +# Use SHA512 as my message digest, overriding GnuPG's efforts to use the lowest +# common denominator in hashing algorithms +personal-digest-preferences SHA512 + +# Suppress a lot of output; sometimes I add --verbose to undo this +quiet + +# Use the GPG agent for key management and decryption +use-agent + +# Include trust/validity for UIDs when verifying signatures +verify-options pka-lookups show-uid-validity + +# Assume "yes" is the answer to most questions, that is, don't keep asking me +# to confirm something I've asked to be done +yes diff --git a/tmux/tmux.conf.m4 b/tmux/tmux.conf.m4 deleted file mode 100644 index 3a1d2425..00000000 --- a/tmux/tmux.conf.m4 +++ /dev/null @@ -1,130 +0,0 @@ -# Strip out a lot of machine and X11 dependent crap from the initial -# environment -set-environment -gru COLORFGBG -set-environment -gru COLORTERM -set-environment -gru DISPLAY -set-environment -gru SSH_CLIENT -set-environment -gru SSH_CONNECTION -set-environment -gru SSH_TTY -set-environment -gru WINDOWID - -# Otherwise, use the environment we had when we started; don't touch it during -# a session unless I specifically ask -set-option -g update-environment '' - -# Setting this makes each new pane a non-login shell, which suits me better -set-option -g default-command "$SHELL" - -# Expect a 256-color terminal -set-option -g default-terminal 'screen-256color' - -# Change the prefix to ^A rather than the default of ^B, because I'm a godless -# GNU Screen refugee, and also I like using ^B in my shell and in Vim more -unbind-key C-b -set-option -g prefix C-a -bind-key a send-prefix - -# Repeating the prefix switches to the last window and back, a GNU Screen -# feature that's hardwired into my brain now -bind-key C-a last-window - -# Quick ways to kill single windows and the whole server -bind-key '/' confirm-before 'kill-window' -bind-key '\' confirm-before 'kill-server' - -# Slightly more intuitive way to split windows -bind-key '_' split-window -v -bind-key '|' split-window -h - -# Switch to the last active pane -bind-key Tab last-pane - -# Use the vi mode for tmux interaction behaviour in copy and choice modes -set-window-option -g mode-keys vi -bind-key -T copy-mode-vi v send -X begin-selection -bind-key -T copy-mode-vi y send -X copy-selection-and-cancel - -# Detach with Alt-M, no prefix required -bind-key -n M-m detach - -# Vim-like pane resizing -bind-key -r '+' resize-pane -U 5 -bind-key -r '-' resize-pane -D 5 -bind-key -r '<' resize-pane -L 5 -bind-key -r '>' resize-pane -R 5 - -# Vim-like pane switching -bind-key h select-pane -L -bind-key j select-pane -D -bind-key k select-pane -U -bind-key l select-pane -R - -# Join and break panes -bind-key J choose-window "join-pane -h -s '%%'" -bind-key B break-pane -d - -# Select only sessions in the choose-tree menu, not the whole tree of sessions -# and windows, I prefer to drill down -bind-key s choose-session - -# Session title on the left side of the status bar -set-option -g status-left '[#S] ' - -# Username, hostname, and the current date on the right side of the status bar -set-option -g status-right ' [#(whoami)@#H] #(date +"%F %T")' - -# Update the status bar every second -set-option -g status-interval 1 - -# The first window in a session has index 1, rather than 0 -set-option -g base-index 1 - -# Don't worry about timeouts for key combinations, as I don't use Escape as -# meta and prefer things to be snappier -set-option -g escape-time 0 - -# Keep plenty of history -set-option -g history-limit 100000 - -# Don't interfere with my system clipboard -set-option -g set-clipboard off - -# Only force individual windows to the smallest attached terminal size, not -# whole sessions -set-window-option -g aggressive-resize on - -# If I don't set a title on a window, use the program name for the window title -set-window-option -g automatic-rename on - -# However, don't let terminal escape sequences rename my windows -set-window-option -g allow-rename off - -# Window titles are the window index, a colon, the window or command name, and -# any activity or alert indicators -set-window-option -g window-status-format "#I:#W#F" - -# Message dialogs are white on blue -set-option -g message-style "bg=colour18,fg=colour231" - -# Window choosers are white on blue -set-window-option -g mode-style "bg=colour18,fg=colour231" - -# Pane borders are always in the background color -set-option -g pane-border-style "fg=DF_TMUX_BG" -set-option -g pane-active-border-style "fg=DF_TMUX_BG" - -# Inactive windows have slightly washed-out system colours -set-option -g window-style "bg=colour232,fg=colour248" -set-option -g window-active-style "bg=colour0,fg=colour15" - -# The status bar has the defined background and foreground colours -set-option -g status-style "bg=DF_TMUX_BG,fg=DF_TMUX_FG" - -# Titles of windows default to black text with no embellishment -set-window-option -g window-status-style "fg=colour16" - -# The title of the active window is in white rather than black -set-window-option -g window-status-current-style "fg=colour231" - -# A window with a bell has a title with a red background until cleared -set-window-option -g window-status-bell-style "bg=colour9" diff --git a/tmux/tmux.conf.m4.mi5 b/tmux/tmux.conf.m4.mi5 new file mode 100644 index 00000000..76d493c1 --- /dev/null +++ b/tmux/tmux.conf.m4.mi5 @@ -0,0 +1,130 @@ +# Strip out a lot of machine and X11 dependent crap from the initial +# environment +set-environment -gru COLORFGBG +set-environment -gru COLORTERM +set-environment -gru DISPLAY +set-environment -gru SSH_CLIENT +set-environment -gru SSH_CONNECTION +set-environment -gru SSH_TTY +set-environment -gru WINDOWID + +# Otherwise, use the environment we had when we started; don't touch it during +# a session unless I specifically ask +set-option -g update-environment '' + +# Setting this makes each new pane a non-login shell, which suits me better +set-option -g default-command "$SHELL" + +# Expect a 256-color terminal +set-option -g default-terminal 'screen-256color' + +# Change the prefix to ^A rather than the default of ^B, because I'm a godless +# GNU Screen refugee, and also I like using ^B in my shell and in Vim more +unbind-key C-b +set-option -g prefix C-a +bind-key a send-prefix + +# Repeating the prefix switches to the last window and back, a GNU Screen +# feature that's hardwired into my brain now +bind-key C-a last-window + +# Quick ways to kill single windows and the whole server +bind-key '/' confirm-before 'kill-window' +bind-key '\' confirm-before 'kill-server' + +# Slightly more intuitive way to split windows +bind-key '_' split-window -v +bind-key '|' split-window -h + +# Switch to the last active pane +bind-key Tab last-pane + +# Use the vi mode for tmux interaction behaviour in copy and choice modes +set-window-option -g mode-keys vi +bind-key -T copy-mode-vi v send -X begin-selection +bind-key -T copy-mode-vi y send -X copy-selection-and-cancel + +# Detach with Alt-M, no prefix required +bind-key -n M-m detach + +# Vim-like pane resizing +bind-key -r '+' resize-pane -U 5 +bind-key -r '-' resize-pane -D 5 +bind-key -r '<' resize-pane -L 5 +bind-key -r '>' resize-pane -R 5 + +# Vim-like pane switching +bind-key h select-pane -L +bind-key j select-pane -D +bind-key k select-pane -U +bind-key l select-pane -R + +# Join and break panes +bind-key J choose-window "join-pane -h -s '%%'" +bind-key B break-pane -d + +# Select only sessions in the choose-tree menu, not the whole tree of sessions +# and windows, I prefer to drill down +bind-key s choose-session + +# Session title on the left side of the status bar +set-option -g status-left '[#S] ' + +# Username, hostname, and the current date on the right side of the status bar +set-option -g status-right ' [#(whoami)@#H] #(date +"%F %T")' + +# Update the status bar every second +set-option -g status-interval 1 + +# The first window in a session has index 1, rather than 0 +set-option -g base-index 1 + +# Don't worry about timeouts for key combinations, as I don't use Escape as +# meta and prefer things to be snappier +set-option -g escape-time 0 + +# Keep plenty of history +set-option -g history-limit 100000 + +# Don't interfere with my system clipboard +set-option -g set-clipboard off + +# Only force individual windows to the smallest attached terminal size, not +# whole sessions +set-window-option -g aggressive-resize on + +# If I don't set a title on a window, use the program name for the window title +set-window-option -g automatic-rename on + +# However, don't let terminal escape sequences rename my windows +set-window-option -g allow-rename off + +# Window titles are the window index, a colon, the window or command name, and +# any activity or alert indicators +set-window-option -g window-status-format "#I:#W#F" + +# Message dialogs are white on blue +set-option -g message-style "bg=colour18,fg=colour231" + +# Window choosers are white on blue +set-window-option -g mode-style "bg=colour18,fg=colour231" + +# Pane borders are always in the background color +set-option -g pane-border-style "fg=<% DF_TMUX_BG %>" +set-option -g pane-active-border-style "fg=<% DF_TMUX_BG %>" + +# Inactive windows have slightly washed-out system colours +set-option -g window-style "bg=colour232,fg=colour248" +set-option -g window-active-style "bg=colour0,fg=colour15" + +# The status bar has the defined background and foreground colours +set-option -g status-style "bg=<% DF_TMUX_BG %>,fg=<% DF_TMUX_FG %>" + +# Titles of windows default to black text with no embellishment +set-window-option -g window-status-style "fg=colour16" + +# The title of the active window is in white rather than black +set-window-option -g window-status-current-style "fg=colour231" + +# A window with a bell has a title with a red background until cleared +set-window-option -g window-status-bell-style "bg=colour9" -- cgit v1.2.3 From 78e2ead680d0f35aa1dd70de91f28932284b3664 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Jun 2017 20:48:15 +1200 Subject: Correct some terms in man mi5(1df) --- man/man1/mi5.1df | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/man1/mi5.1df b/man/man1/mi5.1df index dd215d0c..b56bed93 100644 --- a/man/man1/mi5.1df +++ b/man/man1/mi5.1df @@ -22,7 +22,7 @@ covers almost every usage case for the author. It's written to work with any POSIX m4. .P mi5 inverts m4's usual approach by approaching most of the file as if it were -part of an m4 comment, with <% and %> as the delimiters to specify markers in +part of an m4 quote, with <% and %> as the delimiters to specify markers in which macro expansion should occur. This makes m4 work in a way reminiscent of templating libraries or languages like PHP. .P @@ -50,10 +50,10 @@ very simple macro expansion in an mi5 inline. .SH CAVEATS Only very simple macro expansions work in inline calls at the moment. This can be fixed by the author tokenizing the line properly, which he'll do Real Soon -Now (TM). Specifically, neither comment delimiters nor macro parameters work. +Now (TM). Specifically, neither quote delimiters nor macro parameters work. The latter is because of a nasty corner-case in m4 where parameter expansions $1, $2, $*, etc are expanded -.B even within comments, +.B even within quotes, one of m4's darkest corners. The workaround is to do as much logic as you can in a block, defining your result as a single simple macros, and then expanding that inline. -- cgit v1.2.3 From bc1d5fb28841f6050605e93886685b3a02e7787a Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Jun 2017 22:07:52 +1200 Subject: Use mi5 to make templated shell scripts --- .gitignore | 21 +++++++- Makefile | 77 ++++++++++++++++++++---------- bin/chn.mi5 | 57 ++++++++++++++++++++++ bin/chn.sh | 69 --------------------------- bin/edda.mi5 | 21 ++++++++ bin/edda.sh | 33 ------------- bin/pst.mi5 | 19 ++++++++ bin/pst.sh | 32 ------------- bin/rndl.mi5 | 38 +++++++++++++++ bin/rndl.sh | 50 ------------------- bin/swr.mi5 | 52 ++++++++++++++++++++ bin/swr.sh | 64 ------------------------- bin/tlcs.mi5 | 81 +++++++++++++++++++++++++++++++ bin/tlcs.sh | 93 ------------------------------------ bin/try.mi5 | 65 +++++++++++++++++++++++++ bin/try.sh | 77 ------------------------------ bin/urlc.mi5 | 64 +++++++++++++++++++++++++ bin/urlc.sh | 76 ----------------------------- git/gitconfig.m4.mi5 | 64 ------------------------- git/gitconfig.mi5 | 64 +++++++++++++++++++++++++ gnupg/gpg.conf.m4.mi5 | 52 -------------------- gnupg/gpg.conf.mi5 | 52 ++++++++++++++++++++ include/mktd.mi5 | 15 ++++++ tmux/tmux.conf.m4.mi5 | 130 -------------------------------------------------- tmux/tmux.conf.mi5 | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ 25 files changed, 730 insertions(+), 766 deletions(-) create mode 100644 bin/chn.mi5 delete mode 100644 bin/chn.sh create mode 100644 bin/edda.mi5 delete mode 100644 bin/edda.sh create mode 100644 bin/pst.mi5 delete mode 100644 bin/pst.sh create mode 100644 bin/rndl.mi5 delete mode 100644 bin/rndl.sh create mode 100644 bin/swr.mi5 delete mode 100644 bin/swr.sh create mode 100644 bin/tlcs.mi5 delete mode 100644 bin/tlcs.sh create mode 100644 bin/try.mi5 delete mode 100644 bin/try.sh create mode 100644 bin/urlc.mi5 delete mode 100644 bin/urlc.sh delete mode 100644 git/gitconfig.m4.mi5 create mode 100644 git/gitconfig.mi5 delete mode 100644 gnupg/gpg.conf.m4.mi5 create mode 100644 gnupg/gpg.conf.mi5 create mode 100644 include/mktd.mi5 delete mode 100644 tmux/tmux.conf.m4.mi5 create mode 100644 tmux/tmux.conf.mi5 diff --git a/.gitignore b/.gitignore index 873b60a1..153d2227 100644 --- a/.gitignore +++ b/.gitignore @@ -12,16 +12,20 @@ bin/cf bin/cfr bin/chc bin/chn +bin/chn.sh +bin/chn.m4 bin/clog bin/clrd bin/clwr bin/csmw -bin/dam bin/d2u +bin/dam bin/ddup bin/dmp bin/dub bin/edda +bin/edda.sh +bin/edda.m4 bin/eds bin/exm bin/fgscr @@ -46,13 +50,13 @@ bin/jfc bin/jfcd bin/jfp bin/loc -bin/mi5 bin/max bin/maybe bin/mean bin/med bin/mex bin/mftl +bin/mi5 bin/min bin/mkcp bin/mkmv @@ -73,6 +77,8 @@ bin/plmu bin/pp bin/pph bin/pst +bin/pst.sh +bin/pst.m4 bin/pvi bin/pwg bin/quo @@ -84,6 +90,8 @@ bin/rnda bin/rndf bin/rndi bin/rndl +bin/rndl.sh +bin/rndl.m4 bin/rnds bin/sd2u bin/sec @@ -102,17 +110,25 @@ bin/su2d bin/sue bin/supp bin/swr +bin/swr.sh +bin/swr.m4 bin/td bin/tl bin/tlcs +bin/tlcs.sh +bin/tlcs.m4 bin/tm bin/tot bin/trs bin/try +bin/try.sh +bin/try.m4 bin/u2d bin/umake bin/unf bin/urlc +bin/urlc.sh +bin/urlc.m4 bin/urlh bin/urlmt bin/uts @@ -140,6 +156,7 @@ git/gitconfig git/gitconfig.m4 gnupg/gpg.conf gnupg/gpg.conf.m4 +include/mktd.m4 man/man7/dotfiles.7df tmux/tmux.conf tmux/tmux.conf.m4 diff --git a/Makefile b/Makefile index 11bcf6f0..8f278325 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ lint-xinit .SUFFIXES: -.SUFFIXES: .awk .bash .mi5 .pl .sed .sh +.SUFFIXES: .awk .bash .m4 .mi5 .pl .sed .sh NAME = 'Tom Ryder' EMAIL = tom@sanctum.geek.nz @@ -217,15 +217,67 @@ clean distclean: rm -f -- \ $(BINS) \ $(GAMES) \ + bin/chn.sh \ + bin/chn.m4 \ + bin/edda.sh \ + bin/edda.m4 \ + bin/pst.sh \ + bin/pst.m4 \ + bin/rndl.sh \ + bin/rndl.m4 \ + bin/swr.sh \ + bin/swr.m4 \ + bin/tlcs.sh \ + bin/tlcs.m4 \ + bin/try.sh \ + bin/try.m4 \ + bin/urlc.sh \ + bin/urlc.m4 \ git/gitconfig \ git/gitconfig.m4 \ gnupg/gpg.conf \ gnupg/gpg.conf.m4 \ + include/mktd.m4 \ man/man8/dotfiles.7df \ tmux/tmux.conf \ tmux/tmux.conf.m4 \ urxvt/ext/select +.awk: + sh bin/shb.sh awk -f < $< > $@ + chmod +x ./$@ + +.bash: + sh bin/shb.sh bash < $< > $@ + chmod +x ./$@ + +.pl: + sh bin/shb.sh perl < $< > $@ + chmod +x ./$@ + +.sed: + sh bin/shb.sh sed -f < $< > $@ + chmod +x ./$@ + +.sh: + sh bin/shb.sh sh < $< > $@ + chmod +x ./$@ + +.mi5.m4: + awk -f bin/mi5.awk < $< > $@ + +.m4.sh: + m4 < $< > $@ + +bin/chn.sh: include/mktd.m4 +bin/edda.sh: include/mktd.m4 +bin/pst.sh: include/mktd.m4 +bin/rndl.sh: include/mktd.m4 +bin/swr.sh: include/mktd.m4 +bin/tlcs.sh: include/mktd.m4 +bin/try.sh: include/mktd.m4 +bin/urlc.sh: include/mktd.m4 + git/gitconfig: git/gitconfig.m4 m4 \ -D DF_NAME=$(NAME) \ @@ -253,29 +305,6 @@ tmux/tmux.conf: tmux/tmux.conf.m4 m4 -D DF_TMUX_BG=$(TMUX_BG) -D DF_TMUX_FG=$(TMUX_FG) \ tmux/tmux.conf.m4 > $@ -.awk: - sh bin/shb.sh awk -f < $< > $@ - chmod +x ./$@ - -.bash: - sh bin/shb.sh bash < $< > $@ - chmod +x ./$@ - -.pl: - sh bin/shb.sh perl < $< > $@ - chmod +x ./$@ - -.sed: - sh bin/shb.sh sed -f < $< > $@ - chmod +x ./$@ - -.sh: - sh bin/shb.sh sh < $< > $@ - chmod +x ./$@ - -.mi5: - awk -f bin/mi5.awk < $< > $@ - install: install-bin \ install-curl \ install-ex \ diff --git a/bin/chn.mi5 b/bin/chn.mi5 new file mode 100644 index 00000000..dfc1000c --- /dev/null +++ b/bin/chn.mi5 @@ -0,0 +1,57 @@ +# Repeat a command to filter input several times +self=chn + +# Check arguments. +if [ "$#" -lt 2 ] ; then + printf >&2 '%s: Need a count and a program name\n' "$self" + exit 2 +fi + +# Shift off the repetition count. +c=$1 +shift + +# Check the repetition count looks sane. Zero is fine! +if [ "$c" -lt 0 ] ; then + printf >&2 '%s: Nonsensical negative count\n' "$self" + exit 2 +fi + +# If the count is zero, just run the input straight through! +if [ "$c" -eq 0 ] ; then + cat + exit +fi + +<% +include(`include/mktd.m4') +%> + +# Define and create input and output files +if=$td/if of=$td/of +touch -- "$if" "$of" + +# Iterate through the count +while [ "${n=1}" -le "$c" ] ; do + + # Start a subshell so we can deal with FDs cleanly + ( + # If this isn't the first iteration, our input comes from $if + [ "$n" -eq 1 ] || + exec <"$if" + + # If this isn't the last iteration, our output goes to $of + [ "$n" -eq "$c" ] || + exec >"$of" + + # Run the command with the descriptors above; if the command fails, the + # subshell will exit, which will in turn exit the program + "$@" + ) || exit + + # Copy the output file over the input one + cp -- "$of" "$if" + + # Increment the counter for the next while loop run + n=$((n+1)) +done diff --git a/bin/chn.sh b/bin/chn.sh deleted file mode 100644 index 9103dd07..00000000 --- a/bin/chn.sh +++ /dev/null @@ -1,69 +0,0 @@ -# Repeat a command to filter input several times -self=chn - -# Check arguments. -if [ "$#" -lt 2 ] ; then - printf >&2 '%s: Need a count and a program name\n' "$self" - exit 2 -fi - -# Shift off the repetition count. -c=$1 -shift - -# Check the repetition count looks sane. Zero is fine! -if [ "$c" -lt 0 ] ; then - printf >&2 '%s: Nonsensical negative count\n' "$self" - exit 2 -fi - -# If the count is zero, just run the input straight through! -if [ "$c" -eq 0 ] ; then - cat - exit -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Define and create input and output files -if=$td/if of=$td/of -touch -- "$if" "$of" - -# Iterate through the count -while [ "${n=1}" -le "$c" ] ; do - - # Start a subshell so we can deal with FDs cleanly - ( - # If this isn't the first iteration, our input comes from $if - [ "$n" -eq 1 ] || - exec <"$if" - - # If this isn't the last iteration, our output goes to $of - [ "$n" -eq "$c" ] || - exec >"$of" - - # Run the command with the descriptors above; if the command fails, the - # subshell will exit, which will in turn exit the program - "$@" - ) || exit - - # Copy the output file over the input one - cp -- "$of" "$if" - - # Increment the counter for the next while loop run - n=$((n+1)) -done diff --git a/bin/edda.mi5 b/bin/edda.mi5 new file mode 100644 index 00000000..aaf974cf --- /dev/null +++ b/bin/edda.mi5 @@ -0,0 +1,21 @@ +# Run ed(1) over multiple files, duplicating stdin. +self=edda + +# Need at least one file +if [ "$#" -eq 0 ] ; then + printf >&2 'edda: Need at least one file\n' + exit 2 +fi + +<% +include(`include/mktd.m4') +%> + +# Duplicate stdin into a file +script=$td/script +cat >"$script" || exit + +# Run ed(1) over each file with the stdin given +for file ; do + ed -- "$file" <"$script" +done diff --git a/bin/edda.sh b/bin/edda.sh deleted file mode 100644 index b1d7b27a..00000000 --- a/bin/edda.sh +++ /dev/null @@ -1,33 +0,0 @@ -# Run ed(1) over multiple files, duplicating stdin. -self=edda - -# Need at least one file -if [ "$#" -eq 0 ] ; then - printf >&2 'edda: Need at least one file\n' - exit 2 -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Duplicate stdin into a file -script=$td/script -cat >"$script" || exit - -# Run ed(1) over each file with the stdin given -for file ; do - ed -- "$file" <"$script" -done diff --git a/bin/pst.mi5 b/bin/pst.mi5 new file mode 100644 index 00000000..34ffbd8c --- /dev/null +++ b/bin/pst.mi5 @@ -0,0 +1,19 @@ +# Interrupt a pipe with manual /dev/tty input to a program +self=pst + +# Don't accept terminal as stdin +if [ -t 0 ] ; then + printf >&2 '%s: stdin is a term\n' "$self" + exit 2 +fi + +<% +include(`include/mktd.m4') +%> + +# Run the interactive command on the temporary file forcing /dev/tty as +# input/output +tf=$td/data +cat - > "$tf" || exit +"${@:-"${PAGER:-more}"}" "$tf" /dev/tty +cat -- "$tf" || exit diff --git a/bin/pst.sh b/bin/pst.sh deleted file mode 100644 index fdea9884..00000000 --- a/bin/pst.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# Interrupt a pipe with manual /dev/tty input to a program -self=pst - -# Don't accept terminal as stdin -if [ -t 0 ] ; then - printf >&2 '%s: stdin is a term\n' "$self" - exit 2 -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Run the interactive command on the temporary file forcing /dev/tty as -# input/output -tf=$td/data -cat - > "$tf" || exit -"${@:-"${PAGER:-more}"}" "$tf" /dev/tty -cat -- "$tf" || exit diff --git a/bin/rndl.mi5 b/bin/rndl.mi5 new file mode 100644 index 00000000..f99ccbea --- /dev/null +++ b/bin/rndl.mi5 @@ -0,0 +1,38 @@ +# Print a random line from input +self=rndl + +# If there are no arguments, we're checking stdin; this is more complicated +# than checking file arguments because we have to count the lines in order to +# correctly choose a random one, and two passes means we require a temporary +# file if we don't want to read all of the input into memory (!) +if [ "$#" -eq 0 ] ; then + +<% +include(`include/mktd.m4') +%> + + # We'll operate on stdin in the temp directory; write the script's stdin to + # it with cat(1) + set -- "$td"/stdin + cat >"$td"/stdin +fi + +# Count the number of lines in the input +lc=$(sed -- '$=;d' "$@") || exit + +# If there were none, bail +case $lc in + ''|0) + printf >&2 'rndl: No lines found on input\n' + exit 2 + ;; +esac + +# Try to get a random seed from rnds(1df) for rndi(1df) +seed=$(rnds) + +# Get a random line number from rndi(1df) +ri=$(rndi 1 "$lc" "$seed") || exit + +# Print the line using sed(1) +sed -- "$ri"'!d' "$@" diff --git a/bin/rndl.sh b/bin/rndl.sh deleted file mode 100644 index 18bcec07..00000000 --- a/bin/rndl.sh +++ /dev/null @@ -1,50 +0,0 @@ -# Print a random line from input -self=rndl - -# If there are no arguments, we're checking stdin; this is more complicated -# than checking file arguments because we have to count the lines in order to -# correctly choose a random one, and two passes means we require a temporary -# file if we don't want to read all of the input into memory (!) -if [ "$#" -eq 0 ] ; then - - # Create a temporary directory with name in $td, and handle POSIX-ish traps to - # remove it when the script exits. - td= - cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi - } - for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" - done - td=$(mktd "$self") || exit - - # We'll operate on stdin in the temp directory; write the script's stdin to - # it with cat(1) - set -- "$td"/stdin - cat >"$td"/stdin -fi - -# Count the number of lines in the input -lc=$(sed -- '$=;d' "$@") || exit - -# If there were none, bail -case $lc in - ''|0) - printf >&2 'rndl: No lines found on input\n' - exit 2 - ;; -esac - -# Try to get a random seed from rnds(1df) for rndi(1df) -seed=$(rnds) - -# Get a random line number from rndi(1df) -ri=$(rndi 1 "$lc" "$seed") || exit - -# Print the line using sed(1) -sed -- "$ri"'!d' "$@" diff --git a/bin/swr.mi5 b/bin/swr.mi5 new file mode 100644 index 00000000..9b73b6d6 --- /dev/null +++ b/bin/swr.mi5 @@ -0,0 +1,52 @@ +# Transparently wrap scp(1) targets to read (not write) on the command line +self=swr + +<% +include(`include/mktd.m4') +%> + +# Set a flag to manage resetting the positional parameters at the start of the +# loop +n=1 +for arg ; do + + # If this is our first iteration, reset the shell parameters + case $n in + 1) set -- ;; + esac + + # Test whether this argument looks like a remote file + if ( + + # Test it contains a colon + case $arg in + *:*) ;; + *) exit 1 ;; + esac + + # Test the part before the first colon has at least one character and + # only hostname characters + case ${arg%%:*} in + '') exit 1 ;; + *[!a-zA-Z0-9-.]*) exit 1 ;; + esac + + ) ; then + + # Looks like a remote file request; try to copy it into the temporary + # directory, bail out completely if we can't + dst=$td/$n + scp -q -- "$arg" "$dst" || exit + set -- "$@" "$dst" + + else + # Just a plain old argument; stack it up + set -- "$@" "$arg" + fi + + # Bump n + n=$((n+1)) +done + +# Run the command with the processed arguments +exec "$@" diff --git a/bin/swr.sh b/bin/swr.sh deleted file mode 100644 index 5bad63ae..00000000 --- a/bin/swr.sh +++ /dev/null @@ -1,64 +0,0 @@ -# Transparently wrap scp(1) targets to read (not write) on the command line -self=swr - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Set a flag to manage resetting the positional parameters at the start of the -# loop -n=1 -for arg ; do - - # If this is our first iteration, reset the shell parameters - case $n in - 1) set -- ;; - esac - - # Test whether this argument looks like a remote file - if ( - - # Test it contains a colon - case $arg in - *:*) ;; - *) exit 1 ;; - esac - - # Test the part before the first colon has at least one character and - # only hostname characters - case ${arg%%:*} in - '') exit 1 ;; - *[!a-zA-Z0-9-.]*) exit 1 ;; - esac - - ) ; then - - # Looks like a remote file request; try to copy it into the temporary - # directory, bail out completely if we can't - dst=$td/$n - scp -q -- "$arg" "$dst" || exit - set -- "$@" "$dst" - - else - # Just a plain old argument; stack it up - set -- "$@" "$arg" - fi - - # Bump n - n=$((n+1)) -done - -# Run the command with the processed arguments -exec "$@" diff --git a/bin/tlcs.mi5 b/bin/tlcs.mi5 new file mode 100644 index 00000000..a3e17c82 --- /dev/null +++ b/bin/tlcs.mi5 @@ -0,0 +1,81 @@ +# Execute a command and tag the output of the stdout and stderr streams. +self=tlcs + +# Set the default prefixes and suffixes for stdout/err +out_pref='stdout: ' +err_pref='stderr: ' +out_suff= +err_suff= + +# Parse options out, give help if necessary +while getopts 'co:e:' opt ; do + case $opt in + c) + color=1 + ;; + o) + out_pref=$OPTARG + ;; + e) + err_pref=$OPTARG + ;; + \?) + printf >&2 'Unknown option %s\n' "$opt" + exit 2 + ;; + esac +done +shift "$((OPTIND-1))" + +# We need at least one more argument +if [ "$#" -eq 0 ] ; then + printf >&2 '%s: Need a command to run\n' "$self" + exit 2 +fi + +# If color was requested for the output, try and get a count of available +# colors; otherwise default to zero +[ -n "$color" ] && color_count=$( { + tput colors || tput Co +} 2>/dev/null ) +: "${color_count:=0}" + +# If the color count is 8 or greater, we'll color the output +if [ "$((color_count >= 8))" -eq 1 ] ; then + + # Color code for resetting + color_reset=$( { + tput me || tput sgr0 + } 2>/dev/null ) + + # If stdout is a terminal, color it + if [ -t 1 ] ; then + color_stdout=$( { + tput AF 2 || tput setaf 2 + } 2>/dev/null ) + out_pref=${color_stdout}${out_pref} + out_suff=${out_suff}${color_reset} + fi + + # If stderr is a terminal, color it + if [ -t 2 ] ; then + color_stderr=$( { + tput AF 1 || tput setaf 1 + } 2>/dev/null ) + err_pref=${color_stderr}${err_pref} + out_suff=${err_suff}${color_reset} + fi +fi + +<% +include(`include/mktd.m4') +%> + +# Execute the command, passing stdout and stderr to tl(1df) calls as appropriate +# via named pipes +out=$td/out err=$td/err +mkfifo -- "$out" "$err" || exit +tl -p "$out_pref" -s "$out_suff" < "$out" & +tl -p "$err_pref" -s "$err_suff" < "$err" & +"$@" >"$out" 2>"$err" +ex=$? ; wait ; exit "$ex" diff --git a/bin/tlcs.sh b/bin/tlcs.sh deleted file mode 100644 index f20b160e..00000000 --- a/bin/tlcs.sh +++ /dev/null @@ -1,93 +0,0 @@ -# Execute a command and tag the output of the stdout and stderr streams. -self=tlcs - -# Set the default prefixes and suffixes for stdout/err -out_pref='stdout: ' -err_pref='stderr: ' -out_suff= -err_suff= - -# Parse options out, give help if necessary -while getopts 'co:e:' opt ; do - case $opt in - c) - color=1 - ;; - o) - out_pref=$OPTARG - ;; - e) - err_pref=$OPTARG - ;; - \?) - printf >&2 'Unknown option %s\n' "$opt" - exit 2 - ;; - esac -done -shift "$((OPTIND-1))" - -# We need at least one more argument -if [ "$#" -eq 0 ] ; then - printf >&2 '%s: Need a command to run\n' "$self" - exit 2 -fi - -# If color was requested for the output, try and get a count of available -# colors; otherwise default to zero -[ -n "$color" ] && color_count=$( { - tput colors || tput Co -} 2>/dev/null ) -: "${color_count:=0}" - -# If the color count is 8 or greater, we'll color the output -if [ "$((color_count >= 8))" -eq 1 ] ; then - - # Color code for resetting - color_reset=$( { - tput me || tput sgr0 - } 2>/dev/null ) - - # If stdout is a terminal, color it - if [ -t 1 ] ; then - color_stdout=$( { - tput AF 2 || tput setaf 2 - } 2>/dev/null ) - out_pref=${color_stdout}${out_pref} - out_suff=${out_suff}${color_reset} - fi - - # If stderr is a terminal, color it - if [ -t 2 ] ; then - color_stderr=$( { - tput AF 1 || tput setaf 1 - } 2>/dev/null ) - err_pref=${color_stderr}${err_pref} - out_suff=${err_suff}${color_reset} - fi -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Execute the command, passing stdout and stderr to tl(1df) calls as appropriate -# via named pipes -out=$td/out err=$td/err -mkfifo -- "$out" "$err" || exit -tl -p "$out_pref" -s "$out_suff" < "$out" & -tl -p "$err_pref" -s "$err_suff" < "$err" & -"$@" >"$out" 2>"$err" -ex=$? ; wait ; exit "$ex" diff --git a/bin/try.mi5 b/bin/try.mi5 new file mode 100644 index 00000000..ea39d717 --- /dev/null +++ b/bin/try.mi5 @@ -0,0 +1,65 @@ +# Attempt a certain number of times to perform a task, buffer stderr unless and +# until all command attempts fail +self=try + +# Parse options +while getopts 's:n:' opt ; do + case $opt in + n) + attn=$OPTARG + ;; + s) + sleep=$OPTARG + ;; + \?) + printf >&2 '%s: Unknown option\n' "$self" + exit 2 + ;; + esac +done +shift "$((OPTIND-1))" + +# Check we have at least one argument left (the command to run) +if [ "$#" -eq 0 ] ; then + printf >&2 '%s: Need a command to run\n' "$self" + exit 2 +fi + +<% +include(`include/mktd.m4') +%> + +# Open a filehandle to the error buffer, just to save on file operations +errbuff=$td/errbuff +exec 3>"$errbuff" + +# Keep trying the command, writing error output to the buffer file, and exit +# if we succeed on any of them +attc=1 +: "${attn:=3}" "${sleep:=0}" +while [ "$attc" -le "$attn" ] ; do + + # Try running the command; if it succeeds, we're done, and any previous + # failures get their errors discarded + if "$@" 2>&3 ; then + exit + + # If the command failed, record the exit value + else + ex=$? + fi + + # If this isn't the last run, have a sleep + if [ "$attc" -lt "$attn" ] ; then + sleep "${sleep:=0}" + fi + + # Increment the attempt count + attc=$((attc + 1)) +done + +# Attempts were exhausted, and all failed; print the error output from all of +# the failures and exit with the non-zero exit value of the most recent one +exec 3>&- +cat -- "$td"/errbuff >&2 +exit "$ex" diff --git a/bin/try.sh b/bin/try.sh deleted file mode 100644 index 20ccbe5f..00000000 --- a/bin/try.sh +++ /dev/null @@ -1,77 +0,0 @@ -# Attempt a certain number of times to perform a task, buffer stderr unless and -# until all command attempts fail -self=try - -# Parse options -while getopts 's:n:' opt ; do - case $opt in - n) - attn=$OPTARG - ;; - s) - sleep=$OPTARG - ;; - \?) - printf >&2 '%s: Unknown option\n' "$self" - exit 2 - ;; - esac -done -shift "$((OPTIND-1))" - -# Check we have at least one argument left (the command to run) -if [ "$#" -eq 0 ] ; then - printf >&2 '%s: Need a command to run\n' "$self" - exit 2 -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Open a filehandle to the error buffer, just to save on file operations -errbuff=$td/errbuff -exec 3>"$errbuff" - -# Keep trying the command, writing error output to the buffer file, and exit -# if we succeed on any of them -attc=1 -: "${attn:=3}" "${sleep:=0}" -while [ "$attc" -le "$attn" ] ; do - - # Try running the command; if it succeeds, we're done, and any previous - # failures get their errors discarded - if "$@" 2>&3 ; then - exit - - # If the command failed, record the exit value - else - ex=$? - fi - - # If this isn't the last run, have a sleep - if [ "$attc" -lt "$attn" ] ; then - sleep "${sleep:=0}" - fi - - # Increment the attempt count - attc=$((attc + 1)) -done - -# Attempts were exhausted, and all failed; print the error output from all of -# the failures and exit with the non-zero exit value of the most recent one -exec 3>&- -cat -- "$td"/errbuff >&2 -exit "$ex" diff --git a/bin/urlc.mi5 b/bin/urlc.mi5 new file mode 100644 index 00000000..55dac171 --- /dev/null +++ b/bin/urlc.mi5 @@ -0,0 +1,64 @@ +# Try to find erroneous or insecure URLs +self=urlc + +# cURL request timeout +tm=${URLCHECK_TIMEOUT:-8} + +<% +include(`include/mktd.m4') +%> + +# Create buffer files for the headers and body content, to be cleaned up on +# exit +list=$td/list head=$td/head body=$td/body + +# Iterate through input; ignore leading/trailing whitespace +cat -- "${@:--}" >"$list" +while read -r url ; do + + # Skip anything that doesn't start with HTTP + case $url in + http*) ;; + *) continue ;; + esac + + # Make initial request, log head and body to files, cry and skip on error + if ! curl -A Mozilla -fHLsS -D "$head" -m "$tm" -o "$body" -- \ + "$url" ; then + printf >&2 '%s: %s raises error\n' \ + "$self" "$url" + ex=1 + continue + fi + + # Iterate through header file, cry about the first redirect we find + while IFS=': ' read -r header value ; do + [ "$header" = 'Location' ] || continue + printf >&2 '%s: %s redirects to %s\n' \ + "$self" "$url" "$value" >&2 + ex=1 + break + done < "$head" + + # Skip anything that's already secure + case $url in + https*) continue ;; + *) ;; + esac + + # Form a naïve attempt at a possible secure URL and try to request it, + # point it out if it actually works + surl=https://${url#http://} + if curl -A Mozilla -fLsS -D "$head" -m "$tm" -o "$body" -- \ + "$surl" 2>/dev/null ; then + printf >&2 '%s: %s has a working secure version at %s\n' \ + "$self" "$url" "$surl" + ex=1 + fi +done <"$list" + +# Wait for the input process to finish +wait + +# Exit if any errors +exit "${ex:-0}" diff --git a/bin/urlc.sh b/bin/urlc.sh deleted file mode 100644 index 0e6530fa..00000000 --- a/bin/urlc.sh +++ /dev/null @@ -1,76 +0,0 @@ -# Try to find erroneous or insecure URLs -self=urlc - -# cURL request timeout -tm=${URLCHECK_TIMEOUT:-8} - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Create buffer files for the headers and body content, to be cleaned up on -# exit -list=$td/list head=$td/head body=$td/body - -# Iterate through input; ignore leading/trailing whitespace -cat -- "${@:--}" >"$list" -while read -r url ; do - - # Skip anything that doesn't start with HTTP - case $url in - http*) ;; - *) continue ;; - esac - - # Make initial request, log head and body to files, cry and skip on error - if ! curl -A Mozilla -fHLsS -D "$head" -m "$tm" -o "$body" -- \ - "$url" ; then - printf >&2 '%s: %s raises error\n' \ - "$self" "$url" - ex=1 - continue - fi - - # Iterate through header file, cry about the first redirect we find - while IFS=': ' read -r header value ; do - [ "$header" = 'Location' ] || continue - printf >&2 '%s: %s redirects to %s\n' \ - "$self" "$url" "$value" >&2 - ex=1 - break - done < "$head" - - # Skip anything that's already secure - case $url in - https*) continue ;; - *) ;; - esac - - # Form a naïve attempt at a possible secure URL and try to request it, - # point it out if it actually works - surl=https://${url#http://} - if curl -A Mozilla -fLsS -D "$head" -m "$tm" -o "$body" -- \ - "$surl" 2>/dev/null ; then - printf >&2 '%s: %s has a working secure version at %s\n' \ - "$self" "$url" "$surl" - ex=1 - fi -done <"$list" - -# Wait for the input process to finish -wait - -# Exit if any errors -exit "${ex:-0}" diff --git a/git/gitconfig.m4.mi5 b/git/gitconfig.m4.mi5 deleted file mode 100644 index bce64d6c..00000000 --- a/git/gitconfig.m4.mi5 +++ /dev/null @@ -1,64 +0,0 @@ -[advice] - statusHints = false - detachedHead = false - implicitIdentity = false - pushUpdateRejected = false - -[alias] - amend = commit --amend - ls = log --oneline - others = ls-files --others --exclude-standard - fuckit = "!git clean -dfx ; git reset --hard" - -[color] - ui = true - -[commit] - status = false - -[core] - compression = 9 - -[diff] - algorithm = patience - tool = vimdiff - -[difftool] - prompt = false - -[fetch] - output = compact - prune = true - -[grep] - extendRegexp = true - lineNumber = true - -[log] - date = local - decorate = short - -[merge] - ff = false - -[pager] - diff = cat - -[pull] - ff = only - -[push] - default = current - -[sendemail] - confirm = compose - smtpServer = <% DF_SENDMAIL %> - -[status] - short = true - showUntrackedFiles = all - -[user] - name = <% DF_NAME %> - email = <% DF_EMAIL %> - signingKey = <% DF_KEY %> diff --git a/git/gitconfig.mi5 b/git/gitconfig.mi5 new file mode 100644 index 00000000..bce64d6c --- /dev/null +++ b/git/gitconfig.mi5 @@ -0,0 +1,64 @@ +[advice] + statusHints = false + detachedHead = false + implicitIdentity = false + pushUpdateRejected = false + +[alias] + amend = commit --amend + ls = log --oneline + others = ls-files --others --exclude-standard + fuckit = "!git clean -dfx ; git reset --hard" + +[color] + ui = true + +[commit] + status = false + +[core] + compression = 9 + +[diff] + algorithm = patience + tool = vimdiff + +[difftool] + prompt = false + +[fetch] + output = compact + prune = true + +[grep] + extendRegexp = true + lineNumber = true + +[log] + date = local + decorate = short + +[merge] + ff = false + +[pager] + diff = cat + +[pull] + ff = only + +[push] + default = current + +[sendemail] + confirm = compose + smtpServer = <% DF_SENDMAIL %> + +[status] + short = true + showUntrackedFiles = all + +[user] + name = <% DF_NAME %> + email = <% DF_EMAIL %> + signingKey = <% DF_KEY %> diff --git a/gnupg/gpg.conf.m4.mi5 b/gnupg/gpg.conf.m4.mi5 deleted file mode 100644 index d8f14c09..00000000 --- a/gnupg/gpg.conf.m4.mi5 +++ /dev/null @@ -1,52 +0,0 @@ -# Retrieve certs automatically if possible -auto-key-locate cert pka - -# Prevent boilerplate about needing key decryption, which is handled by the -# agent; the gpg function in my Bash scripts overrides this for certain -# commands where it interferes -batch - -# Use SHA512 as the hash when making key signatures -cert-digest-algo SHA512 - -# Specify the hash algorithms to be used for new keys as available -default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed - -# In the absence of any other recipient, encrypt messages for myself -default-recipient-self - -# Show complete dates and use proper column separation for --with-colon listing mode -fixed-list-mode - -# Use 16-character key IDs as the default 8-character key IDs can be forged -keyid-format 0xlong - -# Use a pool of servers which support HKPS (encrypted key retrieval) -keyserver DF_KEYSERVER - -# Retrieve keys automatically; check the keyserver port cert; use whichever -# server is proffered from the pool -keyserver-options auto-key-retrieve check-cert no-honor-keyserver-url ca-certfile=<% DF_HOME %>/.gnupg/sks-keyservers.net/sks-keyservers.netCA.pem - -# Include trust/validity for UIDs in listings -list-options show-uid-validity - -# Suppress the copyright message -no-greeting - -# Use SHA512 as my message digest, overriding GnuPG's efforts to use the lowest -# common denominator in hashing algorithms -personal-digest-preferences SHA512 - -# Suppress a lot of output; sometimes I add --verbose to undo this -quiet - -# Use the GPG agent for key management and decryption -use-agent - -# Include trust/validity for UIDs when verifying signatures -verify-options pka-lookups show-uid-validity - -# Assume "yes" is the answer to most questions, that is, don't keep asking me -# to confirm something I've asked to be done -yes diff --git a/gnupg/gpg.conf.mi5 b/gnupg/gpg.conf.mi5 new file mode 100644 index 00000000..d8f14c09 --- /dev/null +++ b/gnupg/gpg.conf.mi5 @@ -0,0 +1,52 @@ +# Retrieve certs automatically if possible +auto-key-locate cert pka + +# Prevent boilerplate about needing key decryption, which is handled by the +# agent; the gpg function in my Bash scripts overrides this for certain +# commands where it interferes +batch + +# Use SHA512 as the hash when making key signatures +cert-digest-algo SHA512 + +# Specify the hash algorithms to be used for new keys as available +default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed + +# In the absence of any other recipient, encrypt messages for myself +default-recipient-self + +# Show complete dates and use proper column separation for --with-colon listing mode +fixed-list-mode + +# Use 16-character key IDs as the default 8-character key IDs can be forged +keyid-format 0xlong + +# Use a pool of servers which support HKPS (encrypted key retrieval) +keyserver DF_KEYSERVER + +# Retrieve keys automatically; check the keyserver port cert; use whichever +# server is proffered from the pool +keyserver-options auto-key-retrieve check-cert no-honor-keyserver-url ca-certfile=<% DF_HOME %>/.gnupg/sks-keyservers.net/sks-keyservers.netCA.pem + +# Include trust/validity for UIDs in listings +list-options show-uid-validity + +# Suppress the copyright message +no-greeting + +# Use SHA512 as my message digest, overriding GnuPG's efforts to use the lowest +# common denominator in hashing algorithms +personal-digest-preferences SHA512 + +# Suppress a lot of output; sometimes I add --verbose to undo this +quiet + +# Use the GPG agent for key management and decryption +use-agent + +# Include trust/validity for UIDs when verifying signatures +verify-options pka-lookups show-uid-validity + +# Assume "yes" is the answer to most questions, that is, don't keep asking me +# to confirm something I've asked to be done +yes diff --git a/include/mktd.mi5 b/include/mktd.mi5 new file mode 100644 index 00000000..388eb9be --- /dev/null +++ b/include/mktd.mi5 @@ -0,0 +1,15 @@ +# Create a temporary directory with name in $td, and handle POSIX-ish traps to +# remove it when the script exits. +td= +cleanup() { + [ -n "$td" ] && rm -fr -- "$td" + if [ "$1" != EXIT ] ; then + trap - "$1" + kill "-$1" "$$" + fi +} +for sig in EXIT HUP INT TERM ; do + # shellcheck disable=SC2064 + trap "cleanup $sig" "$sig" +done +td=$(mktd "$self") || exit diff --git a/tmux/tmux.conf.m4.mi5 b/tmux/tmux.conf.m4.mi5 deleted file mode 100644 index 76d493c1..00000000 --- a/tmux/tmux.conf.m4.mi5 +++ /dev/null @@ -1,130 +0,0 @@ -# Strip out a lot of machine and X11 dependent crap from the initial -# environment -set-environment -gru COLORFGBG -set-environment -gru COLORTERM -set-environment -gru DISPLAY -set-environment -gru SSH_CLIENT -set-environment -gru SSH_CONNECTION -set-environment -gru SSH_TTY -set-environment -gru WINDOWID - -# Otherwise, use the environment we had when we started; don't touch it during -# a session unless I specifically ask -set-option -g update-environment '' - -# Setting this makes each new pane a non-login shell, which suits me better -set-option -g default-command "$SHELL" - -# Expect a 256-color terminal -set-option -g default-terminal 'screen-256color' - -# Change the prefix to ^A rather than the default of ^B, because I'm a godless -# GNU Screen refugee, and also I like using ^B in my shell and in Vim more -unbind-key C-b -set-option -g prefix C-a -bind-key a send-prefix - -# Repeating the prefix switches to the last window and back, a GNU Screen -# feature that's hardwired into my brain now -bind-key C-a last-window - -# Quick ways to kill single windows and the whole server -bind-key '/' confirm-before 'kill-window' -bind-key '\' confirm-before 'kill-server' - -# Slightly more intuitive way to split windows -bind-key '_' split-window -v -bind-key '|' split-window -h - -# Switch to the last active pane -bind-key Tab last-pane - -# Use the vi mode for tmux interaction behaviour in copy and choice modes -set-window-option -g mode-keys vi -bind-key -T copy-mode-vi v send -X begin-selection -bind-key -T copy-mode-vi y send -X copy-selection-and-cancel - -# Detach with Alt-M, no prefix required -bind-key -n M-m detach - -# Vim-like pane resizing -bind-key -r '+' resize-pane -U 5 -bind-key -r '-' resize-pane -D 5 -bind-key -r '<' resize-pane -L 5 -bind-key -r '>' resize-pane -R 5 - -# Vim-like pane switching -bind-key h select-pane -L -bind-key j select-pane -D -bind-key k select-pane -U -bind-key l select-pane -R - -# Join and break panes -bind-key J choose-window "join-pane -h -s '%%'" -bind-key B break-pane -d - -# Select only sessions in the choose-tree menu, not the whole tree of sessions -# and windows, I prefer to drill down -bind-key s choose-session - -# Session title on the left side of the status bar -set-option -g status-left '[#S] ' - -# Username, hostname, and the current date on the right side of the status bar -set-option -g status-right ' [#(whoami)@#H] #(date +"%F %T")' - -# Update the status bar every second -set-option -g status-interval 1 - -# The first window in a session has index 1, rather than 0 -set-option -g base-index 1 - -# Don't worry about timeouts for key combinations, as I don't use Escape as -# meta and prefer things to be snappier -set-option -g escape-time 0 - -# Keep plenty of history -set-option -g history-limit 100000 - -# Don't interfere with my system clipboard -set-option -g set-clipboard off - -# Only force individual windows to the smallest attached terminal size, not -# whole sessions -set-window-option -g aggressive-resize on - -# If I don't set a title on a window, use the program name for the window title -set-window-option -g automatic-rename on - -# However, don't let terminal escape sequences rename my windows -set-window-option -g allow-rename off - -# Window titles are the window index, a colon, the window or command name, and -# any activity or alert indicators -set-window-option -g window-status-format "#I:#W#F" - -# Message dialogs are white on blue -set-option -g message-style "bg=colour18,fg=colour231" - -# Window choosers are white on blue -set-window-option -g mode-style "bg=colour18,fg=colour231" - -# Pane borders are always in the background color -set-option -g pane-border-style "fg=<% DF_TMUX_BG %>" -set-option -g pane-active-border-style "fg=<% DF_TMUX_BG %>" - -# Inactive windows have slightly washed-out system colours -set-option -g window-style "bg=colour232,fg=colour248" -set-option -g window-active-style "bg=colour0,fg=colour15" - -# The status bar has the defined background and foreground colours -set-option -g status-style "bg=<% DF_TMUX_BG %>,fg=<% DF_TMUX_FG %>" - -# Titles of windows default to black text with no embellishment -set-window-option -g window-status-style "fg=colour16" - -# The title of the active window is in white rather than black -set-window-option -g window-status-current-style "fg=colour231" - -# A window with a bell has a title with a red background until cleared -set-window-option -g window-status-bell-style "bg=colour9" diff --git a/tmux/tmux.conf.mi5 b/tmux/tmux.conf.mi5 new file mode 100644 index 00000000..76d493c1 --- /dev/null +++ b/tmux/tmux.conf.mi5 @@ -0,0 +1,130 @@ +# Strip out a lot of machine and X11 dependent crap from the initial +# environment +set-environment -gru COLORFGBG +set-environment -gru COLORTERM +set-environment -gru DISPLAY +set-environment -gru SSH_CLIENT +set-environment -gru SSH_CONNECTION +set-environment -gru SSH_TTY +set-environment -gru WINDOWID + +# Otherwise, use the environment we had when we started; don't touch it during +# a session unless I specifically ask +set-option -g update-environment '' + +# Setting this makes each new pane a non-login shell, which suits me better +set-option -g default-command "$SHELL" + +# Expect a 256-color terminal +set-option -g default-terminal 'screen-256color' + +# Change the prefix to ^A rather than the default of ^B, because I'm a godless +# GNU Screen refugee, and also I like using ^B in my shell and in Vim more +unbind-key C-b +set-option -g prefix C-a +bind-key a send-prefix + +# Repeating the prefix switches to the last window and back, a GNU Screen +# feature that's hardwired into my brain now +bind-key C-a last-window + +# Quick ways to kill single windows and the whole server +bind-key '/' confirm-before 'kill-window' +bind-key '\' confirm-before 'kill-server' + +# Slightly more intuitive way to split windows +bind-key '_' split-window -v +bind-key '|' split-window -h + +# Switch to the last active pane +bind-key Tab last-pane + +# Use the vi mode for tmux interaction behaviour in copy and choice modes +set-window-option -g mode-keys vi +bind-key -T copy-mode-vi v send -X begin-selection +bind-key -T copy-mode-vi y send -X copy-selection-and-cancel + +# Detach with Alt-M, no prefix required +bind-key -n M-m detach + +# Vim-like pane resizing +bind-key -r '+' resize-pane -U 5 +bind-key -r '-' resize-pane -D 5 +bind-key -r '<' resize-pane -L 5 +bind-key -r '>' resize-pane -R 5 + +# Vim-like pane switching +bind-key h select-pane -L +bind-key j select-pane -D +bind-key k select-pane -U +bind-key l select-pane -R + +# Join and break panes +bind-key J choose-window "join-pane -h -s '%%'" +bind-key B break-pane -d + +# Select only sessions in the choose-tree menu, not the whole tree of sessions +# and windows, I prefer to drill down +bind-key s choose-session + +# Session title on the left side of the status bar +set-option -g status-left '[#S] ' + +# Username, hostname, and the current date on the right side of the status bar +set-option -g status-right ' [#(whoami)@#H] #(date +"%F %T")' + +# Update the status bar every second +set-option -g status-interval 1 + +# The first window in a session has index 1, rather than 0 +set-option -g base-index 1 + +# Don't worry about timeouts for key combinations, as I don't use Escape as +# meta and prefer things to be snappier +set-option -g escape-time 0 + +# Keep plenty of history +set-option -g history-limit 100000 + +# Don't interfere with my system clipboard +set-option -g set-clipboard off + +# Only force individual windows to the smallest attached terminal size, not +# whole sessions +set-window-option -g aggressive-resize on + +# If I don't set a title on a window, use the program name for the window title +set-window-option -g automatic-rename on + +# However, don't let terminal escape sequences rename my windows +set-window-option -g allow-rename off + +# Window titles are the window index, a colon, the window or command name, and +# any activity or alert indicators +set-window-option -g window-status-format "#I:#W#F" + +# Message dialogs are white on blue +set-option -g message-style "bg=colour18,fg=colour231" + +# Window choosers are white on blue +set-window-option -g mode-style "bg=colour18,fg=colour231" + +# Pane borders are always in the background color +set-option -g pane-border-style "fg=<% DF_TMUX_BG %>" +set-option -g pane-active-border-style "fg=<% DF_TMUX_BG %>" + +# Inactive windows have slightly washed-out system colours +set-option -g window-style "bg=colour232,fg=colour248" +set-option -g window-active-style "bg=colour0,fg=colour15" + +# The status bar has the defined background and foreground colours +set-option -g status-style "bg=<% DF_TMUX_BG %>,fg=<% DF_TMUX_FG %>" + +# Titles of windows default to black text with no embellishment +set-window-option -g window-status-style "fg=colour16" + +# The title of the active window is in white rather than black +set-window-option -g window-status-current-style "fg=colour231" + +# A window with a bell has a title with a red background until cleared +set-window-option -g window-status-bell-style "bg=colour9" -- cgit v1.2.3 From 54e85f42174610a0aaf29a4912c22bb8d7a4f742 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Jun 2017 22:08:15 +1200 Subject: Remove lies from mi5 The second pass of the evaluator confounded me --- bin/mi5.awk | 3 --- man/man1/mi5.1df | 8 +------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/bin/mi5.awk b/bin/mi5.awk index c05955ff..32bac6e9 100644 --- a/bin/mi5.awk +++ b/bin/mi5.awk @@ -33,9 +33,6 @@ mac { # Don't let apostrophes close the comment gsub(/'/, "''`") - # Don't let $ signs confound expansion - gsub(/\$/, "$'`") - # Replace m5 opener with m4 closer gsub(/<% */, "'") diff --git a/man/man1/mi5.1df b/man/man1/mi5.1df index b56bed93..7fb41078 100644 --- a/man/man1/mi5.1df +++ b/man/man1/mi5.1df @@ -50,13 +50,7 @@ very simple macro expansion in an mi5 inline. .SH CAVEATS Only very simple macro expansions work in inline calls at the moment. This can be fixed by the author tokenizing the line properly, which he'll do Real Soon -Now (TM). Specifically, neither quote delimiters nor macro parameters work. -The latter is because of a nasty corner-case in m4 where parameter expansions -$1, $2, $*, etc are expanded -.B even within quotes, -one of m4's darkest corners. The workaround is to do as much logic as you can -in a block, defining your result as a single simple macros, and then expanding -that inline. +Now (TM). Specifically, quote delimiters do not work. .SH SEE ALSO bp(1df), xargs(1) .SH AUTHOR -- cgit v1.2.3