diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-21 23:56:03 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2016-08-21 23:56:03 +1200 |
commit | f9e350e135585e9df31c17a65364367601bbe1f5 (patch) | |
tree | 471bff90e99b06a13c15c6a328d57eeace0fbb1b | |
parent | Port Bash Git prompt changes to pdksh (diff) | |
parent | Remove double-up import of completions (diff) | |
download | dotfiles-f9e350e135585e9df31c17a65364367601bbe1f5.tar.gz dotfiles-f9e350e135585e9df31c17a65364367601bbe1f5.zip |
Merge branch 'master' into openbsd
-rw-r--r-- | README.markdown | 15 | ||||
-rw-r--r-- | bash/bash_completion.d/bash.bash | 38 | ||||
-rw-r--r-- | bash/bash_logout | 14 | ||||
-rw-r--r-- | bash/bash_profile | 21 | ||||
-rw-r--r-- | bash/bashrc | 30 | ||||
-rw-r--r-- | bash/bashrc.d/completion.bash | 60 | ||||
-rw-r--r-- | bash/bashrc.d/keep.bash | 15 | ||||
-rw-r--r-- | bash/bashrc.d/prompt.bash | 110 | ||||
-rw-r--r-- | sh/profile.d/games.sh | 4 | ||||
-rw-r--r-- | sh/profile.d/go.sh | 8 | ||||
-rw-r--r-- | sh/profile.d/grep.sh | 27 | ||||
-rw-r--r-- | sh/profile.d/keychain.sh | 16 | ||||
-rw-r--r-- | sh/profile.d/ls.sh | 20 | ||||
-rw-r--r-- | sh/profile.d/options.sh | 55 | ||||
-rw-r--r-- | sh/profile.d/verse.sh | 4 | ||||
-rw-r--r-- | sh/shrc.d/bc.sh | 15 | ||||
-rw-r--r-- | sh/shrc.d/ed.sh | 38 | ||||
-rw-r--r-- | sh/shrc.d/grep.sh | 8 | ||||
-rw-r--r-- | sh/shrc.d/keychain.sh | 5 | ||||
-rw-r--r-- | sh/shrc.d/la.sh | 10 | ||||
-rw-r--r-- | sh/shrc.d/ll.sh | 10 | ||||
-rw-r--r-- | sh/shrc.d/ls.sh | 13 |
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 "$@" } |