Eric Bower
·
2026-08-20
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
51_hc='\f${${SSH_CONNECTION:+y}:-g}.'
52if [ "$(id -u)" -eq 0 ]; then
53 _uc='\fr.' # red username for root
54 _2c='\fr.' # red PS2 for root
55else
56 _uc=$_hc _hc= # same username color as hostname for non-root user
57 _2c= # PS2 in normal color for non-root user
58fi
59# The main prompt ($YASH_PS1) contains the username, hostname, working
60# directory, last exit status (only if non-zero), and $SHLVL (only if
61# non-one).
62YASH_PS1=$_uc'${LOGNAME}'$_hc'@${HOSTNAME%%.*}\fd. '\
63'${${${PWD:/~/\~}##*/}:-$PWD} ${{?:/0/}:+\\fr.$?\\fd. }${{SHLVL-0}:/1}\$ '
64YASH_PS1S='\fo.'
65YASH_PS2=$_2c'> '
66YASH_PS2S=$YASH_PS1S
67YASH_PS4='\fm.+ '
68YASH_PS4S='\fmo.'
69unset _hc _uc _2c
70# No escape sequences allowed in the POSIXly-correct mode.
71PS1='${LOGNAME}@${HOSTNAME%%.*} '$PS1
72
73# find escape sequence to change terminal window title
74case "$TERM" in
75 (xterm*|gnome*|putty*|cygwin*|alacritty*|foot*|kitty*|wezterm*|ghostty*|rxvt*|st*|tmux*|screen*|rio*|contour*)
76 _tsl='\033]0;' _fsl='\a' ;;
77 (*)
78 _tsl=$( (tput tsl 0; echo) 2>/dev/null |
79 sed -e 's/\\/\\\\/g' -e 's/%/%%/g')
80 _fsl=$( (tput fsl ; echo) 2>/dev/null |
81 sed -e 's/\\/\\\\/g' -e 's/%/%%/g')
82 if [ -z "$_tsl" ] || [ -z "$_fsl" ]; then
83 if [ "${TERM:-dumb}" != "dumb" ] && [ "${TERM:-dumb}" != "linux" ]; then
84 _tsl='\033]0;' _fsl='\a'
85 fi
86 fi
87 ;;
88esac
89# if terminal window title can be changed...
90if [ "$_tsl" ] && [ "$_fsl" ]; then
91 # set terminal window title on each prompt
92 _set_term_title() {
93 if [ -t 2 ]; then
94 printf "$_tsl"'%s@%s:%s'"$_fsl" "${LOGNAME}" "${HOSTNAME%%.*}" \
95 "${${PWD:/$HOME/\~}/#$HOME\//\~\/}" >&2
96 fi
97 }
98 # set terminal window title when executing a command
99 _set_cmd_title() {
100 if [ -t 2 ] && [ -n "${COMMAND-}" ]; then
101 local nl="
102"
103 local cmd="${COMMAND%%"$nl"*}"
104 if [ -n "$cmd" ]; then
105 printf "$_tsl"'%s'"$_fsl" "$cmd" >&2
106 fi
107 fi
108 }
109 PROMPT_COMMAND=("$PROMPT_COMMAND" '_set_term_title')
110 POST_PROMPT_COMMAND=("$POST_PROMPT_COMMAND" '_set_cmd_title')
111fi
112
113_osc7_cwd() {
114 local tmp="${PWD}" encoded="" cut c esc
115 esc="$(printf '\33')" # or: esc="$(/usr/bin/printf '\033')"
116 while [ -n "$tmp" ]; do
117 cut="${tmp#?}"
118 c="${tmp%"$cut"}"
119 case "$c" in
120 [-/:_.!\'\(\)~[:alnum:]]) encoded="$encoded$c" ;;
121 *) encoded="$encoded$(printf '%%%02X' "'$c")" ;;
122 esac
123 tmp="$cut"
124 done
125 printf '%s]7;file://%s%s%s\\' "$esc" "${HOSTNAME:-$(uname -n)}" "$encoded" "$esc" > /dev/tty
126}
127
128_update_direnv() {
129 if ! command -v direnv > /dev/null 2>&1; then
130 return
131 fi
132
133 eval "$(
134 direnv export json |
135 jq -r 'to_entries | .[] |
136 if .value == null then
137 @sh "unset \(.key)"
138 else
139 @sh "export \(.key)=\(.value)"
140 end'
141 )"
142}
143
144YASH_AFTER_CD=("$YASH_AFTER_CD" _osc7_cwd _update_direnv)
145_osc7_cwd
146_update_direnv > /dev/null 2>&1
147
148# kak: filetype=sh