aboutsummaryrefslogtreecommitdiff
path: root/bash
diff options
context:
space:
mode:
Diffstat (limited to 'bash')
-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
7 files changed, 122 insertions, 166 deletions
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
}