Eric Bower
·
2026-06-16
1set --brace-expand # bash-like extended exp
2set --extended-glob # recursive pathname exp
3set --no-clobber # prevent redirections from overwriting existing files
4set --no-unset # don't expand non-existent variables to empty strings
5set --hist-space # don't save cmds starting with a space in history
6set --notify-le # print job status update asap while line-editing
7set --le-no-conv-meta # terminfo data broken; meta flags ignore utf-8
8set --le-predict # enable line prediction
9set -o vi # vim mode
10
11bindkey --vi-insert '\^F' accept-prediction
12
13sh() { yash --posix "$@"; }
14yash() { command yash "$@"; }
15
16if [ "${COLORTERM-}" = "truecolor" ] || [ "${COLORTERM-}" = "24bit" ] || \
17 [ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]; then
18 ls() { command ls --color=auto "$@"; }
19 grep() { command grep --color=auto "$@"; }
20fi
21
22: ${LOGNAME:=$(logname)} ${HOSTNAME:=$(uname -n)}
23# disable confusing treatment of arguments in the echo command
24: ${ECHO_STYLE:=RAW}
25
26if ! [ "${HISTFILE-}" ]; then
27 HISTFILE=${XDG_STATE_HOME:-~/.local/state}/yash/history
28fi
29# create HISTFILE parent directory if missing
30! [ -d "${HISTFILE%/*}" ] && mkdir -p "${HISTFILE%/*}"
31
32HISTSIZE=5000
33
34# default mail check interval is too long
35MAILCHECK=0
36
37# emulate bash's $SHLVL
38if [ "${_old_shlvl+set}" != set ]; then
39 _old_shlvl=${SHLVL-}
40fi
41SHLVL=$((_old_shlvl+1)) 2>/dev/null || SHLVL=1
42export SHLVL
43
44# initialize event handlers
45COMMAND_NOT_FOUND_HANDLER=()
46PROMPT_COMMAND=()
47POST_PROMPT_COMMAND=()
48YASH_AFTER_CD=()
49
50# define prompt
51if [ -n "${SSH_CONNECTION-}" ]; then
52 _hc='\fy.' # yellow hostname for SSH remote
53else
54 _hc='\fg.' # green hostname for local
55fi
56if [ "$(id -u)" -eq 0 ]; then
57 _uc='\fr.' # red username for root
58 _2c='\fr.' # red PS2 for root
59else
60 _uc=$_hc _hc= # same username color as hostname for non-root user
61 _2c= # PS2 in normal color for non-root user
62fi
63# The main prompt ($YASH_PS1) contains the username, hostname, working
64# directory, last exit status (only if non-zero), and $SHLVL (only if
65# non-one).
66YASH_PS1=$_uc'${LOGNAME}'$_hc'@${HOSTNAME%%.*}\fd. '\
67'${${${PWD:/~/\~}##*/}:-$PWD} ${{?:/0/}:+\\fr.$?\\fd. }${{SHLVL-0}:/1}\$ '
68YASH_PS1S='\fo.'
69YASH_PS2=$_2c'> '
70YASH_PS2S=$YASH_PS1S
71YASH_PS4='\fm.+ '
72YASH_PS4S='\fmo.'
73unset _hc _uc _2c
74# No escape sequences allowed in the POSIXly-correct mode.
75PS1='${LOGNAME}@${HOSTNAME%%.*} '$PS1
76
77# find escape sequence to change terminal window title
78case "$TERM" in
79 (xterm|xterm[+-]*|gnome|gnome[+-]*|putty|putty[+-]*|cygwin)
80 _tsl='\033];' _fsl='\a' ;;
81 (*)
82 _tsl=$( (tput tsl 0; echo) 2>/dev/null |
83 sed -e 's/\\/\\\\/g' -e 's/%/%%/g')
84 _fsl=$( (tput fsl ; echo) 2>/dev/null |
85 sed -e 's/\\/\\\\/g' -e 's/%/%%/g') ;;
86esac
87# if terminal window title can be changed...
88if [ "$_tsl" ] && [ "$_fsl" ]; then
89 # set terminal window title on each prompt
90 _set_term_title()
91 if [ -t 2 ]; then
92 printf "$_tsl"'%s@%s:%s'"$_fsl" "${LOGNAME}" "${HOSTNAME%%.*}" \
93 "${${PWD:/$HOME/\~}/#$HOME\//\~\/}" >&2
94 fi
95 PROMPT_COMMAND=("$PROMPT_COMMAND" '_set_term_title')
96
97 # reset window title when changing host or user
98 ssh() {
99 if [ -t 2 ]; then printf "$_tsl"'ssh %s'"$_fsl" "$*" >&2; fi
100 command ssh "$@"
101 }
102 su() {
103 if [ -t 2 ]; then printf "$_tsl"'su %s'"$_fsl" "$*" >&2; fi
104 command su "$@"
105 }
106 sudo() {
107 if [ -t 2 ]; then printf "$_tsl"'sudo %s'"$_fsl" "$*" >&2; fi
108 command sudo "$@"
109 }
110 doas() {
111 if [ -t 2 ]; then printf "$_tsl"'doas %s'"$_fsl" "$*" >&2; fi
112 command doas "$@"
113 }
114fi
115
116_osc7_cwd() {
117 local tmp="${PWD}" encoded="" cut c esc
118 esc="$(printf '\33')" # or: esc="$(/usr/bin/printf '\033')"
119 while [ -n "$tmp" ]; do
120 cut="${tmp#?}"
121 c="${tmp%"$cut"}"
122 case "$c" in
123 [-/:_.!\'\(\)~[:alnum:]]) encoded="$encoded$c" ;;
124 *) encoded="$encoded$(printf '%%%02X' "'$c")" ;;
125 esac
126 tmp="$cut"
127 done
128 printf '%s]7;file://%s%s%s\\' "$esc" "${HOSTNAME:-$(uname -n)}" "$encoded" "$esc" > /dev/tty
129}
130
131_update_direnv() {
132 if ! command -v direnv > /dev/null 2>&1; then
133 return
134 fi
135
136 eval "$(
137 direnv export json |
138 jq -r 'to_entries | .[] |
139 if .value == null then
140 @sh "unset \(.key)"
141 else
142 @sh "export \(.key)=\(.value)"
143 end'
144 )"
145}
146
147YASH_AFTER_CD=("$YASH_AFTER_CD" _osc7_cwd _update_direnv)
148_osc7_cwd
149_update_direnv > /dev/null 2>&1
150
151# kak: filetype=sh