mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2024-12-28 07:50:09 +08:00
25c2c3a468
Previously this was only emitted on macOS with Apple's Terminal.app (and compatible clones like iTerm2), but it is used by other terminal emulators as well to obtain the actual current working directory wiht symlinks intact. All non-supporting terminal emulators tested gracefully ignored this value, so emit this on these as well in case they (or some other app masquarading as them) add future support for this value. Closes #9914 Co-authored-by: Marc Cornellà <hello@mcornella.com>
161 lines
5.6 KiB
Bash
161 lines
5.6 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*|foot|contour*)
|
|
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 terminal emulator's current working directory correct,
|
|
# even if the current working directory path contains symbolic links
|
|
#
|
|
# References:
|
|
# - Apple's Terminal.app: https://superuser.com/a/315029
|
|
# - iTerm2: https://iterm2.com/documentation-escape-codes.html (iTerm2 Extension / CurrentDir+RemoteHost)
|
|
# - Konsole: https://bugs.kde.org/show_bug.cgi?id=327720#c1
|
|
# - libvte (gnome-terminal, mate-terminal, …): https://bugzilla.gnome.org/show_bug.cgi?id=675987#c14
|
|
# Apparently it had a bug before ~2012 were it would display the unknown OSC 7 code
|
|
#
|
|
# As of May 2021 mlterm, PuTTY, rxvt, screen, termux & xterm simply ignore the unknown OSC.
|
|
|
|
# Don't define the function if we're inside Emacs
|
|
if [[ -n "$INSIDE_EMACS" ]]; then
|
|
return
|
|
fi
|
|
|
|
# Don't define the function if we're in an unsupported terminal
|
|
case "$TERM" in
|
|
# all of these either process OSC 7 correctly or ignore entirely
|
|
xterm*|putty*|rxvt*|konsole*|mlterm*|alacritty|screen*|tmux*) ;;
|
|
contour*|foot*) ;;
|
|
*)
|
|
# Terminal.app and iTerm2 process OSC 7 correctly
|
|
case "$TERM_PROGRAM" in
|
|
Apple_Terminal|iTerm.app) ;;
|
|
*) return ;;
|
|
esac ;;
|
|
esac
|
|
|
|
# Emits the control sequence to notify many terminal emulators
|
|
# of the cwd
|
|
#
|
|
# Identifies the directory using a file: URI scheme, including
|
|
# the host name to disambiguate local vs. remote paths.
|
|
function omz_termsupport_cwd {
|
|
# 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
|
|
|
|
# common control sequence (OSC 7) to set current host and path
|
|
printf "\e]7;%s\a" "file://${URL_HOST}${URL_PATH}"
|
|
}
|
|
|
|
# Use a precmd hook instead of a chpwd hook to avoid contaminating output
|
|
# i.e. when a script or function changes directory without `cd -q`, chpwd
|
|
# will be called the output may be swallowed by the script or function.
|
|
add-zsh-hook precmd omz_termsupport_cwd
|