Here are functions to set the title and hardstatus of an XTerm or of GNU Screen to 'zsh' and the current directory, respectively, when the prompt is displayed, and to the command name and rest of the command line, respectively, when a command is executed:
function title {
if [[ $TERM == "screen" ]]; then
# Use these two for GNU Screen:
print -nR $'\033k'$1$'\033'\\\
print -nR $'\033]0;'$2$'\a'
elif [[ $TERM == "xterm" || $TERM == "rxvt" ]]; then
# Use this one instead for XTerms:
print -nR $'\033]0;'$*$'\a'
fi
}
function precmd {
title zsh "$PWD"
}
function preexec {
emulate -L zsh
local -a cmd; cmd=(${(z)1})
title $cmd[1]:t "$cmd[2,-1]"
}
This line from my .screenrc lets me see this fancy hardstatus:
caption always "%3n %t%? (%u)%?%?: %h%?"
This version of preexec from a post by Bart Schaefer on zsh-workers handles job control, eg. so that entering 'fg' sets the title and hardstatus to the command line of the program that is resumed, not to 'fg'.
Warning: Resuming a job with the full command line will fail, so eg. 'fg %less\ some_file' will fail while 'fg %less' will work. If you can fix this, that would be groovy.
Bart:
I've made the groovy edits:
preexec() {
emulate -L zsh
local -a cmd; cmd=(${(z)1}) # Re-parse the command line
# Construct a command that will output the desired job number.
case $cmd[1] in
fg)
if (( $#cmd == 1 )); then
# No arguments, must find the current job
cmd=(builtin jobs -l %+)
else
# Replace the command name, ignore extra args.
cmd=(builtin jobs -l ${(Q)cmd[2]})
fi;;
%*) cmd=(builtin jobs -l ${(Q)cmd[1]});; # Same as "else" above
exec) shift cmd;& # If the command is 'exec', drop that, because
# we'd rather just see the command that is being
# exec'd. Note the ;& to fall through.
*) title $cmd[1]:t "$cmd[2,-1]" # Not resuming a job,
return;; # so we're all done
esac
local -A jt; jt=(${(kv)jobtexts}) # Copy jobtexts for subshell
# Run the command, read its output, and look up the jobtext.
# Could parse $rest here, but $jobtexts (via $jt) is easier.
$cmd >>(read num rest
cmd=(${(z)${(e):-\$jt$num}})
title $cmd[1]:t "$cmd[2,-1]") 2>/dev/null
}
madduck:
This produces an ugly leading space on all messages from zsh… like:
cirrus:~> new mail in 'debian'.
I can't find the source though…
madduck:
My problem, I call
function precmd() {
title zsh "$IDENTITY:$(print -P %~)"
}
precmd
in .zshrc. Change that:
- precmd + title "$IDENTITY:$(print -P %~)"
fixes it.
ninja:
You can also use screen string escapes in the hardstatus if you use ^E (\005) as the escape character, e.g.:
"%{^[]0;screen ^En (^Et) ^G%}"
Also, screen window titling is as complex an affair as prompting, e.g.:
print -nRP $'\033k%(!.#\[.)'$1$'%'$\(\(20\-${#1}\)\)$'< ..<'${${2:+${${${@[${#${@}}]##/*/}/#/ }:-}}//\"/}$'%(!.\].)\033'\\