diff options
-rw-r--r-- | bash/aliases.bash | 20 | ||||
-rw-r--r-- | bash/bashrc | 2 | ||||
-rw-r--r-- | bash/functions.bash | 166 | ||||
-rw-r--r-- | bash/history.bash | 38 | ||||
-rw-r--r-- | bash/prompt.bash | 56 | ||||
-rw-r--r-- | bash/vterm-emacs.bash | 23 |
6 files changed, 201 insertions, 104 deletions
diff --git a/bash/aliases.bash b/bash/aliases.bash index e29f62a..0132d33 100644 --- a/bash/aliases.bash +++ b/bash/aliases.bash | |||
@@ -20,17 +20,27 @@ alias ll='ls -l' | |||
20 | alias tree='tree -F' | 20 | alias tree='tree -F' |
21 | 21 | ||
22 | # make locally | 22 | # make locally |
23 | alias lake='make PREFIX=$HOME/usr ' | 23 | alias lake='make PREFIX=$LOCAL_PATH ' |
24 | 24 | ||
25 | # bash meta | 25 | # bash meta |
26 | alias rebash='source ~/.bash_profile' | 26 | alias rebash='source ~/.bash_profile' |
27 | 27 | ||
28 | # Debugging | ||
29 | alias emacs_goddamnit='pushd ~/.emacs.d;emacs --debug-init;popd' | ||
30 | |||
31 | # other | 28 | # other |
32 | alias radio=radish | 29 | alias radio=radish |
33 | if ! command -v fd >/dev/null 2>&1; then | 30 | |
31 | # `fd' installs as `fdfind' on some systems | ||
32 | if ! command -v fd >/dev/null 2>&1 && | ||
33 | command -v fdfind >/dev/null 2>&1 | ||
34 | then | ||
34 | alias fd=fdfind | 35 | alias fd=fdfind |
35 | fi | 36 | fi |
36 | 37 | ||
38 | alias e="$EDITOR" | ||
39 | |||
40 | ## ffmpeg | ||
41 | # agafnd | i have ffmpeg and ffprobe aliased to ffwhatever -hide_banner | ||
42 | # agafnd | because if you don't do this it spits out all of the options it was | ||
43 | # | configured with every time you run it | ||
44 | |||
45 | alias ffmpeg='ffmpeg -hide_banner' | ||
46 | alias ffprobe='ffprobe -hide_banner' | ||
diff --git a/bash/bashrc b/bash/bashrc index 63e56d4..9409c78 100644 --- a/bash/bashrc +++ b/bash/bashrc | |||
@@ -10,7 +10,7 @@ BASH_SOURCE_FIRST=( | |||
10 | 10 | ||
11 | BASH_SOURCE_LAST=( | 11 | BASH_SOURCE_LAST=( |
12 | blesh | 12 | blesh |
13 | vterm-emacs | 13 | emacs |
14 | ) | 14 | ) |
15 | 15 | ||
16 | for f in "${BASH_SOURCE_FIRST[@]}"; do | 16 | for f in "${BASH_SOURCE_FIRST[@]}"; do |
diff --git a/bash/functions.bash b/bash/functions.bash index 64e8001..97f89b8 100644 --- a/bash/functions.bash +++ b/bash/functions.bash | |||
@@ -1,89 +1,141 @@ | |||
1 | # Functions | 1 | # Functions |
2 | 2 | ||
3 | memq() { # memq ITEM ARRAY | 3 | memq() { # memq ITEM ARRAY |
4 | ## Test whether an ITEM is a member of ARRAY. | 4 | ## Test whether an ITEM is a member of ARRAY. |
5 | ## Pass ARRAY as ${ARRAY[@]}. | 5 | ## Pass ARRAY as ${ARRAY[@]}. |
6 | local e needle="$1" | 6 | local e needle="$1" |
7 | shift | 7 | shift |
8 | for e; do | 8 | for e; do |
9 | [[ "$e" == "$needle" ]] && { | 9 | [[ "$e" == "$needle" ]] && { |
10 | return 0 | 10 | return 0 |
11 | } | 11 | } |
12 | done | 12 | done |
13 | return 1 | 13 | return 1 |
14 | } | 14 | } |
15 | 15 | ||
16 | rebashrc() { # rebashrc | 16 | rebashrc() { # rebashrc |
17 | ## Reload ~/.bashrc | 17 | ## Reload ~/.bashrc |
18 | printf "Loading ~/.bashrc..." >&2 | 18 | printf "Loading ~/.bashrc..." >&2 |
19 | if source "$HOME/.bashrc"; then | 19 | if source "$HOME/.bashrc"; then |
20 | echo "OK." >&2 | 20 | echo "OK." >&2 |
21 | else | 21 | else |
22 | echo "ERROR!" >&2 | 22 | echo "ERROR!" >&2 |
23 | fi | 23 | fi |
24 | } | 24 | } |
25 | 25 | ||
26 | first_which() { # first_which COMMAND... | 26 | first_which() { # first_which COMMAND... |
27 | ## Return the fully-qualified path of the first COMMAND found in $PATH. | 27 | ## Return the fully-qualified path of the first COMMAND found in $PATH. |
28 | while :; do | 28 | while :; do |
29 | command -v "$1" && break | 29 | command -v "$1" && break |
30 | [ -z "$1" ] && return 1 | 30 | [ -z "$1" ] && return 1 |
31 | shift | 31 | shift |
32 | done | 32 | done |
33 | } | 33 | } |
34 | 34 | ||
35 | please() { # please [COMMAND...] | 35 | please() { # please [COMMAND...] |
36 | # if run without arguments, run the last command with 'sudo' (aka sudo !!) | 36 | # if run without arguments, run the last command with 'sudo' (aka sudo !!) |
37 | # if run WITH arguments, alias as sudo | 37 | # if run WITH arguments, alias as sudo |
38 | history -d -1 | 38 | history -d -1 |
39 | if [ -z "$1" ]; then | 39 | if [ -z "$1" ]; then |
40 | #set -- $(HISTTIMEFORMAT=$'\t' history 2 | sed 's/^.*\t//;q') | 40 | #set -- $(HISTTIMEFORMAT=$'\t' history 2 | sed 's/^.*\t//;q') |
41 | set -- $(fc -lnr | sed 1q) | 41 | set -- $(fc -lnr | sed 1q) |
42 | fi | 42 | fi |
43 | echo >&2 sudo "$@" | 43 | echo >&2 sudo "$@" |
44 | history -s sudo "$@" | 44 | history -s sudo "$@" |
45 | "${DEBUG:-false}" || sudo "$@" | 45 | "${DEBUG:-false}" || sudo "$@" |
46 | } | 46 | } |
47 | 47 | ||
48 | mkcd() { | 48 | mkcd() { |
49 | if [ $# -lt 1 ]; then | 49 | if [ $# -lt 1 ]; then |
50 | command cd | 50 | command cd |
51 | return "$?" | 51 | return "$?" |
52 | fi | 52 | fi |
53 | if [ "x$1" = x- ]; then | 53 | if [ "x$1" = x- ]; then |
54 | command cd - | 54 | command cd - |
55 | return "$?" | 55 | return "$?" |
56 | fi | 56 | fi |
57 | if ! [ -d "$1" ]; then | 57 | if ! [ -d "$1" ]; then |
58 | read -p "$1 doesn't exist. Create (y/N)? " yn | 58 | read -p "$1 doesn't exist. Create (y/N)? " yn |
59 | case "$yn" in | 59 | case "$yn" in |
60 | n* | N*) return 1 ;; | 60 | n* | N*) return 1 ;; |
61 | y* | Y*) mkdir -p "$1" ;; | 61 | y* | Y*) mkdir -p "$1" ;; |
62 | *) return 1 ;; | 62 | *) return 1 ;; |
63 | esac | 63 | esac |
64 | fi | 64 | fi |
65 | command cd "$1" | 65 | command cd "$1" |
66 | } | 66 | } |
67 | alias cd='mkcd ' | 67 | alias cd='mkcd ' |
68 | 68 | ||
69 | # from tomasino | 69 | # from tomasino |
70 | # alias julian='echo "x = $(date +%s); scale=5; x / 86400 + 2440587.5" | bc' | 70 | # alias julian='echo "x = $(date +%s); scale=5; x / 86400 + 2440587.5" | bc' |
71 | julian() { | 71 | julian() { |
72 | echo "x = $(date ${1:+-d "$*"} +%s); scale=5; x / 86400 + 2440587.5" | bc | 72 | echo "x = $(date ${1:+-d "$*"} +%s); scale=5; x / 86400 + 2440587.5" | bc |
73 | } | 73 | } |
74 | 74 | ||
75 | # find files for pipelines | 75 | # find files for pipelines |
76 | f() { | 76 | f() { |
77 | find "${1:-$PWD}" -depth | | 77 | find "${1:-$PWD}" -depth | |
78 | while read -r file; do | 78 | while read -r file; do |
79 | printf '%q\n' "$file" | 79 | printf '%q\n' "$file" |
80 | done | 80 | done |
81 | } | 81 | } |
82 | 82 | ||
83 | words() { | 83 | words() { |
84 | grep "$1" /usr/share/dict/words | 84 | grep "$1" /usr/share/dict/words |
85 | } | 85 | } |
86 | 86 | ||
87 | dict() { | 87 | if ! command -v dict >/dev/null 2>&1; then |
88 | curl "dict://dict.org/d:$1" | less | 88 | dict() { |
89 | curl "dict://dict.org/d:$1" | less | ||
90 | } | ||
91 | fi | ||
92 | |||
93 | if command -v thesauracles >/dev/null 2>&1; then | ||
94 | thesauraphrase() { | ||
95 | for word in "$@"; do | ||
96 | thesauracles -q "$word" | ||
97 | done | tr '\n' ' ' | ||
98 | echo | ||
99 | } | ||
100 | fi | ||
101 | |||
102 | up() { | ||
103 | : "${UP_TODIRECTORY:=..}" | ||
104 | : "${UP_SPECIALARGS:=true}" | ||
105 | local ret=0 | ||
106 | # echo "$UP_TODIRECTORY" "$UP_SPECIALARGS" | ||
107 | if "$UP_SPECIALARGS"; then | ||
108 | case "$1" in | ||
109 | '') cd "$UP_TODIRECTORY" ;; | ||
110 | up) UP_TODIRECTORY="${UP_TODIRECTORY}/.." up "${@:2}" ;; | ||
111 | --) UP_SPECIALARGS=false up "${@:2}" ;; | ||
112 | -*) if (( "$1" == -1 )); then | ||
113 | up | ||
114 | else | ||
115 | UP_TODIRECTORY="${UP_TODIRECTORY}/.." up $(( "$1" + 1 )) | ||
116 | fi | ||
117 | ;; | ||
118 | *) while cd ..; do | ||
119 | case "$PWD" in | ||
120 | /) ret=1; break ;; | ||
121 | */"$1") break ;; | ||
122 | esac | ||
123 | done | ||
124 | ;; | ||
125 | esac | ||
126 | else | ||
127 | case "$1" in | ||
128 | '') cd "$UP_TODIRECTORY" ;; | ||
129 | *) while cd ..; do | ||
130 | case "$PWD" in | ||
131 | /) ret=1; break ;; | ||
132 | */"$1") break ;; | ||
133 | esac | ||
134 | done | ||
135 | ;; | ||
136 | esac | ||
137 | fi | ||
138 | UP_TODIRECTORY= | ||
139 | UP_SPECIALARGS= | ||
140 | return "$ret" | ||
89 | } | 141 | } |
diff --git a/bash/history.bash b/bash/history.bash index 95edf9d..d2bdceb 100644 --- a/bash/history.bash +++ b/bash/history.bash | |||
@@ -1,5 +1,5 @@ | |||
1 | # Bash history settings | 1 | # Bash history settings |
2 | # I don't export any variables in this file because history settings | 2 | # I don't export any variables in this file because history settings |
3 | # really only apply in an interactive session. | 3 | # really only apply in an interactive session. |
4 | 4 | ||
5 | # XDG compliance | 5 | # XDG compliance |
@@ -33,3 +33,39 @@ HISTIGNORE="$HISTIGNORE:ls:exit:cd" | |||
33 | 33 | ||
34 | # Automatically append to HISTFILE on every command | 34 | # Automatically append to HISTFILE on every command |
35 | PROMPT_COMMAND="history -a; ${PROMPT_COMMAND:-:}" | 35 | PROMPT_COMMAND="history -a; ${PROMPT_COMMAND:-:}" |
36 | |||
37 | ## Make a new function from a history item: WIP | ||
38 | # In particular, the arguments of this function could be better imo | ||
39 | histfunc() { # histfunc NAME QUERY | ||
40 | local name="$1" | ||
41 | local query="$2" | ||
42 | local -a cands | ||
43 | while read -r cmd; do | ||
44 | cands=( "${cands[@]}" "$cmd" ) | ||
45 | done < <(grep -E "$query" "$HISTFILE" | sort | uniq) | ||
46 | if (( "${#cands[@]}" == 1 )); then | ||
47 | funcbody="${cands[0]}" | ||
48 | else | ||
49 | select funcbody in "${cands[@]}"; do break; done | ||
50 | fi | ||
51 | eval "$name() { $funcbody; }" | ||
52 | } | ||
53 | |||
54 | funcsave() { # funcsave FUNC FILENAME | ||
55 | (( $# == 2 )) || { | ||
56 | echo "Wrong number of arguments (need 2)" >&2 | ||
57 | return 1 | ||
58 | } | ||
59 | cat <<EOF > "$2" | ||
60 | #!/usr/bin/env bash | ||
61 | # saved with 'funcsave' | ||
62 | |||
63 | $(type "$1" | sed 1d) | ||
64 | |||
65 | if [[ "\${BASH_SOURCE[0]}" == "\$0" ]]; then | ||
66 | [[ "\$DEBUG" ]] && set -x | ||
67 | "$1" "\$@" | ||
68 | fi | ||
69 | EOF | ||
70 | chmod +x "$2" | ||
71 | } | ||
diff --git a/bash/prompt.bash b/bash/prompt.bash index 06ca638..f09d3ab 100644 --- a/bash/prompt.bash +++ b/bash/prompt.bash | |||
@@ -1,8 +1,32 @@ | |||
1 | # bash prompt | 1 | # bash prompt |
2 | 2 | ||
3 | if [[ -n "$INSIDE_EMACS" ]]; then | 3 | MY_BASH_PROMPT=smiley_prompt |
4 | PS1="\n\[\e[34m\]\$ \[\e[0m\]" | 4 | |
5 | else | 5 | # terminal title (current directory) |
6 | __prompt_term_title() { # __prompt_term_title TITLE... | ||
7 | printf '\033]0;%s\007\n' "$*" | ||
8 | } | ||
9 | |||
10 | __prompt_exit_code() { # __prompt_exit_code CODES... | ||
11 | # Each CODE is of the form N=STR. If the code doesn't match one of CODES, | ||
12 | # its number will be printed. | ||
13 | local ec=$? | ||
14 | for code; do | ||
15 | if ((ec == ${code%=*})); then | ||
16 | printf '%s\n' "${code#*=}" | ||
17 | return | ||
18 | elif ((ec == 0)) && [[ "${code%=*}" = ok ]]; then | ||
19 | printf '%s\n' "${code#*=}" | ||
20 | return | ||
21 | elif ((ec > 0)) && [[ "${code%=*}" = fail ]]; then | ||
22 | printf '%s\n' "${code#*=}" | ||
23 | return | ||
24 | fi | ||
25 | done | ||
26 | printf '%s\n' "$ec" | ||
27 | } | ||
28 | |||
29 | two_line_prompt() { | ||
6 | PS1= | 30 | PS1= |
7 | 31 | ||
8 | # user, host, and cwd | 32 | # user, host, and cwd |
@@ -21,7 +45,7 @@ else | |||
21 | for file in "${possible_git_prompt_locations[@]}"; do | 45 | for file in "${possible_git_prompt_locations[@]}"; do |
22 | if [[ -f "$file" ]]; then | 46 | if [[ -f "$file" ]]; then |
23 | source "$file" && | 47 | source "$file" && |
24 | PS1+='\[\e[35m\]$(__git_ps1)' | 48 | PS1+='\[\e[0m\]\[\e[35m\]$(__git_ps1)' |
25 | break | 49 | break |
26 | fi | 50 | fi |
27 | done | 51 | done |
@@ -29,20 +53,18 @@ else | |||
29 | # newline | 53 | # newline |
30 | PS1+='\[\e[0m\]\n' | 54 | PS1+='\[\e[0m\]\n' |
31 | 55 | ||
32 | # exit code (only if error) | 56 | PS1+='\[\e[31m\]$(__prompt_exit_code 0=)\[\e[0m\]' |
33 | __prompt_exit_code() { | ||
34 | local ec=$? | ||
35 | (($ec > 0)) && | ||
36 | printf "$ec" | ||
37 | } | ||
38 | PS1+='\[\e[31m\]$(__prompt_exit_code)\[\e[0m\]' | ||
39 | |||
40 | # terminal title (current directory) | ||
41 | __prompt_term_title() { | ||
42 | printf '\033]0;%s\007\n' "$*" | ||
43 | } | ||
44 | PS1+='\[$(__prompt_term_title "$USER@$(hostname): $PWD")\]' | 57 | PS1+='\[$(__prompt_term_title "$USER@$(hostname): $PWD")\]' |
45 | 58 | ||
46 | # delimiter | 59 | # delimiter |
47 | PS1+='; ' | 60 | PS1+='; ' |
48 | fi | 61 | } |
62 | |||
63 | smiley_prompt() { | ||
64 | __prompt_ec() { case $? in 0) echo '^_^' ;; *) echo ';_;' ;; esac } | ||
65 | PS1='\[\e[1m\]$(__prompt_exit_code "ok=^_^" "fail=;_;") \w\[\e[0m\] ' | ||
66 | PS1+='\[$(__prompt_term_title "$USER@$(hostname): $PWD")\]' | ||
67 | PS1+='\$ ' | ||
68 | } | ||
69 | |||
70 | eval "$MY_BASH_PROMPT" | ||
diff --git a/bash/vterm-emacs.bash b/bash/vterm-emacs.bash deleted file mode 100644 index 88d3e09..0000000 --- a/bash/vterm-emacs.bash +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | # shell-side configuration for Emacs vterm module | ||
2 | # https://github.com/akermu/emacs-libvterm#shell-side-configuration | ||
3 | # Make sure this is the last file loaded by ~/.bashrc! | ||
4 | |||
5 | # Load the requisite code from the vterm install directory | ||
6 | if [[ "$INSIDE_EMACS" = 'vterm' ]] \ | ||
7 | && [[ -n ${EMACS_VTERM_PATH} ]] \ | ||
8 | && [[ -f ${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh ]]; then | ||
9 | source ${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh | ||
10 | fi | ||
11 | |||
12 | # Extra commands for `vterm-eval-cmds' | ||
13 | |||
14 | find_file() { | ||
15 | vterm_cmd find-file "$(realpath "${@:-.}")" | ||
16 | } | ||
17 | |||
18 | say() { | ||
19 | vterm_cmd message "%s" "$*" | ||
20 | } | ||
21 | |||
22 | |||
23 | |||