forked from extern/ohmyzsh
a263cdac9c
The `title` function unsafely prints its input without sanitization, which if used with custom user code that calls it, it could trigger command injection. The `spectrum_ls` and `spectrum_bls` could similarly be exploited if a variable is changed in the user's shell environment with a carefully crafted value. This is highly unlikely to occur (and if possible, other methods would be used instead), but with this change the exploit of these two functions is now impossible.
137 lines
4.7 KiB
Bash
137 lines
4.7 KiB
Bash
# Set terminal window and tab/icon title
|
|
#
|
|
# usage: title short_tab_title [long_window_title]
|
|
#
|
|
# See: http://www.faqs.org/docs/Linux-mini/Xterm-Title.html#ss3.1
|
|
# Fully supports screen, iterm, and probably most modern xterm and rxvt
|
|
# (In screen, only short_tab_title is used)
|
|
# Limited support for Apple Terminal (Terminal can't set window and tab separately)
|
|
function title {
|
|
setopt localoptions nopromptsubst
|
|
|
|
# Don't set the title if inside emacs, unless using vterm
|
|
[[ -n "$INSIDE_EMACS" && "$INSIDE_EMACS" != vterm ]] && return
|
|
|
|
# if $2 is unset use $1 as default
|
|
# if it is set and empty, leave it as is
|
|
: ${2=$1}
|
|
|
|
case "$TERM" in
|
|
cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty|st*)
|
|
print -Pn "\e]2;${2:q}\a" # set window name
|
|
print -Pn "\e]1;${1:q}\a" # set tab name
|
|
;;
|
|
screen*|tmux*)
|
|
print -Pn "\ek${1:q}\e\\" # set screen hardstatus
|
|
;;
|
|
*)
|
|
if [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then
|
|
print -Pn "\e]2;${2:q}\a" # set window name
|
|
print -Pn "\e]1;${1:q}\a" # set tab name
|
|
else
|
|
# Try to use terminfo to set the title if the feature is available
|
|
if (( ${+terminfo[fsl]} && ${+terminfo[tsl]} )); then
|
|
print -Pn "${terminfo[tsl]}$1${terminfo[fsl]}"
|
|
fi
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
ZSH_THEME_TERM_TAB_TITLE_IDLE="%15<..<%~%<<" #15 char left truncated PWD
|
|
ZSH_THEME_TERM_TITLE_IDLE="%n@%m:%~"
|
|
# Avoid duplication of directory in terminals with independent dir display
|
|
if [[ "$TERM_PROGRAM" == Apple_Terminal ]]; then
|
|
ZSH_THEME_TERM_TITLE_IDLE="%n@%m"
|
|
fi
|
|
|
|
# Runs before showing the prompt
|
|
function omz_termsupport_precmd {
|
|
[[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return
|
|
title "$ZSH_THEME_TERM_TAB_TITLE_IDLE" "$ZSH_THEME_TERM_TITLE_IDLE"
|
|
}
|
|
|
|
# Runs before executing the command
|
|
function omz_termsupport_preexec {
|
|
[[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return
|
|
|
|
emulate -L zsh
|
|
setopt extended_glob
|
|
|
|
# split command into array of arguments
|
|
local -a cmdargs
|
|
cmdargs=("${(z)2}")
|
|
# if running fg, extract the command from the job description
|
|
if [[ "${cmdargs[1]}" = fg ]]; then
|
|
# get the job id from the first argument passed to the fg command
|
|
local job_id jobspec="${cmdargs[2]#%}"
|
|
# logic based on jobs arguments:
|
|
# http://zsh.sourceforge.net/Doc/Release/Jobs-_0026-Signals.html#Jobs
|
|
# https://www.zsh.org/mla/users/2007/msg00704.html
|
|
case "$jobspec" in
|
|
<->) # %number argument:
|
|
# use the same <number> passed as an argument
|
|
job_id=${jobspec} ;;
|
|
""|%|+) # empty, %% or %+ argument:
|
|
# use the current job, which appears with a + in $jobstates:
|
|
# suspended:+:5071=suspended (tty output)
|
|
job_id=${(k)jobstates[(r)*:+:*]} ;;
|
|
-) # %- argument:
|
|
# use the previous job, which appears with a - in $jobstates:
|
|
# suspended:-:6493=suspended (signal)
|
|
job_id=${(k)jobstates[(r)*:-:*]} ;;
|
|
[?]*) # %?string argument:
|
|
# use $jobtexts to match for a job whose command *contains* <string>
|
|
job_id=${(k)jobtexts[(r)*${(Q)jobspec}*]} ;;
|
|
*) # %string argument:
|
|
# use $jobtexts to match for a job whose command *starts with* <string>
|
|
job_id=${(k)jobtexts[(r)${(Q)jobspec}*]} ;;
|
|
esac
|
|
|
|
# override preexec function arguments with job command
|
|
if [[ -n "${jobtexts[$job_id]}" ]]; then
|
|
1="${jobtexts[$job_id]}"
|
|
2="${jobtexts[$job_id]}"
|
|
fi
|
|
fi
|
|
|
|
# cmd name only, or if this is sudo or ssh, the next cmd
|
|
local CMD="${1[(wr)^(*=*|sudo|ssh|mosh|rake|-*)]:gs/%/%%}"
|
|
local LINE="${2:gs/%/%%}"
|
|
|
|
title "$CMD" "%100>...>${LINE}%<<"
|
|
}
|
|
|
|
autoload -Uz add-zsh-hook
|
|
|
|
if [[ -z "$INSIDE_EMACS" || "$INSIDE_EMACS" = vterm ]]; then
|
|
add-zsh-hook precmd omz_termsupport_precmd
|
|
add-zsh-hook preexec omz_termsupport_preexec
|
|
fi
|
|
|
|
# Keep Apple Terminal.app's current working directory updated
|
|
# Based on this answer: https://superuser.com/a/315029
|
|
# With extra fixes to handle multibyte chars and non-UTF-8 locales
|
|
|
|
if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then
|
|
# Emits the control sequence to notify Terminal.app of the cwd
|
|
# Identifies the directory using a file: URI scheme, including
|
|
# the host name to disambiguate local vs. remote paths.
|
|
function update_terminalapp_cwd() {
|
|
emulate -L zsh
|
|
|
|
# Percent-encode the host and path names.
|
|
local URL_HOST URL_PATH
|
|
URL_HOST="$(omz_urlencode -P $HOST)" || return 1
|
|
URL_PATH="$(omz_urlencode -P $PWD)" || return 1
|
|
|
|
# Undocumented Terminal.app-specific control sequence
|
|
printf '\e]7;%s\a' "file://$URL_HOST$URL_PATH"
|
|
}
|
|
|
|
# Use a precmd hook instead of a chpwd hook to avoid contaminating output
|
|
add-zsh-hook precmd update_terminalapp_cwd
|
|
# Run once to get initial cwd set
|
|
update_terminalapp_cwd
|
|
fi
|