aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION4
-rw-r--r--bash/bash_completion.d/_ssh_config_hosts.bash43
-rw-r--r--bash/bash_completion.d/git.bash41
-rw-r--r--bash/bash_completion.d/gpg.bash13
-rw-r--r--bash/bash_completion.d/make.bash2
-rw-r--r--bash/bash_completion.d/man.bash1
-rw-r--r--bash/bash_completion.d/mex.bash2
-rw-r--r--bash/bash_completion.d/openssl.bash29
-rw-r--r--bash/bash_completion.d/pass.bash2
-rw-r--r--bash/bash_completion.d/path.bash2
-rw-r--r--bash/bashrc2
-rw-r--r--bash/bashrc.d/keep.bash2
-rw-r--r--bash/bashrc.d/vared.bash2
-rw-r--r--bin/ap.sh2
-rw-r--r--bin/apf.sh2
-rw-r--r--bin/d2u.sh2
-rw-r--r--bin/eds.sh4
-rw-r--r--bin/fnp.sh2
-rw-r--r--bin/loc.sh2
-rw-r--r--bin/mex.sh2
-rw-r--r--bin/mkcp.sh2
-rw-r--r--bin/mked.sh2
-rw-r--r--bin/mkmv.sh2
-rw-r--r--bin/mkvi.sh2
-rw-r--r--bin/pp.sh2
-rw-r--r--bin/sqs.sh2
-rw-r--r--bin/stbl.sh2
-rw-r--r--bin/stex.sh2
-rw-r--r--bin/stws.sh2
-rw-r--r--bin/sue.sh2
-rw-r--r--bin/u2d.sh2
-rw-r--r--bin/xgo.sh2
-rw-r--r--check/bash.sh2
-rw-r--r--check/ksh.sh2
-rw-r--r--check/sh.sh2
-rw-r--r--check/xinit.sh2
-rw-r--r--check/zsh.sh2
-rw-r--r--ksh/kshrc.d/keep.ksh2
-rw-r--r--readline/inputrc6
-rw-r--r--sh/profile12
-rw-r--r--sh/profile.d/downloads.sh6
-rw-r--r--sh/profile.d/options.sh7
-rw-r--r--sh/profile.d/welcome.sh10
-rw-r--r--sh/shinit9
-rw-r--r--sh/shrc4
-rw-r--r--sh/shrc.d/bc.sh3
-rw-r--r--sh/shrc.d/ed.sh6
-rw-r--r--sh/shrc.d/grep.sh20
-rw-r--r--sh/shrc.d/gt.sh4
-rw-r--r--sh/shrc.d/ls.sh36
-rw-r--r--sh/shrc.d/mkcd.sh3
-rw-r--r--sh/shrc.d/path.sh33
-rw-r--r--sh/shrc.d/tree.sh2
-rw-r--r--sh/shrc.d/vr.sh11
-rw-r--r--vim/autoload/filetype.vim76
-rw-r--r--vim/filetype.vim81
-rw-r--r--zsh/profile.d/zsh.sh25
-rw-r--r--zsh/zshrc.d/keep.zsh2
58 files changed, 314 insertions, 239 deletions
diff --git a/VERSION b/VERSION
index 63c62745..2a431fea 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
-tejr dotfiles v3.1.0
-Wed Dec 5 22:40:16 UTC 2018
+tejr dotfiles v3.2.0
+Fri Dec 14 00:14:00 UTC 2018
diff --git a/bash/bash_completion.d/_ssh_config_hosts.bash b/bash/bash_completion.d/_ssh_config_hosts.bash
index 3f937a2a..0959f52b 100644
--- a/bash/bash_completion.d/_ssh_config_hosts.bash
+++ b/bash/bash_completion.d/_ssh_config_hosts.bash
@@ -1,31 +1,26 @@
# Complete ssh_config(5) hostnames
_ssh_config_hosts() {
- # Iterate through words from a subshell
- local ci comp
- while read -r comp ; do
- COMPREPLY[ci++]=$comp
- done < <(
+ # Iterate through SSH client config paths
+ local config
+ for config in "$HOME"/.ssh/config /etc/ssh/ssh_config ; do
+ [[ -e $config ]] || continue
- # Iterate through SSH client config paths
- for config in "$HOME"/.ssh/config /etc/ssh/ssh_config ; do
- [[ -e $config ]] || continue
+ # Read 'Host' options and their first value from file
+ local option value ci
+ while read -r option value _ ; do
+ [[ $option == Host ]] || continue
- # Read 'Host' options and their first value from file
- while read -r option value _ ; do
- [[ $option == Host ]] || continue
+ # Check host value
+ case $value in
+ # No empties
+ '') ;;
+ # No wildcards
+ *'*'*) ;;
+ # Found a match; print it
+ "$2"*) COMPREPLY[ci++]=$value ;;
+ esac
- # Check host value
- case $value in
- # No empties
- ('') ;;
- # No wildcards
- (*'*'*) ;;
- # Found a match; print it
- ("$2"*) printf '%s\n' "$value" ;;
- esac
-
- done < "$config"
- done
- )
+ done < "$config"
+ done
}
diff --git a/bash/bash_completion.d/git.bash b/bash/bash_completion.d/git.bash
new file mode 100644
index 00000000..c3a4d49c
--- /dev/null
+++ b/bash/bash_completion.d/git.bash
@@ -0,0 +1,41 @@
+# Complete Git with branch names or tag names if specific keys are used, but
+# fall back on filenames otherwise; it's too complicated to be worth trying to
+# do it all contextually
+
+# Requires Bash >=4.0 for COMP_KEY
+((BASH_VERSINFO[0] >= 4)) || return
+
+# Define and set helper function
+_git() {
+
+ # What completion to do
+ case $COMP_KEY in
+
+ # Complete with branch names if C-x,B is pressed
+ 98)
+ local ci
+ while read -r _ ref ; do
+ branch=${ref#refs/heads/}
+ case $branch in
+ "$2"*) COMPREPLY[ci++]=$branch ;;
+ esac
+ done < <(git show-ref --heads)
+ ;;
+
+ # Complete with tag names if C-x,T is pressed
+ 116)
+ local ci
+ while read -r _ ref ; do
+ tag=${ref#refs/tags/}
+ case $tag in
+ "$2"*) COMPREPLY[ci++]=$tag ;;
+ esac
+ done < <(git show-ref --tags)
+ ;;
+
+ # Do no completion, so we fall back on filenames
+ *) return 1 ;;
+
+ esac
+}
+complete -F _git -o bashdefault -o default git
diff --git a/bash/bash_completion.d/gpg.bash b/bash/bash_completion.d/gpg.bash
index c6f92676..5a055352 100644
--- a/bash/bash_completion.d/gpg.bash
+++ b/bash/bash_completion.d/gpg.bash
@@ -13,14 +13,9 @@ _gpg() {
# Generate completion reply from gpg(1) options
local ci comp
while read -r comp ; do
- COMPREPLY[ci++]=$comp
- done < <(
- gpg --dump-options 2>/dev/null |
- while read -r option ; do
- case $option in
- ("$2"*) printf '%s\n' "$option" ;;
- esac
- done
- )
+ case $comp in
+ "$2"*) COMPREPLY[ci++]=$comp ;;
+ esac
+ done < <(gpg --dump-options 2>/dev/null)
}
complete -F _gpg -o bashdefault -o default gpg
diff --git a/bash/bash_completion.d/make.bash b/bash/bash_completion.d/make.bash
index 7f8b8125..909c52fb 100644
--- a/bash/bash_completion.d/make.bash
+++ b/bash/bash_completion.d/make.bash
@@ -34,11 +34,11 @@ _make() {
esac
# Break the target up with space delimiters
- declare -a targets
IFS=' ' read -a targets -r \
< <(printf '%s\n' "${line%%:*}")
# Short-circuit if there are no targets
+ # shellcheck disable=SC2154
((${#targets[@]})) || exit
# Make matches behave correctly
diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash
index 50ab852e..714fa493 100644
--- a/bash/bash_completion.d/man.bash
+++ b/bash/bash_completion.d/man.bash
@@ -56,7 +56,6 @@ _man() {
fi
# Add pages from each manual directory
- local pages pi
for mp in "${manpaths[@]}" ; do
[[ -n $mp ]] || continue
diff --git a/bash/bash_completion.d/mex.bash b/bash/bash_completion.d/mex.bash
index b1e0e1a7..d9604b2c 100644
--- a/bash/bash_completion.d/mex.bash
+++ b/bash/bash_completion.d/mex.bash
@@ -51,4 +51,4 @@ _mex() {
done
)
}
-complete -F _mex mex
+complete -F _mex -o filenames mex
diff --git a/bash/bash_completion.d/openssl.bash b/bash/bash_completion.d/openssl.bash
index 1cb4bd07..1e2a9c58 100644
--- a/bash/bash_completion.d/openssl.bash
+++ b/bash/bash_completion.d/openssl.bash
@@ -8,25 +8,18 @@ _openssl() {
((COMP_CWORD == 1)) || return
# Iterate through completions produced by subshell
- local ci comp
- while read -r comp ; do
- COMPREPLY[ci++]=$comp
+ local -a subcmds
+ local ci subcmd
+ while read -a subcmds -r ; do
+ for subcmd in "${subcmds[@]}" ; do
+ case $subcmd in
+ "$2"*) COMPREPLY[ci++]=$subcmd ;;
+ esac
+ done
done < <(
-
- # Run each of the command-listing commands; read each line into an
- # array of subcommands (they are printed as a table)
- for list in commands digest-commands cipher-commands ; do
- openssl list -"$list"
- done | {
- declare -a subcmds
- while read -a subcmds -r ; do
- for subcmd in "${subcmds[@]}" ; do
- case $subcmd in
- ("$2"*) printf '%s\n' "$subcmd" ;;
- esac
- done
- done
- }
+ openssl list -commands \
+ -cipher-commands \
+ -digest-commands
)
}
complete -F _openssl -o bashdefault -o default openssl
diff --git a/bash/bash_completion.d/pass.bash b/bash/bash_completion.d/pass.bash
index 5a6e0b6c..760e774e 100644
--- a/bash/bash_completion.d/pass.bash
+++ b/bash/bash_completion.d/pass.bash
@@ -30,7 +30,7 @@ _pass() {
# Try to iterate into subdirs, use depth search with ** if available
if shopt -s globstar 2>/dev/null ; then
- for entry in "$pass_dir"/"$2"**/*.gpg ; do
+ for entry in "$pass_dir"/"$2"*/**/*.gpg ; do
entries[ei++]=$entry
done
else
diff --git a/bash/bash_completion.d/path.bash b/bash/bash_completion.d/path.bash
index 9234f132..c3bb7b80 100644
--- a/bash/bash_completion.d/path.bash
+++ b/bash/bash_completion.d/path.bash
@@ -62,11 +62,11 @@ _path() {
fi
# Break PATH into parts
- declare -a paths
IFS=: read -a paths -d '' -r \
< <(printf '%s\0' "$PATH")
# Print shell-quoted matching parts, null-terminated
+ # shellcheck disable=SC2154
for path in "${paths[@]}" ; do
case $path in
("$2"*) printf '%q\0' "$path" ;;
diff --git a/bash/bashrc b/bash/bashrc
index a05526f2..0400e41d 100644
--- a/bash/bashrc
+++ b/bash/bashrc
@@ -6,7 +6,7 @@ esac
# Don't do anything if restricted, not even sourcing the ENV file
# Testing $- for "r" doesn't work
-! shopt -q restricted_shell >/dev/null 2>&1 || return
+! shopt -q restricted_shell 2>/dev/null || return
# Clear away all aliases; we do this here rather than in the $ENV file shared
# between POSIX shells, because ksh relies on aliases to implement certain
diff --git a/bash/bashrc.d/keep.bash b/bash/bashrc.d/keep.bash
index 48196aeb..191dac4b 100644
--- a/bash/bashrc.d/keep.bash
+++ b/bash/bashrc.d/keep.bash
@@ -83,7 +83,7 @@ EOF
# Iterate through the NAMEs given
local name
- for name ; do
+ for name do
# Check NAMEs for validity
case $name in
diff --git a/bash/bashrc.d/vared.bash b/bash/bashrc.d/vared.bash
index e024f48a..491e5bff 100644
--- a/bash/bashrc.d/vared.bash
+++ b/bash/bashrc.d/vared.bash
@@ -24,7 +24,7 @@ vared() {
return 2
fi
local name
- for name ; do
+ for name do
IFS= read -e -i "${!name}" -p "${prompt:-"$name"=}" -r -- "${name?}"
done
}
diff --git a/bin/ap.sh b/bin/ap.sh
index 1d6376cc..2b13dfde 100644
--- a/bin/ap.sh
+++ b/bin/ap.sh
@@ -10,7 +10,7 @@ shift
# Iterate through the remaining args; it's legal for there to be none, but in
# that case the user may as well just have invoked the command directly
-for arg ; do
+for arg do
# If this is the first iteration, clear the params away (we grabbed them in
# the for statement)
diff --git a/bin/apf.sh b/bin/apf.sh
index 5e40e9b8..e11145ff 100644
--- a/bin/apf.sh
+++ b/bin/apf.sh
@@ -16,7 +16,7 @@ shift 2
if [ "$#" -gt 0 ] ; then
# Iterate through any remaining arguments
- for carg ; do
+ for carg do
# If this is the first command argument, then before we add it, we'll
# add all the ones from the file first if it exists
diff --git a/bin/d2u.sh b/bin/d2u.sh
index 892c446b..eceb11de 100644
--- a/bin/d2u.sh
+++ b/bin/d2u.sh
@@ -10,7 +10,7 @@ fi
r=$(printf '\r')
# Iterate over arguments and apply the same ed(1) script to each of them
-for fn ; do
+for fn do
# Note the heredoc WORD is intentionally unquoted because we want to expand
# $r within it to get a literal carriage return; the escape characters
diff --git a/bin/eds.sh b/bin/eds.sh
index c85069c6..c692cb30 100644
--- a/bin/eds.sh
+++ b/bin/eds.sh
@@ -21,7 +21,7 @@ case :$PATH: in
esac
# Prepend the path to each of the names given if they don't look like options
-for arg ; do
+for arg do
[ -n "$reset" ] || set -- && reset=1
case $arg in
--)
@@ -44,7 +44,7 @@ done
"${VISUAL:-"${EDITOR:-ed}"}" "$@"
# Make any created scripts executable if they now appear to be files
-for script ; do
+for script do
[ -f "$script" ] || continue
chmod +x -- "$script"
done
diff --git a/bin/fnp.sh b/bin/fnp.sh
index ec68e51f..bc0c7e21 100644
--- a/bin/fnp.sh
+++ b/bin/fnp.sh
@@ -4,7 +4,7 @@
[ "$#" -gt 0 ] || set -- -
# Iterate through arguments
-for arg ; do
+for arg do
# We'll print the filename "-stdin-" rather than - just to be slightly more
# explicit
diff --git a/bin/loc.sh b/bin/loc.sh
index 995c6932..214e87da 100644
--- a/bin/loc.sh
+++ b/bin/loc.sh
@@ -7,7 +7,7 @@ if [ "$#" -eq 0 ] ; then
fi
# Iterate through each search term and run an appropriate find(1) command
-for pat ; do
+for pat do
# Skip dotfiles, dotdirs, and symbolic links; print anything that matches
# the term as a substring (and stop iterating through it)
diff --git a/bin/mex.sh b/bin/mex.sh
index cf4e07e7..e79f8f2f 100644
--- a/bin/mex.sh
+++ b/bin/mex.sh
@@ -9,7 +9,7 @@ if [ "$#" -eq 0 ] ; then
fi
# Iterate through the given names
-for name ; do
+for name do
# Clear the found variable
found=
diff --git a/bin/mkcp.sh b/bin/mkcp.sh
index 10308263..3acf12f0 100644
--- a/bin/mkcp.sh
+++ b/bin/mkcp.sh
@@ -7,7 +7,7 @@ if [ "$#" -lt 2 ] ; then
fi
# Get the last argument (the directory to create)
-for dir ; do : ; done
+for dir do : ; done
# Create it, or bail
mkdir -p -- "$dir" || exit
diff --git a/bin/mked.sh b/bin/mked.sh
index 4e280205..93e21573 100644
--- a/bin/mked.sh
+++ b/bin/mked.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Create paths to all files before invoking editor
-for file ; do
+for file do
mkdir -p -- "${file%/*}" || exit
done
exec "$EDITOR" "$@"
diff --git a/bin/mkmv.sh b/bin/mkmv.sh
index 53b5aa8f..832c205e 100644
--- a/bin/mkmv.sh
+++ b/bin/mkmv.sh
@@ -7,7 +7,7 @@ if [ "$#" -lt 2 ] ; then
fi
# Get the last argument (the directory to create)
-for dir ; do : ; done
+for dir do : ; done
# Create it, or bail
mkdir -p -- "$dir" || exit
diff --git a/bin/mkvi.sh b/bin/mkvi.sh
index 244b89f8..c5974383 100644
--- a/bin/mkvi.sh
+++ b/bin/mkvi.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Create paths to all files before invoking editor
-for file ; do
+for file do
mkdir -p -- "${file%/*}" || exit
done
exec "$VISUAL" "$@"
diff --git a/bin/pp.sh b/bin/pp.sh
index b472a012..e9c25571 100644
--- a/bin/pp.sh
+++ b/bin/pp.sh
@@ -1,5 +1,5 @@
# Print the full path to each argument; path need not exist
-for arg ; do
+for arg do
case $arg in
/*) path=$arg ;;
*) path=$PWD/$arg ;;
diff --git a/bin/sqs.sh b/bin/sqs.sh
index 28435059..447a6563 100644
--- a/bin/sqs.sh
+++ b/bin/sqs.sh
@@ -8,7 +8,7 @@ if [ "$#" -eq 0 ] ; then
fi
# Iterate through the given files
-for sn ; do
+for sn do
# Strip trailing slash if any and then query string
sn=${sn%/}
diff --git a/bin/stbl.sh b/bin/stbl.sh
index 23d77703..2f6702b1 100644
--- a/bin/stbl.sh
+++ b/bin/stbl.sh
@@ -7,7 +7,7 @@ if [ "$#" -eq 0 ] ; then
fi
# Iterate over arguments and apply the same ed(1) script to each of them
-for fn ; do
+for fn do
ed -s -- "$fn" <<'EOF' || ex=1
$g/^ *$/d
w
diff --git a/bin/stex.sh b/bin/stex.sh
index 14d2cabf..b27d9cf8 100644
--- a/bin/stex.sh
+++ b/bin/stex.sh
@@ -13,7 +13,7 @@ ext=$1
shift
# Iterate through the given files (remaining args)
-for sn ; do
+for sn do
# Strip trailing slash if any and then extension
sn=${sn%/}
diff --git a/bin/stws.sh b/bin/stws.sh
index ce2c14d0..59a8652a 100644
--- a/bin/stws.sh
+++ b/bin/stws.sh
@@ -7,7 +7,7 @@ if [ "$#" -eq 0 ] ; then
fi
# Iterate over arguments and apply the same ed(1) script to each of them
-for fn ; do
+for fn do
ed -s -- "$fn" <<'EOF' || ex=1
g/ *$/ s/ *$//
w
diff --git a/bin/sue.sh b/bin/sue.sh
index 654c041f..34343e4a 100644
--- a/bin/sue.sh
+++ b/bin/sue.sh
@@ -4,7 +4,7 @@
user=
# Iterate over the given files
-for file ; do
+for file do
# Get the file's owner, or bail
file_owner=$(stat -c %U -- "$file") || exit
diff --git a/bin/u2d.sh b/bin/u2d.sh
index 31030341..cdbe9a33 100644
--- a/bin/u2d.sh
+++ b/bin/u2d.sh
@@ -10,7 +10,7 @@ fi
r=$(printf '\r')
# Iterate over arguments and apply the same ed(1) script to each of them
-for fn ; do
+for fn do
# Note the heredoc WORD is intentionally unquoted because we want to expand
# $r within it to get a literal carriage return; the escape characters
diff --git a/bin/xgo.sh b/bin/xgo.sh
index 3fb11fde..e627f9c6 100644
--- a/bin/xgo.sh
+++ b/bin/xgo.sh
@@ -7,7 +7,7 @@ if [ "$#" -eq 0 ] ; then
fi
# Iterate over the URL arguments
-for url ; do (
+for url do (
# Look for patterns in the URL that suggest transformations
case $url in
diff --git a/check/bash.sh b/check/bash.sh
index 1f9e1b38..510f2af0 100644
--- a/check/bash.sh
+++ b/check/bash.sh
@@ -5,7 +5,7 @@ set \
bash/bash_profile \
bash/bashrc \
bash/bashrc.d/*.bash
-for bash ; do
+for bash do
bash -n -- "$bash" || exit
done
printf 'GNU Bash dotfiles parsed successfully.\n'
diff --git a/check/ksh.sh b/check/ksh.sh
index f4bade82..cf83bc1f 100644
--- a/check/ksh.sh
+++ b/check/ksh.sh
@@ -1,7 +1,7 @@
set \
ksh/kshrc \
ksh/kshrc.d/*.ksh
-for ksh ; do
+for ksh do
ksh -n -- "$ksh" || exit
done
sh -n -- ksh/shrc.d/ksh.sh || exit
diff --git a/check/sh.sh b/check/sh.sh
index 92910c11..e0162f47 100644
--- a/check/sh.sh
+++ b/check/sh.sh
@@ -4,7 +4,7 @@ set \
sh/shinit \
sh/shrc \
sh/shrc.d/*.sh
-for sh ; do
+for sh do
sh -n -- "$sh" || exit
done
printf 'POSIX shell dotfiles parsed successfully.\n'
diff --git a/check/xinit.sh b/check/xinit.sh
index fa235c9d..ae03b8c2 100644
--- a/check/xinit.sh
+++ b/check/xinit.sh
@@ -1,7 +1,7 @@
set \
X/xinitrc \
X/xinitrc.d/*.sh
-for xinit ; do
+for xinit do
sh -n -- "$xinit" || exit
done
printf 'Xinit startup scripts parsed successfully.\n'
diff --git a/check/zsh.sh b/check/zsh.sh
index ce209584..0170e586 100644
--- a/check/zsh.sh
+++ b/check/zsh.sh
@@ -2,7 +2,7 @@ set \
zsh/zprofile \
zsh/zshrc.d/*.zsh \
zsh/zshrc
-for zsh ; do
+for zsh do
zsh -n -- "$zsh" || exit
done
sh -n zsh/profile.d/zsh.sh || exit
diff --git a/ksh/kshrc.d/keep.ksh b/ksh/kshrc.d/keep.ksh
index f6593c3d..629b2fe6 100644
--- a/ksh/kshrc.d/keep.ksh
+++ b/ksh/kshrc.d/keep.ksh
@@ -94,7 +94,7 @@ EOF
# Iterate through the NAMEs given
typeset name
- for name ; do
+ for name do
# Check NAMEs for validity
case $name in
diff --git a/readline/inputrc b/readline/inputrc
index c11d8fe7..857952cd 100644
--- a/readline/inputrc
+++ b/readline/inputrc
@@ -62,6 +62,12 @@ $if Bash
# Alt+A cycles through completion options
"\ea": menu-complete
+ # Special completion keys for git(1)
+ ## Branches
+ "\C-xb": complete
+ ## Tags
+ "\C-xt": complete
+
# Ctrl-Alt-L to clear screen; more ksh-like
"\e\C-l": clear-screen
diff --git a/sh/profile b/sh/profile
index 68e803ca..7f16cb32 100644
--- a/sh/profile
+++ b/sh/profile
@@ -1,5 +1,7 @@
# Add ~/.local/bin to PATH if it exists
-[ -d "$HOME"/.local/bin ] && PATH=$HOME/.local/bin:$PATH
+if [ -d "$HOME"/.local/bin ] ; then
+ PATH=$HOME/.local/bin:$PATH
+fi
# Load all supplementary scripts in ~/.profile.d
for sh in "$HOME"/.profile.d/*.sh ; do
@@ -13,11 +15,3 @@ if [ -f "$HOME"/.shinit ] ; then
ENV=$HOME/.shinit
export ENV
fi
-
-# If ENV_FORCE is set and we're interactive, source ENV explicitly
-# At the moment this is just for zsh-as-ksh/sh
-if [ -n "$ENV_FORCE" ] ; then
- case $- in *i*)
- [ -f "$ENV" ] && . "$ENV" ;;
- esac
-fi
diff --git a/sh/profile.d/downloads.sh b/sh/profile.d/downloads.sh
index 865cb859..1a89bc3f 100644
--- a/sh/profile.d/downloads.sh
+++ b/sh/profile.d/downloads.sh
@@ -8,7 +8,7 @@ esac
[ -z "$TMUX" ] || return
# Not if ~/.hushlogin exists
-[ -e "$HOME"/.hushlogin ] && return
+! [ -e "$HOME"/.hushlogin ] || return
# Not if ~/.downloads doesn't
[ -f "$HOME"/.downloads ] || return
@@ -27,5 +27,7 @@ esac
printf 'You have %u unsorted files in %s.\n' "$#" "$dir"
lc=$((lc+1))
done < "$HOME"/.downloads
- [ "$((lc > 0))" -eq 1 ] && printf '\n'
+ if [ "$lc" -gt 0 ] ; then
+ printf '\n'
+ fi
)
diff --git a/sh/profile.d/options.sh b/sh/profile.d/options.sh
index 73f62243..58376fb3 100644
--- a/sh/profile.d/options.sh
+++ b/sh/profile.d/options.sh
@@ -22,9 +22,10 @@ options() {
# Iterate through remaining arguments (desired options), creating files to
# show they're available if found in the help output
- for opt ; do
- command -p grep -q -- '[^[:alnum:]]--'"$opt"'[^[:alnum:]]' help &&
- touch -- "$opt"
+ for opt do
+ command -p grep -q -- \
+ '[^[:alnum:]]--'"$opt"'[^[:alnum:]]' help || continue
+ touch -- "$opt"
done
}
diff --git a/sh/profile.d/welcome.sh b/sh/profile.d/welcome.sh
index ede7a05f..cdd41edb 100644
--- a/sh/profile.d/welcome.sh
+++ b/sh/profile.d/welcome.sh
@@ -20,8 +20,10 @@ esac
# Show a fortune
if welcome fortune ; then
- [ -d "$HOME"/.local/share/games/fortunes ] &&
- : "${FORTUNE_PATH:="$HOME"/.local/share/games/fortunes}"
+ if ! [ -n "$FORTUNE_PATH"] &&
+ [ -d "$HOME"/.local/share/games/fortunes ] ; then
+ FORTUNE_PATH=$HOME/.local/share/games/fortunes
+ fi
fortune -s "$FORTUNE_PATH"
printf '\n'
fi
@@ -34,7 +36,9 @@ esac
# Run verse(1) if we haven't seen it already today
if welcome verse ; then
- [ -f "$HOME"/.verse ] && read -r last <"$HOME"/.verse
+ if [ -f "$HOME"/.verse ] ; then
+ read -r last <"$HOME"/.verse
+ fi
now=$(date +%Y%m%d)
if [ "$now" -gt "${last:-0}" ] ; then
verse
diff --git a/sh/shinit b/sh/shinit
index fe770a70..fb72cd14 100644
--- a/sh/shinit
+++ b/sh/shinit
@@ -1,4 +1,7 @@
-# If the shell is interactive, source ~/.shrc
-case $- in *i*)
- [ -f "$HOME"/.shrc ] && . "$HOME"/.shrc ;;
+# If the shell is interactive, and ~/.shrc exists, source it
+case $- in
+ *i*)
+ if [ -f "$HOME"/.shrc ] ; then
+ . "$HOME"/.shrc
+ fi
esac
diff --git a/sh/shrc b/sh/shrc
index 6359dbc3..808e944d 100644
--- a/sh/shrc
+++ b/sh/shrc
@@ -22,5 +22,7 @@ done
unset -v sh
# If ENV_EXT was set and exists, source that too, then clean it away
-[ -e "$ENV_EXT" ] && . "$ENV_EXT"
+if [ -e "$ENV_EXT" ] ; then
+ . "$ENV_EXT"
+fi
unset -v ENV_EXT
diff --git a/sh/shrc.d/bc.sh b/sh/shrc.d/bc.sh
index aee88e09..591b4359 100644
--- a/sh/shrc.d/bc.sh
+++ b/sh/shrc.d/bc.sh
@@ -6,8 +6,9 @@
bc() {
# Add --quiet to stop the annoying welcome banner
- [ -e "$HOME"/.cache/sh/opt/bc/quiet ] &&
+ if [ -e "$HOME"/.cache/sh/opt/bc/quiet ] ; then
set -- --quiet "$@"
+ fi
# Run bc(1) with the concluded arguments
command bc "$@"
diff --git a/sh/shrc.d/ed.sh b/sh/shrc.d/ed.sh
index e6b6eee8..dc8433f6 100644
--- a/sh/shrc.d/ed.sh
+++ b/sh/shrc.d/ed.sh
@@ -12,16 +12,18 @@ ed() {
fi
# Add --verbose to explain errors
- [ -e "$HOME"/.cache/sh/opt/ed/verbose ] &&
+ if [ -e "$HOME"/.cache/sh/opt/ed/verbose ] ; then
set -- --verbose "$@"
+ fi
# Add an asterisk prompt (POSIX feature)
set -- -p\* "$@"
# Run in rlwrap(1) if available
set -- ed "$@"
- command -v rlwrap >/dev/null 2>&1 &&
+ if command -v rlwrap >/dev/null 2>&1 ; then
set -- rlwrap --history-filename=/dev/null "$@"
+ fi
# Run determined command
command "$@"
diff --git a/sh/shrc.d/grep.sh b/sh/shrc.d/grep.sh
index 43797ef5..997babc9 100644
--- a/sh/shrc.d/grep.sh
+++ b/sh/shrc.d/grep.sh
@@ -9,37 +9,43 @@ unset -v GREP_OPTIONS
grep() {
# Add --binary-files=without-match to gracefully skip binary files
- [ -e "$HOME"/.cache/sh/opt/grep/binary-files ] &&
+ if [ -e "$HOME"/.cache/sh/opt/grep/binary-files ] ; then
set -- --binary-files=without-match "$@"
+ fi
# Add --color=auto if the terminal has at least 8 colors
- [ -e "$HOME"/.cache/sh/opt/grep/color ] &&
- [ "$({ tput colors||tput Co||echo 0; } 2>/dev/null)" -ge 8 ] &&
+ if [ -e "$HOME"/.cache/sh/opt/grep/color ] &&
+ [ "$({ tput colors||tput Co||echo 0; } 2>/dev/null)" -ge 8 ] ; then
set -- --color=auto "$@"
+ fi
# Add --devices=skip to gracefully skip devices
- [ -e "$HOME"/.cache/sh/opt/grep/devices ] &&
+ if [ -e "$HOME"/.cache/sh/opt/grep/devices ] ; then
set -- --devices=skip "$@"
+ fi
# Add --directories=skip to gracefully skip directories
- [ -e "$HOME"/.cache/sh/opt/grep/directories ] &&
+ if [ -e "$HOME"/.cache/sh/opt/grep/directories ] ; then
set -- --directories=skip "$@"
+ fi
# Add --exclude to ignore .gitignore and .gitmodules files
- [ -e "$HOME"/.cache/sh/opt/grep/exclude ] &&
+ if [ -e "$HOME"/.cache/sh/opt/grep/exclude ] ; then
set -- \
--exclude=.gitignore \
--exclude=.gitmodules \
"$@"
+ fi
# Add --exclude-dir to ignore version control dot-directories
- [ -e "$HOME"/.cache/sh/opt/grep/exclude-dir ] &&
+ if [ -e "$HOME"/.cache/sh/opt/grep/exclude-dir ] ; then
set -- \
--exclude-dir=.cvs \
--exclude-dir=.git \
--exclude-dir=.hg \
--exclude-dir=.svn \
"$@"
+ fi
# Run grep(1) with the concluded arguments
command grep "$@"
diff --git a/sh/shrc.d/gt.sh b/sh/shrc.d/gt.sh
index 95ab4c2f..7a52571d 100644
--- a/sh/shrc.d/gt.sh
+++ b/sh/shrc.d/gt.sh
@@ -19,7 +19,9 @@ gt() {
done
# If target isn't a directory, chop to its parent
- [ -d "$1" ] || set -- "${1%/*}"
+ if ! [ -d "$1" ] ; then
+ set -- "${1%/*}"
+ fi
# Try to change into the determined directory, or root if empty
command cd -- "${1:-/}"
diff --git a/sh/shrc.d/ls.sh b/sh/shrc.d/ls.sh
index 7e843cc7..1083dfca 100644
--- a/sh/shrc.d/ls.sh
+++ b/sh/shrc.d/ls.sh
@@ -12,26 +12,30 @@ unset -v LS_OPTIONS LS_COLORS
# Define function proper
ls() {
- # -F to show trailing indicators of the filetype
- # -q to replace control chars with '?'
+ # POSIX options:
+ ## -F to show trailing indicators of the filetype
+ ## -q to replace control chars with '?'
set -- -Fq "$@"
-
- # If output is to a terminal, add -x to format entries across, not down
- [ -t 1 ] && set -- -x "$@"
-
- # Add --block-size=K to always show the filesize in kibibytes
- [ -e "$HOME"/.cache/sh/opt/ls/block-size ] &&
+ ## -x to format entries across, not down, if output looks like a terminal
+ if [ -t 1 ] ; then
+ set -- -x "$@"
+ fi
+
+ # GNU options:
+ ## Add --block-size=K to always show the filesize in kibibytes
+ if [ -e "$HOME"/.cache/sh/opt/ls/block-size ] ; then
set -- --block-size=1024 "$@"
-
- # Add --color if the terminal has at least 8 colors
- [ -e "$HOME"/.cache/sh/opt/ls/color ] &&
- [ "$({ tput colors||tput Co||echo 0; } 2>/dev/null)" -ge 8 ] &&
+ fi
+ ## Add --color if the terminal has at least 8 colors
+ if [ -e "$HOME"/.cache/sh/opt/ls/color ] &&
+ [ "$(exec 2>/dev/null;tput colors||tput Co||echo 0)" -ge 8 ] ; then
set -- --color=auto "$@"
-
- # Add --time-style='+%Y-%m-%d %H:%M:%S' to show the date in my preferred
- # (fixed) format
- [ -e "$HOME"/.cache/sh/opt/ls/time-style ] &&
+ fi
+ ## Add --time-style='+%Y-%m-%d %H:%M:%S' to show the date in my preferred
+ ## (fixed) format
+ if [ -e "$HOME"/.cache/sh/opt/ls/time-style ] ; then
set -- --time-style='+%Y-%m-%d %H:%M:%S' "$@"
+ fi
# If the operating system is FreeBSD, there are some specific options we
# can add that might mean different things to e.g. GNU ls(1)
diff --git a/sh/shrc.d/mkcd.sh b/sh/shrc.d/mkcd.sh
index c59a8c54..cd882b51 100644
--- a/sh/shrc.d/mkcd.sh
+++ b/sh/shrc.d/mkcd.sh
@@ -1,4 +1,5 @@
# Create a directory and change into it
mkcd() {
- mkdir -p -- "$1" && command cd -- "$1"
+ command -p mkdir -p -- "$1" || return
+ command cd -- "$1"
}
diff --git a/sh/shrc.d/path.sh b/sh/shrc.d/path.sh
index b6b1820f..a854e148 100644
--- a/sh/shrc.d/path.sh
+++ b/sh/shrc.d/path.sh
@@ -5,15 +5,16 @@ path() {
case $1 in
# List current directories in PATH
- list|'') (
- path=$PATH:
- while [ -n "$path" ] ; do
- dir=${path%%:*}
- path=${path#*:}
- [ -n "$dir" ] || continue
- printf '%s\n' "$dir"
+ list|'')
+ set -- "$PATH":
+ while [ -n "$1" ] ; do
+ case $1 in
+ :*) ;;
+ *) printf '%s\n' "${1%%:*}" ;;
+ esac
+ set -- "${1#*:}"
done
- ) ;;
+ ;;
# Helper function checks directory argument makes sense
_argcheck)
@@ -33,7 +34,9 @@ path() {
# Add a directory at the start of $PATH
insert)
- [ "$#" -eq 2 ] || set -- "$1" "$PWD"
+ if ! [ "$#" -eq 2 ] ; then
+ set -- "$1" "$PWD"
+ fi
path _argcheck "$@" || return
if path check "$2" ; then
printf >&2 'path(): %s: %s already in PATH\n' "$@"
@@ -44,7 +47,9 @@ path() {
# Add a directory to the end of $PATH
append)
- [ "$#" -eq 2 ] || set -- "$1" "$PWD"
+ if ! [ "$#" -eq 2 ] ; then
+ set -- "$1" "$PWD"
+ fi
path _argcheck "$@" || return
if path check "$2" ; then
printf >&2 'path(): %s: %s already in PATH\n' "$@"
@@ -55,7 +60,9 @@ path() {
# Remove a directory from $PATH
remove)
- [ "$#" -eq 2 ] || set -- "$1" "$PWD"
+ if ! [ "$#" -eq 2 ] ; then
+ set -- "$1" "$PWD"
+ fi
path _argcheck "$@" || return
if ! path check "$2" ; then
printf >&2 'path(): %s: %s not in PATH\n' "$@"
@@ -107,7 +114,9 @@ path() {
# Check whether a directory is in PATH
check)
path _argcheck "$@" || return
- [ "$#" -eq 2 ] || set -- "$1" "$PWD"
+ if ! [ "$#" -eq 2 ] ; then
+ set -- "$1" "$PWD"
+ fi
case :$PATH: in
*:"$2":*) return 0 ;;
esac
diff --git a/sh/shrc.d/tree.sh b/sh/shrc.d/tree.sh
index d462f3e1..a7e5bef3 100644
--- a/sh/shrc.d/tree.sh
+++ b/sh/shrc.d/tree.sh
@@ -22,7 +22,7 @@ tree() {
[ -t 1 ] || exit
# Not if output terminal doesn't have at least 8 colors
- [ "$({ tput colors||tput Co||echo 0; } 2>/dev/null)" -ge 8 ]
+ [ "$(exec 2>/dev/null;tput colors||tput Co||echo 0)" -ge 8 ]
) ; then
set -- -C "$@"
diff --git a/sh/shrc.d/vr.sh b/sh/shrc.d/vr.sh
index 8b35357c..c7057ec2 100644
--- a/sh/shrc.d/vr.sh
+++ b/sh/shrc.d/vr.sh
@@ -11,9 +11,14 @@ vr() {
exit 2
fi
- # Get path from first argument, strip trailing slash
+ # Get path from first argument
path=${1:-"$PWD"}
- [ "$path" = / ] || path=${path%/}
+
+ # Strip a trailing slash
+ case $path in
+ (/) ;;
+ (*) path=${path%/} ;;
+ esac
# Step into the directory
cd -- "$path" || exit
@@ -34,7 +39,7 @@ vr() {
# that is the root (bad)
while svn info >/dev/null 2>&1 ; do
root=$PWD
- [ "$root" = / ] && break
+ ! [ "$root" = / ] || break
cd .. || exit
done
if [ -n "$root" ] ; then
diff --git a/vim/autoload/filetype.vim b/vim/autoload/filetype.vim
new file mode 100644
index 00000000..d1e4e3d7
--- /dev/null
+++ b/vim/autoload/filetype.vim
@@ -0,0 +1,76 @@
+" Helper function to run the 'filetypedetect' group on a file with its
+" extension stripped off
+function! filetype#StripRepeat() abort
+
+ " Check we have the fnameescape() function
+ if !exists('*fnameescape')
+ return
+ endif
+
+ " Expand the match result
+ let l:fn = expand('<afile>')
+
+ " Strip leading and trailing #hashes#
+ if l:fn =~# '^#\+.*#\+$'
+ let l:fn = substitute(l:fn, '^#\+\(.\+\)#\+$', '\1', '')
+
+ " Strip trailing tilde~
+ elseif l:fn =~# '\~$'
+ let l:fn = substitute(l:fn, '\~$', '', '')
+
+ " Strip generic .extension
+ else
+ let l:fn = expand('<afile>:r')
+ endif
+
+ " Re-run the group if there's anything left
+ if strlen(l:fn)
+ execute 'doautocmd filetypedetect BufRead ' . fnameescape(l:fn)
+ endif
+
+endfunction
+
+" Helper function to run the 'filetypedetect' group on a file in a temporary
+" sudoedit(8) directory, modifying it with an attempt to reverse the temporary
+" filename change
+function! filetype#SudoRepeat() abort
+
+ " Check we have the fnameescape() function
+ if !exists('*fnameescape')
+ return
+ endif
+
+ " Expand the match result
+ let l:fn = expand('<afile>')
+
+ " myfileXXQGS16A.conf: strip eight chars before final period
+ if l:fn =~# '/[^./]\+\w\{8}\.[^./]\+$'
+ let l:fr = expand('<afile>:r')
+ let l:fe = expand('<afile>:e')
+ let l:fn = strpart(l:fr, -8, strlen(l:fr)) . '.' . l:fe
+
+ " myfile.XXQGS16A: strip extension
+ elseif l:fn =~# '/[^./]\+\.\w\{8}$'
+ let l:fn = expand('<afile>:r')
+
+ " Unrecognised pattern; return, don't repeat
+ else
+ return
+ endif
+
+ " Re-run the group if there's anything left
+ if strlen(l:fn)
+ execute 'doautocmd filetypedetect BufRead ' . fnameescape(l:fn)
+ endif
+
+endfunction
+
+" Check whether the first line was changed and looks like a shebang, and if
+" so, re-run filetype detection
+function! filetype#CheckShebang() abort
+ if line('''[') == 1 && getline(1) =~# '^#!'
+ doautocmd filetypedetect BufRead
+ endif
+endfunction
+
+
diff --git a/vim/filetype.vim b/vim/filetype.vim
index cc0de4e4..3ac816d4 100644
--- a/vim/filetype.vim
+++ b/vim/filetype.vim
@@ -10,81 +10,6 @@ if !has('autocmd') || &compatible
finish
endif
-" Helper function to run the 'filetypedetect' group on a file with its
-" extension stripped off
-function! s:StripRepeat()
-
- " Check we have the fnameescape() function
- if !exists('*fnameescape')
- return
- endif
-
- " Expand the match result
- let l:fn = expand('<afile>')
-
- " Strip leading and trailing #hashes#
- if l:fn =~# '^#\+.*#\+$'
- let l:fn = substitute(l:fn, '^#\+\(.\+\)#\+$', '\1', '')
-
- " Strip trailing tilde~
- elseif l:fn =~# '\~$'
- let l:fn = substitute(l:fn, '\~$', '', '')
-
- " Strip generic .extension
- else
- let l:fn = expand('<afile>:r')
- endif
-
- " Re-run the group if there's anything left
- if strlen(l:fn)
- execute 'doautocmd filetypedetect BufRead ' . fnameescape(l:fn)
- endif
-
-endfunction
-
-" Helper function to run the 'filetypedetect' group on a file in a temporary
-" sudoedit(8) directory, modifying it with an attempt to reverse the temporary
-" filename change
-function! s:SudoRepeat()
-
- " Check we have the fnameescape() function
- if !exists('*fnameescape')
- return
- endif
-
- " Expand the match result
- let l:fn = expand('<afile>')
-
- " myfileXXQGS16A.conf: strip eight chars before final period
- if l:fn =~# '/[^./]\+\w\{8}\.[^./]\+$'
- let l:fr = expand('<afile>:r')
- let l:fe = expand('<afile>:e')
- let l:fn = strpart(l:fr, -8, strlen(l:fr)) . '.' . l:fe
-
- " myfile.XXQGS16A: strip extension
- elseif l:fn =~# '/[^./]\+\.\w\{8}$'
- let l:fn = expand('<afile>:r')
-
- " Unrecognised pattern; return, don't repeat
- else
- return
- endif
-
- " Re-run the group if there's anything left
- if strlen(l:fn)
- execute 'doautocmd filetypedetect BufRead ' . fnameescape(l:fn)
- endif
-
-endfunction
-
-" Check whether the first line was changed and looks like a shebang, and if
-" so, re-run filetype detection
-function! s:CheckShebang()
- if line('''[') == 1 && getline(1) =~# '^#!'
- doautocmd filetypedetect BufRead
- endif
-endfunction
-
" Use our own filetype detection rules
augroup filetypedetect
autocmd!
@@ -97,7 +22,7 @@ augroup filetypedetect
\,?*~
\,?*.{bak,example,in,new,old,orig,sample,test}
\,?*.dpkg-{bak,dist,new,old}
- \ call s:StripRepeat()
+ \ call filetype#StripRepeat()
" Stuff Tom cares about enough and edits often enough to type based on
" filename patterns follows.
@@ -534,7 +459,7 @@ augroup filetypedetect
\ /var/tmp/?*????????.*
\,/var/tmp/?*.????????
\ if !did_filetype()
- \| call s:SudoRepeat()
+ \| call filetype#SudoRepeat()
\|endif
" Generic text, config, and log files, if no type assigned yet
@@ -568,6 +493,6 @@ augroup filetypedetect
" On leaving insert mode, check whether the first line was changed and looks
" like a shebang format, and if so, re-run filetype detection
- autocmd InsertLeave * call s:CheckShebang()
+ autocmd InsertLeave * call filetype#CheckShebang()
augroup END
diff --git a/zsh/profile.d/zsh.sh b/zsh/profile.d/zsh.sh
index 47de6d4d..37ec8014 100644
--- a/zsh/profile.d/zsh.sh
+++ b/zsh/profile.d/zsh.sh
@@ -5,24 +5,33 @@
# ~/.profile is read. This seems to have been fixed in Zsh commit ID fde365e,
# which was followed by release 5.3.0.
-# Is this zsh masquerading as sh/ksh?
+# This hack is only applicable to interactive zsh invoked as sh/ksh, when ENV
+# exists, so check each of those:
+## Interactive?
+case $- in
+ *i*) ;;
+ *) return ;;
+esac
+## zsh?
[ -n "$ZSH_VERSION" ] || return
+## Invoked as sh or ksh?
case $ZSH_NAME in
sh|ksh) ;;
*) return ;;
esac
+## ENV exists?
+[ -e "$ENV" ] || return
# Iterate through the zsh version number to see if it's at least 5.3.0; if not,
-# we'll have ~/.profile force sourcing $ENV
-if ! (
+# we'll source $ENV ourselves, since ~/.profile probably didn't do it
+if (
zvs=$ZSH_VERSION
for fv in 5 3 0 ; do
zv=${zvs%%[!0-9]*}
- [ "$((zv > fv))" -eq 1 ] && exit 0
- [ "$((zv < fv))" -eq 1 ] && exit 1
- zvs=${zvs#*.}
- [ -n "$zvs" ] || exit 0
+ ! [ "$zv" -gt "$fv" ] || exit 1
+ ! [ "$zv" -lt "$fv" ] || exit 0
+ zvs=${ZSH_VERSION#*.}
done
) ; then
- ENV_FORCE=1
+ . "$ENV"
fi
diff --git a/zsh/zshrc.d/keep.zsh b/zsh/zshrc.d/keep.zsh
index 59696301..c47748cd 100644
--- a/zsh/zshrc.d/keep.zsh
+++ b/zsh/zshrc.d/keep.zsh
@@ -83,7 +83,7 @@ EOF
# Iterate through the NAMEs given
local name
- for name ; do
+ for name do
# Check NAMEs for validity
case $name in