-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.bash_behavior
160 lines (143 loc) · 7.16 KB
/
.bash_behavior
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# shellcheck shell=bash
# This is sourced from `.bash_aliases` under interactive bash; see notes there.
# Interactive mode for incomplete `aws` commands (like `aws --cli-auto-prompt`).
# In contrast to using Bash completion, incomplete commands that trigger the AWS
# CLI interactive mode are added to Bash Readline history whereas the finalized
# commands are added to the Readline history inside the interactive mode itself,
# which can be seen via `jq .commands ~/.aws/cli/cache/prompt_history.json`.
export AWS_CLI_AUTO_PROMPT=on-partial
export EDITOR=vi # safe fallback, even on BusyBox systems
if command -v vim &>/dev/null; then
EDITOR=vim
fi
# Increase bash history size; see dotfiles `install.sh` fixes to `~/.bashrc`.
HISTSIZE=100000
HISTFILESIZE=500000
# Improve `less` paging. In `git` operations, `FRX` (`--quit-if-one-screen`,
# `--RAW-CONTROL-CHARS`, and `--no-init`) is exported if `LESS` is not set (see
# notes for `core.pager` on `man git-config`).
__ccdotfiles_less=(
--chop-long-lines # must scroll horizontally to see remainder of long lines
--ignore-case # can use uppercase in pattern for a case-sensitive search
--LONG-PROMPT # see visible line numbers and, if known, total line count
# --mouse # scrollwheel under `--no-init`, but breaks text selection
# --no-init # do not clear screen before and after pager usage
--quit-if-one-screen
--RAW-CONTROL-CHARS
)
export LESS="${__ccdotfiles_less[*]}"
unset __ccdotfiles_less
# Avail `nvm` and automatically activate Node environment as given by `.nvmrc`
# files. `NVM_DIR` can be specified explicitly elsewhere, like machine-specific
# not-version-controlled `~/.profile` file to make it visible higher in process
# tree (e.g. to desktop environment apps), but elsewise will be automatically
# detected and set here if nvm is in the normal place. Under GitHub Codespaces,
# `nvm` is already available and installed to `~/.nvm`, and NVS is the preferred
# way of doing things anyway, so just skip this setup if running in Codespaces.
if [[ ! -v CODESPACES ]]; then
[[ ! -v NVM_DIR && -d ~/.nvm && -f ~/.nvm/nvm.sh ]] && export NVM_DIR=~/.nvm
if
# shellcheck source=/dev/null
[[ -v NVM_DIR && -d "$NVM_DIR" && -f "$NVM_DIR/nvm.sh" ]] &&
source "$NVM_DIR/nvm.sh" --no-use # skip `default` environment activation
then
# Explicitly call `nvm use` when `.nvmrc` is present or version it has
# changes (due to, e.g., changing directories, moving git `HEAD`, altering
# contents manually). Calling `nvm use` explicitly also prints activated
# environment and triggering `.nvmrc`. This is one of *many* ways to do
# this; see <https://github.com/nvm-sh/nvm#deeper-shell-integration>.
function __ccdotfiles_promptCommandNvmrc() {
local nvmrc
nvmrc=$(nvm_find_nvmrc)
local version
[ -n "$nvmrc" ] && version=$(<"$nvmrc")
if [ -n "$version" ]; then
if [ "$version" != "$__ccdotfiles_promptCommandNvmrc_last" ]; then
nvm use
__ccdotfiles_promptCommandNvmrc_last=$version
fi
elif [ -n "$__ccdotfiles_promptCommandNvmrc_last" ]; then
nvm deactivate
unset __ccdotfiles_promptCommandNvmrc_last
fi
}
[[ $PROMPT_COMMAND =~ __ccdotfiles_promptCommandNvmrc ]] ||
PROMPT_COMMAND="__ccdotfiles_promptCommandNvmrc; $PROMPT_COMMAND"
fi
fi
# Avail `pyenv`, possibly lazily. Once `pyenv` is activated, it stays activated.
[[ ! -v PYENV_ROOT && -x $HOME/.pyenv/bin/pyenv ]] && export PYENV_ROOT=$HOME/.pyenv
if [[ -v PYENV_ROOT && -x $PYENV_ROOT/bin/pyenv ]] && ! command -v pyenv >/dev/null; then
function pyenv() {
unset pyenv __ccdotfiles_promptCommandPyenv
PROMPT_COMMAND="${PROMPT_COMMAND/__ccdotfiles_promptCommandPyenv;/}"
if ! [[ ":$PATH:" == *":$PYENV_ROOT/bin:"* ]]; then
echo "Adding $PYENV_ROOT/bin to PATH for terminal session" >&2
PATH="$PYENV_ROOT/bin:$PATH"
fi
echo 'Initializing pyenv shell integration for terminal session' >&2
eval "$(command pyenv init -)" # creates another `pyenv` shell function
pyenv "$@"
}
if [[ -f $PWD/.python-version ]]; then # load immediately
echo "Starting at $PWD with .python-version" >&2
pyenv version
else # load upon seeing `.python-version` *or* explicit invocation by user
function __ccdotfiles_promptCommandPyenv() {
[[ -f $PWD/.python-version ]] || return
echo "Now at $PWD with .python-version" >&2
pyenv version
}
[[ $PROMPT_COMMAND =~ __ccdotfiles_promptCommandPyenv ]] ||
PROMPT_COMMAND="__ccdotfiles_promptCommandPyenv;$PROMPT_COMMAND"
fi
fi
# Perform enhancements to the `PS1` bash prompt. Hints and suggestions:
#
# - avoid newlines, e.g.: `less` with `--quit-if-one-screen` assumes prompt that
# follows won't be multiline, and similarly, if using `--no-init` to avoid
# clearing the screen, the first line of on-screen text would be scrolled away
# if prompt is multiline
# - when using escape sequences, start these with `\[` and end with `\]` so the
# width of the prompt is correctly calculated and navigation keys (e.g. up,
# down, home) behave properly
# - such delimitation needs to be in the PS1 itself; doing it inside of a
# variable or in command output substitution won't work
# - try to avoid using `PROMPT_COMMAND`
# - reading variables like `PIPESTATUS` from a `PROMPT_COMMAND` might not work
# when using tools that insert themselves into the `PROMPT_COMMAND`, like
# Visual Studio Code's terminal integration features
# - similarly, some people like building the `PS1` string from scratch each
# time before display using a `PROMPT_COMMAND`, but doing this can clobber
# helpful information set by some tools, e.g. Python `virtualenv` activation
# prepends onto the `PS1` variable
# - some environments, like Codespaces, will provide their own fancy `PS1`, so
# sniffing for things before adding them can sometimes prevent duplication
# Given a regular bash prompt ending in '$ ' that doesn't already try to do
# something git-related, if we have `__git_ps1` *or* it appears that we *will*
# have it (as on Ubuntu, where `/etc/bash_completion.d/git-prompt` sources
# `/usr/lib/git-core/git-sh-prompt`, which happens later after we're done here),
# call out to include git info in the prompt whenever in a repository and also
# change the appearance of the trailing '$ ' to differentiate from the git info.
if [[ $PS1 == *'\$ ' && $PS1 != *'git'* ]] &&
(
command -v __git_ps1 &>/dev/null ||
[ -f /etc/bash_completion.d/git-prompt ] && [ -f /usr/lib/git-core/git-sh-prompt ]
); then
function __ccdotfiles_ps1Git {
if command -v __git_ps1 &>/dev/null; then
GIT_PS1_SHOWDIRTYSTATE=1 GIT_PS1_SHOWSTASHSTATE=1 \
GIT_PS1_SHOWUNTRACKEDFILES=1 GIT_PS1_SHOWUPSTREAM=auto __git_ps1 ' %s'
fi
}
PS1=${PS1/%'\$ '/'\[\e[1;33m\]'\$(__ccdotfiles_ps1Git)'\[\e[3;37m\]\$\[\e[0m\] '}
fi
# Include exit status at the beginning of the prompt. If most recent command was
# a pipeline, display the exit statuses of the individual processes.
function __ccdotfiles_ps1Exit {
local statuses="${PIPESTATUS[*]}"
if ! [[ $statuses =~ ^0( 0)*$ ]]; then
echo "${statuses// /│} "
fi
}
PS1='\[\e[1;91m\]$(__ccdotfiles_ps1Exit)\[\e[0m\]'"$PS1"