aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2016-08-21 23:56:03 +1200
committerTom Ryder <tom@sanctum.geek.nz>2016-08-21 23:56:03 +1200
commitf9e350e135585e9df31c17a65364367601bbe1f5 (patch)
tree471bff90e99b06a13c15c6a328d57eeace0fbb1b
parentPort Bash Git prompt changes to pdksh (diff)
parentRemove double-up import of completions (diff)
downloaddotfiles-f9e350e135585e9df31c17a65364367601bbe1f5.tar.gz
dotfiles-f9e350e135585e9df31c17a65364367601bbe1f5.zip
Merge branch 'master' into openbsd
-rw-r--r--README.markdown15
-rw-r--r--bash/bash_completion.d/bash.bash38
-rw-r--r--bash/bash_logout14
-rw-r--r--bash/bash_profile21
-rw-r--r--bash/bashrc30
-rw-r--r--bash/bashrc.d/completion.bash60
-rw-r--r--bash/bashrc.d/keep.bash15
-rw-r--r--bash/bashrc.d/prompt.bash110
-rw-r--r--sh/profile.d/games.sh4
-rw-r--r--sh/profile.d/go.sh8
-rw-r--r--sh/profile.d/grep.sh27
-rw-r--r--sh/profile.d/keychain.sh16
-rw-r--r--sh/profile.d/ls.sh20
-rw-r--r--sh/profile.d/options.sh55
-rw-r--r--sh/profile.d/verse.sh4
-rw-r--r--sh/shrc.d/bc.sh15
-rw-r--r--sh/shrc.d/ed.sh38
-rw-r--r--sh/shrc.d/grep.sh8
-rw-r--r--sh/shrc.d/keychain.sh5
-rw-r--r--sh/shrc.d/la.sh10
-rw-r--r--sh/shrc.d/ll.sh10
-rw-r--r--sh/shrc.d/ls.sh13
22 files changed, 260 insertions, 276 deletions
diff --git a/README.markdown b/README.markdown
index e17ddb68..1790afb2 100644
--- a/README.markdown
+++ b/README.markdown
@@ -175,15 +175,14 @@ in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include:
* `gdb()` silences startup messages from `gdb(1)`.
* `gpg()` quietens `gpg(1)` down for most commands.
* `grep()` tries to apply color and other options good for interactive use,
- depending on the capabilities of the system `grep(1)`. It's dependent on
- information written by the `grep.sh` script in `~/.profile.d`.
+ depending on the capabilities of the system `grep(1)`.
* `hgrep()` allows searching `$HISTFILE`.
-* `keychain()` updates `$GPG_TTY` if set for `keychain(1)`.
+* `keychain()` keeps `$GPG_TTY` up to date if a GnuPG agent is available.
* `lhn()` gets the history number of the last command, if the POSIX `fc`
builtin is available.
* `ls()` tries to apply color to `ls(1)` for interactive use if available.
- It's dependent on information written by the `ls.sh` script in
- `~/.profile.d`.
+ * `la()` runs `ls -A` if it can, or `ls -a` otherwise.
+ * `ll()` runs `ls -Al` if it can, or `ls -al` otherwise.
* `mkcd()` creates a directory and changes into it.
* `mysql()` allows shortcuts to MySQL configuration files stored in
`~/.mysql`.
@@ -195,7 +194,7 @@ in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include:
* `scr()` creates a temporary directory and changes into it.
* `sd()` changes into a sibling of the current directory.
* `sudo()` forces `-H` for `sudo(8)` calls so that `$HOME` is never
- preserved; I hate ending up `root`-owned files in my home directory.
+ preserved; I hate having `root`-owned files in my home directory.
* `tmux()` changes the default command for `tmux(1)` to `attach-session -d`
if a session exists, or creates a new session if one doesn't.
* `ud()` changes into an indexed ancestor of a directory.
@@ -233,7 +232,9 @@ files for things I really do get tired of typing repeatedly:
* `pass(1)` entries
* `ssh(1)` hostnames from `~/.ssh/config`
-I also add completions for my own scripts and functions where useful.
+I also add completions for my own scripts and functions where useful. The
+completions are dynamically loaded if Bash is version 4.0 or greater.
+Otherwise, they're all loaded on startup.
#### pdksh
diff --git a/bash/bash_completion.d/bash.bash b/bash/bash_completion.d/bash.bash
deleted file mode 100644
index 5d944b9b..00000000
--- a/bash/bash_completion.d/bash.bash
+++ /dev/null
@@ -1,38 +0,0 @@
-# Various easy completions
-
-# Bash builtins
-complete -A builtin builtin
-
-# Bash options
-complete -A setopt set
-
-# Commands
-complete -A command command complete coproc exec hash type
-
-# Directories
-complete -A directory cd pushd mkdir rmdir
-
-# Functions
-complete -A function function
-
-# Help topics
-complete -A helptopic help
-
-# Jobspecs
-complete -A job disown fg jobs
-complete -A stopped bg
-
-# Readline bindings
-complete -A binding bind
-
-# Shell options
-complete -A shopt shopt
-
-# Signal names
-complete -A signal trap
-
-# Variables
-complete -A variable declare export readonly typeset
-
-# Both functions and variables
-complete -A function -A variable unset
diff --git a/bash/bash_logout b/bash/bash_logout
index afb088b8..911b4f66 100644
--- a/bash/bash_logout
+++ b/bash/bash_logout
@@ -1,14 +1,2 @@
-# Ensure we're using at least version 2.05. Weird arithmetic syntax needed here
-# due to leading zeroes and trailing letters in some 2.x version numbers (e.g.
-# 2.05a).
-if ! [ -n "$BASH_VERSINFO" ] ; then
- return
-elif ((BASH_VERSINFO[0] == 2)) &&
- ((10#${BASH_VERSINFO[1]%%[![:digit:]]*} < 5)) ; then
- return
-fi
-
# Clear console if possible when logging out
-if ((SHLVL == 1)) ; then
- clear_console -q 2>/dev/null
-fi
+[ "$SHLVL" = 1 ] && clear_console -q 2>/dev/null
diff --git a/bash/bash_profile b/bash/bash_profile
index 69350102..a520f051 100644
--- a/bash/bash_profile
+++ b/bash/bash_profile
@@ -1,19 +1,6 @@
# Load ~/.profile regardless of shell version
-if [ -e "$HOME"/.profile ] ; then
- . "$HOME"/.profile
-fi
+[ -e "$HOME"/.profile ] && . "$HOME"/.profile
-# Ensure we're using at least version 2.05. Weird arithmetic syntax needed here
-# due to leading zeroes and trailing letters in some 2.x version numbers (e.g.
-# 2.05a).
-if ! [ -n "$BASH_VERSINFO" ] ; then
- return
-elif ((BASH_VERSINFO[0] == 2)) &&
- ((10#${BASH_VERSINFO[1]%%[![:digit:]]*} < 5)) ; then
- return
-fi
-
-# If ~/.bashrc exists, source that too; the test for interactivity is in there
-if [[ -f $HOME/.bashrc ]] ; then
- source "$HOME"/.bashrc
-fi
+# If ~/.bashrc exists, source that too; the tests for both interactivity and
+# >=2.05a (for features like [[) are in there
+[ -f "$HOME"/.bashrc ] && . "$HOME"/.bashrc
diff --git a/bash/bashrc b/bash/bashrc
index 7defd85d..d6b2adca 100644
--- a/bash/bashrc
+++ b/bash/bashrc
@@ -1,12 +1,10 @@
# Ensure we're using at least version 2.05. Weird arithmetic syntax needed here
# due to leading zeroes and trailing letters in some 2.x version numbers (e.g.
# 2.05a).
-if ! [ -n "$BASH_VERSINFO" ] ; then
+[ -n "$BASH_VERSINFO" ] || return
+((BASH_VERSINFO[0] == 2)) &&
+ ((10#${BASH_VERSINFO[1]%%[![:digit:]]*} < 5)) &&
return
-elif ((BASH_VERSINFO[0] == 2)) &&
- ((10#${BASH_VERSINFO[1]%%[![:digit:]]*} < 5)) ; then
- return
-fi
# Make sure the shell is interactive
case $- in
@@ -15,9 +13,7 @@ case $- in
esac
# Don't do anything if running a restricted shell
-if shopt -q restricted_shell ; then
- return
-fi
+shopt -q restricted_shell && return
# Keep around four thousand lines of history in file
HISTFILESIZE=$((1 << 12))
@@ -80,7 +76,7 @@ shopt -s shift_verbose
shopt -u sourcepath
# These options only exist since Bash 4.0-alpha
-if ((BASH_VERSINFO[0] == 4)) ; then
+if ((BASH_VERSINFO[0] >= 4)) ; then
# Autocorrect fudged paths during completion
shopt -s dirspell
@@ -89,28 +85,20 @@ if ((BASH_VERSINFO[0] == 4)) ; then
# Warn me about stopped jobs when exiting; only if >=4.1 due to bug
# <https://lists.gnu.org/archive/html/bug-bash/2009-02/msg00176.html>
- if ((BASH_VERSINFO[1] >= 1)) ; then
- shopt -s checkjobs
- fi
+ ((BASH_VERSINFO[1] >= 1)) && shopt -s checkjobs
# Expand variables in directory completion; only available since 4.3
- if ((BASH_VERSINFO[1] >= 3)) ; then
- shopt -s direxpand
- fi
+ ((BASH_VERSINFO[1] >= 3)) && shopt -s direxpand
fi
# If COMP_WORDBREAKS has a value, strip all colons from it; this allows
# completing filenames correctly, since an unquoted colon is not a syntactic
# character: <http://tiswww.case.edu/php/chet/bash/FAQ> (E13)
-if [[ -n $COMP_WORDBREAKS ]] ; then
- COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
-fi
+[[ -n $COMP_WORDBREAKS ]] && COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
# Load POSIX shell functions, Bash-specific scripts, and Bash completion files,
# in that order
-for sh in "$ENV" \
- "$HOME"/.bashrc.d/*.bash \
- "$HOME"/.bash_completion.d/*.bash ; do
+for sh in "$ENV" "$HOME"/.bashrc.d/*.bash ; do
[[ -e $sh ]] && source "$sh"
done
unset -v sh
diff --git a/bash/bashrc.d/completion.bash b/bash/bashrc.d/completion.bash
new file mode 100644
index 00000000..1246ba31
--- /dev/null
+++ b/bash/bashrc.d/completion.bash
@@ -0,0 +1,60 @@
+# Various easy completions for Bash builtins; more specific stuff goes in
+# ~/.bash_completion.d
+
+# Bash builtins
+complete -A builtin builtin
+
+# Bash options
+complete -A setopt set
+
+# Commands
+complete -A command command complete coproc exec hash type
+
+# Directories
+complete -A directory cd pushd mkdir rmdir
+
+# Functions
+complete -A function function
+
+# Help topics
+complete -A helptopic help
+
+# Jobspecs
+complete -A job disown fg jobs
+complete -A stopped bg
+
+# Readline bindings
+complete -A binding bind
+
+# Shell options
+complete -A shopt shopt
+
+# Signal names
+complete -A signal trap
+
+# Variables
+complete -A variable declare export readonly typeset
+
+# Both functions and variables
+complete -A function -A variable unset
+
+# If we have dynamic completion loading (Bash>=4.0), use it
+if ((BASH_VERSINFO[0] >= 4)) ; then
+
+ # Handler tries to load appropriate completion for commands
+ _completion_loader() {
+ [[ -n $1 ]] || return
+ local compspec
+ compspec=$HOME/.bash_completion.d/$1.bash
+ [[ -f $compspec ]] || return
+ source "$compspec" >/dev/null 2>&1 && return 124
+ }
+ complete -D -F _completion_loader -o bashdefault -o default
+
+# If not, load all of the completions up now
+else
+ for sh in "$HOME"/.bash_completion.d/*.bash ; do
+ [[ -e $sh ]] && source "$sh"
+ done
+ unset -v sh
+fi
diff --git a/bash/bashrc.d/keep.bash b/bash/bashrc.d/keep.bash
index b1c8bea4..fb4b8bde 100644
--- a/bash/bashrc.d/keep.bash
+++ b/bash/bashrc.d/keep.bash
@@ -45,9 +45,7 @@ keep() {
# -h given; means show help
h)
- while IFS= read -r line ; do
- printf '%s\n' "$line"
- done <<EOF
+ cat <<EOF
$FUNCNAME: Keep variables and functions in shell permanently by writing them to
named scripts iterated on shell start, in \$BASHKEEP (defaults to
~/.bashkeep.d).
@@ -145,10 +143,7 @@ EOF
}
# Load any existing scripts in bashkeep
-if [[ -d ${BASHKEEP:-"$HOME"/.bashkeep.d} ]] ; then
- for bashkeep in "${BASHKEEP:-"$HOME"/.bashkeep.d}"/*.bash ; do
- [[ -e $bashkeep ]] || continue
- source "$bashkeep"
- done
- unset -v bashkeep
-fi
+for bashkeep in "${BASHKEEP:-"$HOME"/.bashkeep.d}"/*.bash ; do
+ [[ -e $bashkeep ]] && source "$bashkeep"
+done
+unset -v bashkeep
diff --git a/bash/bashrc.d/prompt.bash b/bash/bashrc.d/prompt.bash
index 1e8c568d..e61b69d5 100644
--- a/bash/bashrc.d/prompt.bash
+++ b/bash/bashrc.d/prompt.bash
@@ -1,12 +1,6 @@
# Frontend to controlling prompt
prompt() {
- # If no arguments, print the prompt strings as they are
- if ! (($#)) ; then
- declare -p PS1 PS2 PS3 PS4
- return
- fi
-
# What's done next depends on the first argument to the function
case $1 in
@@ -19,9 +13,7 @@ prompt() {
PROMPT_COMMAND='PROMPT_RETURN=$? ; history -a'
# If Bash 4.0 is available, trim very long paths in prompt
- if ((BASH_VERSINFO[0] >= 4)) ; then
- PROMPT_DIRTRIM=4
- fi
+ ((BASH_VERSINFO[0] >= 4)) && PROMPT_DIRTRIM=4
# Basic prompt shape
PS1='\u@\h:\w'
@@ -38,13 +30,13 @@ prompt() {
# Count available colors
local -i colors
colors=$( {
- tput Co || tput colors
+ tput colors || tput Co
} 2>/dev/null )
# Prepare reset code
local reset
reset=$( {
- tput me || tput sgr0
+ tput sgr0 || tput me
} 2>/dev/null )
# Decide prompt color formatting based on color availability
@@ -55,10 +47,10 @@ prompt() {
256)
format=$( {
: "${PROMPT_COLOR:=10}"
- tput AF "$PROMPT_COLOR" ||
tput setaf "$PROMPT_COLOR" ||
- tput AF "$PROMPT_COLOR" 0 0 ||
- tput setaf "$PROMPT_COLOR" 0 0
+ tput setaf "$PROMPT_COLOR" 0 0 ||
+ tput AF "$PROMPT_COLOR" ||
+ tput AF "$PROMPT_COLOR" 0 0
} 2>/dev/null )
;;
@@ -66,9 +58,9 @@ prompt() {
8)
format=$( {
: "${PROMPT_COLOR:=2}"
- tput AF "$PROMPT_COLOR" ||
- tput setaf "$PROMPT_COLOR"
- tput md || tput bold
+ tput setaf "$PROMPT_COLOR" ||
+ tput AF "$PROMPT_COLOR"
+ tput bold || tput md
} 2>/dev/null )
;;
@@ -76,7 +68,7 @@ prompt() {
# use bold
*)
format=$( {
- tput md || tput bold
+ tput bold || tput md
} 2>/dev/null )
;;
esac
@@ -99,17 +91,10 @@ prompt() {
# Git prompt function
git)
- # Bail if we have no git(1)
- if ! hash git 2>/dev/null ; then
- return 1
- fi
-
- # Bail if we're not in a work tree
- local iswt
- iswt=$(git rev-parse --is-inside-work-tree 2>/dev/null)
- if [[ $iswt != true ]] ; then
- return 1
- fi
+ # Bail if we're not in a work tree--or, implicitly, if we don't
+ # have git(1).
+ [[ $(git rev-parse --is-inside-work-tree 2>/dev/null) = true ]] ||
+ return
# Attempt to determine git branch, bail if we can't
local branch
@@ -117,9 +102,7 @@ prompt() {
git symbolic-ref --quiet HEAD ||
git rev-parse --short HEAD
} 2>/dev/null )
- if [[ ! -n $branch ]] ; then
- return 1
- fi
+ [[ -n $branch ]] || return
branch=${branch##*/}
# Refresh index so e.g. git-diff-files(1) is accurate
@@ -129,41 +112,39 @@ prompt() {
local state
# Upstream HEAD has commits after local HEAD; we're "behind"
- (($(git rev-list --count 'HEAD..@{u}' 2>/dev/null) > 0)) &&
- state=${state}\<
+ local -i behind
+ behind=$(git rev-list --count 'HEAD..@{u}' 2>/dev/null)
+ ((behind)) && state=${state}'<'
# Local HEAD has commits after upstream HEAD; we're "ahead"
- (($(git rev-list --count '@{u}..HEAD' 2>/dev/null) > 0)) &&
- state=${state}\>
+ local -i ahead
+ ahead=$(git rev-list --count '@{u}..HEAD' 2>/dev/null)
+ ((ahead)) && state=${state}'>'
# Tracked files are modified
git diff-files --quiet ||
- state=${state}\!
+ state=${state}'!'
# Changes are staged
git diff-index --cached --quiet HEAD ||
- state=${state}\+
+ state=${state}'+'
# There are some untracked and unignored files
[[ -n $(git ls-files --others --exclude-standard) ]] &&
- state=${state}\?
+ state=${state}'?'
# There are stashed changes
git rev-parse --quiet --verify refs/stash >/dev/null &&
- state=${state}\^
+ state=${state}'^'
# Print the status in brackets; add a git: prefix only if there
# might be another VCS prompt (because PROMPT_VCS is set)
- printf '(%s%s%s)' "${PROMPT_VCS:+git:}" "${branch:-unknown}" "$state"
+ printf '(%s%s%s)' \
+ "${PROMPT_VCS:+git:}" "${branch:-unknown}" "$state"
;;
# Subversion prompt function
svn)
- # Bail if we have no svn(1)
- if ! hash svn 2>/dev/null ; then
- return 1
- fi
-
# Determine the repository URL and root directory
local key value url root
while IFS=: read -r key value ; do
@@ -177,10 +158,10 @@ prompt() {
esac
done < <(svn info 2>/dev/null)
- # Exit if we couldn't get either
- if [[ ! -n $url || ! -n $root ]] ; then
- return 1
- fi
+ # Exit if we couldn't get either--or, implicitly, if we don't have
+ # svn(1).
+ [[ -n $url ]] || return
+ [[ -n $root ]] || return
# Remove the root from the URL to get what's hopefully the branch
# name, removing leading slashes and the 'branches' prefix, and any
@@ -204,32 +185,25 @@ prompt() {
# Add appropriate state flags
local -a state
- if ((modified)) ; then
- state[${#state[@]}]='!'
- fi
- if ((untracked)) ; then
- state[${#state[@]}]='?'
- fi
+ ((modified)) && state[${#state[@]}]='!'
+ ((untracked)) && state[${#state[@]}]='?'
# Print the state in brackets with an svn: prefix
- (IFS= ; printf '(svn:%s%s)' "${branch:-unknown}" "${state[*]}")
+ (IFS= ; printf '(svn:%s%s)' \
+ "${branch:-unknown}" "${state[*]}")
;;
# VCS wrapper prompt function; print the first relevant prompt, if any
vcs)
local vcs
for vcs in "${PROMPT_VCS[@]:-git}" ; do
- if prompt "$vcs" ; then
- return
- fi
+ prompt "$vcs" && return
done
;;
# Show return status of previous command in angle brackets, if not zero
ret)
- if ((PROMPT_RETURN > 0)) ; then
- printf '<%u>' "$PROMPT_RETURN"
- fi
+ ((PROMPT_RETURN)) && printf '<%u>' "$PROMPT_RETURN"
;;
# Show the count of background jobs in curly brackets, if not zero
@@ -238,9 +212,12 @@ prompt() {
while read ; do
((jobc++))
done < <(jobs -p)
- if ((jobc > 0)) ; then
- printf '{%u}' "$jobc"
- fi
+ ((jobc)) && printf '{%u}' "$jobc"
+ ;;
+
+ # No argument given, print prompt strings and vars
+ '')
+ declare -p PS1 PS2 PS3 PS4
;;
# Print error
@@ -248,7 +225,6 @@ prompt() {
printf '%s: Unknown command %s\n' "$FUNCNAME" "$1" >&2
return 2
;;
-
esac
}
diff --git a/sh/profile.d/games.sh b/sh/profile.d/games.sh
index b0dd1d35..58db3487 100644
--- a/sh/profile.d/games.sh
+++ b/sh/profile.d/games.sh
@@ -1,4 +1,2 @@
# Add ~/.local/games to PATH if it exists
-if [ -d "$HOME"/.local/games ] ; then
- PATH=$HOME/.local/games:$PATH
-fi
+[ -d "$HOME"/.local/games ] && PATH=$HOME/.local/games:$PATH
diff --git a/sh/profile.d/go.sh b/sh/profile.d/go.sh
deleted file mode 100644
index 86bf9994..00000000
--- a/sh/profile.d/go.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-# Define path for Go code to be installed
-GOPATH=$HOME/.local/gocode
-export GOPATH
-
-# Prepend GOPATH to PATH for the executables if it exists
-if [ -d "$GOPATH"/bin ] ; then
- PATH=$GOPATH/bin:$PATH
-fi
diff --git a/sh/profile.d/grep.sh b/sh/profile.d/grep.sh
deleted file mode 100644
index d1ef3ba1..00000000
--- a/sh/profile.d/grep.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-# Test that we have metadata about what options this system's grep(1) supports,
-# and try to create it if not
-(
- # Create a directory to hold metadata about grep
- gcd=$HOME/.cache/grep
- if ! [ -d "$gcd" ] ; then
- mkdir -p -- "$gcd" || exit
- fi
-
- # Write grep(1)'s --help output to a file, even if it's empty
- if ! [ -f "$gcd"/help ] ; then
- grep --help </dev/null >"$gcd"/help 2>/dev/null || exit
-
- # Iterate through some useful options and create files to show they're
- # available
- set -- binary-files \
- color \
- devices \
- directories \
- exclude \
- exclude-dir
- for opt ; do
- grep -Eq -- --"$opt" "$gcd"/help || continue
- touch -- "$gcd"/"$opt" || exit
- done
- fi
-)
diff --git a/sh/profile.d/keychain.sh b/sh/profile.d/keychain.sh
index 55306ad4..66c23d32 100644
--- a/sh/profile.d/keychain.sh
+++ b/sh/profile.d/keychain.sh
@@ -1,17 +1,9 @@
# ssh-askpass setup
-if command -v ssh-askpass >/dev/null 2>&1 ; then
- SSH_ASKPASS=$(command -v ssh-askpass)
+[ -n "${SSH_ASKPASS:="$(command -v ssh-askpass 2>&1)"}" ] &&
export SSH_ASKPASS
-fi
# keychain setup
-if command -v keychain >/dev/null 2>&1 ; then
+command -v keychain >/dev/null 2>&1 &&
eval "$(TERM=${TERM:-ansi} keychain \
- --eval --ignore-missing --quiet id_dsa id_rsa id_ecsda)"
-
- # Set and export TTY/GPG_TTY for interactive shells
- if [ -t 0 ] ; then
- GPG_TTY=$(tty)
- export GPG_TTY
- fi
-fi
+ --eval --ignore-missing --quick --quiet \
+ id_dsa id_rsa id_ecsda)"
diff --git a/sh/profile.d/ls.sh b/sh/profile.d/ls.sh
deleted file mode 100644
index 0c3754e9..00000000
--- a/sh/profile.d/ls.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-# Test that we have metadata about what options this system's ls(1) supports,
-# and try to create it if not
-(
- # Create a directory to hold metadata about ls(1)
- lcd=$HOME/.cache/ls
- if ! [ -d "$lcd" ] ; then
- mkdir -p -- "$lcd" || exit
- fi
-
- # Write ls(1)'s --help output to a file, even if it's empty
- if ! [ -f "$lcd"/help ] ; then
- ls --help >"$lcd"/help 2>/dev/null || exit
-
- # Iterate through some useful options and create files to show they're
- # available
- if grep -q -- --color "$lcd"/help ; then
- touch -- "$lcd"/color || exit
- fi
- fi
-)
diff --git a/sh/profile.d/options.sh b/sh/profile.d/options.sh
new file mode 100644
index 00000000..aa6bea06
--- /dev/null
+++ b/sh/profile.d/options.sh
@@ -0,0 +1,55 @@
+# Cache the options available to certain programs. Run all this in a subshell
+# (none of its state needs to endure in the session)
+(
+options() { (
+
+ # Check or create the directory to cache the options
+ dir=$HOME/.cache/$1
+
+ # Directory already exists; bail out
+ [ -d "$dir" ] && exit
+
+ # Create the directory
+ mkdir -p -- "$dir" || exit
+ cd -- "$dir" || exit
+
+ # Write grep(1)'s --help output to a file, even if it's empty
+ "$1" --help </dev/null >help 2>/dev/null || exit
+
+ # Shift the program name off; remaining arguments are the options to check
+ shift
+
+ # Iterate through some useful options and create files to show they're
+ # available if found in the help output
+ for opt ; do
+ grep -q -- '[^[:alnum:]]--'"$opt"'[^[:alnum:]]' help &&
+ touch -- "$opt"
+ done
+) ; }
+
+# Cache options for bc(1)
+options bc \
+ quiet
+
+# Cache options for ed(1)
+options ed \
+ verbose
+
+# Cache options for grep(1)
+options grep \
+ binary-files \
+ color \
+ devices \
+ directories \
+ exclude \
+ exclude-dir
+
+# Cache options for ls(1)
+options ls \
+ almost-all \
+ block-size \
+ classify \
+ color \
+ human-readable \
+ time-style
+)
diff --git a/sh/profile.d/verse.sh b/sh/profile.d/verse.sh
index 781d68bc..ef68bb93 100644
--- a/sh/profile.d/verse.sh
+++ b/sh/profile.d/verse.sh
@@ -18,9 +18,7 @@ command -v verse >/dev/null 2>&1 || return
# date); run in a subshell to keep vars out of global namespace
(
now=$(date +%Y-%m-%d)
- if [ -f "$HOME"/.verse ] ; then
- last=$(cat -- "$HOME"/.verse)
- fi
+ [ -f "$HOME"/.verse ] && last=$(cat -- "$HOME"/.verse)
[ "$now" \> "$last" ] || exit
verse
printf '\n'
diff --git a/sh/shrc.d/bc.sh b/sh/shrc.d/bc.sh
index 643678ac..41331ff9 100644
--- a/sh/shrc.d/bc.sh
+++ b/sh/shrc.d/bc.sh
@@ -1,7 +1,14 @@
-# This function is only applicable if bc(1) has the non-POSIX -q option
-command bc -q </dev/null >&0 2>&0 || return
+# Our ~/.profile should already have made a directory with the supported
+# options for us; if not, we won't be wrapping bc(1) with a function at all
+[ -d "$HOME"/.cache/bc ] || return
-# Don't print the bc(1) welcome message
+# Define function proper
bc() {
- command bc -q "$@"
+
+ # Add --quiet to stop the annoying welcome banner
+ [ -e "$HOME"/.cache/bc/quiet ] &&
+ set -- --quiet "$@"
+
+ # Run bc(1) with the concluded arguments
+ command bc "$@"
}
diff --git a/sh/shrc.d/ed.sh b/sh/shrc.d/ed.sh
index 4638d2cb..243dcffc 100644
--- a/sh/shrc.d/ed.sh
+++ b/sh/shrc.d/ed.sh
@@ -1,26 +1,24 @@
-# Add a colon prompt to ed when a command is expected rather than text; makes
-# it feel a lot more like using ex. Only do this when stdin is a terminal,
-# however. Also try and use -v for more verbose error output, and rlwrap(1) if
-# it's available.
+# Define function proper
ed() {
- # We're only adding options if input is from a terminal
- if [ -t 0 ] ; then
+ # Don't mess with original call if input not a terminal
+ if ! [ -t 0 ] ; then
+ command ed "$@"
+ return
+ fi
- # Colon prompt (POSIX)
- set -- -p : "$@"
+ # Add --verbose to explain errors
+ [ -e "$HOME"/.cache/ed/verbose ] &&
+ set -- --verbose "$@"
- # Verbose if available (not POSIX)
- if ed -sv - </dev/null >&0 2>&0 ; then
- set -- -v "$@"
- fi
- fi
+ # Add a colon prompt (POSIX feature)
+ set -- -p: "$@"
- # Execute the ed(1) call, in a wrapper if appropriate and with the
- # concluded options
- if [ -t 0 ] && command -v rlwrap >/dev/null 2>&1 ; then
- command rlwrap ed "$@"
- else
- command ed "$@"
- fi
+ # Run in rlwrap(1) if available
+ set -- ed "$@"
+ command -v rlwrap >/dev/null 2>&1 &&
+ set -- rlwrap "$@"
+
+ # Run determined command
+ command "$@"
}
diff --git a/sh/shrc.d/grep.sh b/sh/shrc.d/grep.sh
index 2f360716..2ccaed69 100644
--- a/sh/shrc.d/grep.sh
+++ b/sh/shrc.d/grep.sh
@@ -5,15 +5,15 @@
# Define function proper
grep() {
+ # Add --binary-files=without-match to gracefully skip binary files
+ [ -e "$HOME"/.cache/grep/binary-files ] &&
+ set -- --binary-files=without-match "$@"
+
# Add --color if the terminal has at least 8 colors
[ -e "$HOME"/.cache/grep/color ] &&
[ "$({ tput colors || tput Co ; } 2>/dev/null)" -ge 8 ] &&
set -- --color=auto "$@"
- # Add --binary-files=without-match to gracefully skip binary files
- [ -e "$HOME"/.cache/grep/binary-files ] &&
- set -- --binary-files=without-match "$@"
-
# Add --devices=skip to gracefully skip devices
[ -e "$HOME"/.cache/grep/devices ] &&
set -- --devices=skip "$@"
diff --git a/sh/shrc.d/keychain.sh b/sh/shrc.d/keychain.sh
index 82f83473..e625d704 100644
--- a/sh/shrc.d/keychain.sh
+++ b/sh/shrc.d/keychain.sh
@@ -1,3 +1,4 @@
-# If GPG_TTY is set, update it
-[ -n "$GPG_TTY" ] || return
+# If GPG_AGENT_INFO is set, update GPG_TTY for clean use of pinentry(1) etc
+[ -n "$GPG_AGENT_INFO" ] || return
GPG_TTY=$(tty)
+export GPG_TTY
diff --git a/sh/shrc.d/la.sh b/sh/shrc.d/la.sh
new file mode 100644
index 00000000..e21ad8fb
--- /dev/null
+++ b/sh/shrc.d/la.sh
@@ -0,0 +1,10 @@
+# Run ls -A if we can (-A is not POSIX), ls -a otherwise
+la() {
+ # Prefer --almost-all (exclude "." and "..") if available
+ if [ -e "$HOME"/.cache/ls/almost-all ] ; then
+ set -- -A "$@"
+ else
+ set -- -a "$@"
+ fi
+ ls "$@"
+}
diff --git a/sh/shrc.d/ll.sh b/sh/shrc.d/ll.sh
new file mode 100644
index 00000000..c8c95d3b
--- /dev/null
+++ b/sh/shrc.d/ll.sh
@@ -0,0 +1,10 @@
+# Run ls -Al if we can (-A is not POSIX), ls -al otherwise
+ll() {
+ # Prefer -A/--almost-all (exclude "." and "..") if available
+ if [ -e "$HOME"/.cache/ls/almost-all ] ; then
+ set -- -Al "$@"
+ else
+ set -- -al "$@"
+ fi
+ ls "$@"
+}
diff --git a/sh/shrc.d/ls.sh b/sh/shrc.d/ls.sh
index eec25eb7..8fd42431 100644
--- a/sh/shrc.d/ls.sh
+++ b/sh/shrc.d/ls.sh
@@ -5,11 +5,24 @@
# Define function proper
ls() {
+ # Add --block-size=K to always show the filesize in kibibytes
+ [ -e "$HOME"/.cache/ls/block-size ] &&
+ set -- --block-size=K "$@"
+
+ # Add --classify to show trailing indicators of the filetype
+ [ -e "$HOME"/.cache/ls/classify ] &&
+ set -- --classify "$@"
+
# Add --color if the terminal has at least 8 colors
[ -e "$HOME"/.cache/ls/color ] &&
[ "$({ tput colors || tput Co ; } 2>/dev/null)" -ge 8 ] &&
set -- --color=auto "$@"
+ # Add --time-style='+%Y-%m-%d %H:%M:%S' to show trailing indicators of the
+ # filetype
+ [ -e "$HOME"/.cache/ls/time-style ] &&
+ set -- --time-style='+%Y-%m-%d %H:%M:%S' "$@"
+
# Run ls(1) with the concluded arguments
command ls "$@"
}