Thursday, August 23, 2007

XTerm title setting in zsh

I always forget how to configure zsh to set the title of an XTerm automatically, and I usually just copy some code on the web without really understanding it. I finally tracked down how the stuff works behind the scenes and wrote an easier-to-understand version myself (loosely based on some random code found via Google of course):
set_xterm_text_params() {
local param=$1
shift
case $TERM in
xterm*|rxvt) print -Pn "%{\e]$param;$*\a%}"
esac
}

set_xterm_title() {
set_xterm_text_params 0 "$*"
}

set_xterm_icon_name() {
set_xterm_text_params 1 "$*"
}

set_xterm_window_title() {
set_xterm_text_params 2 "$*"
}

tag() {
if [[ $# -eq 0 ]] ; then
custom_tag=""
else
custom_tag="$*"
fi
}

# preexec() runs before each command. The command line used to run the
# program is $1. That allows this hack, which shows the name of
# whatever command is currently running, directly in the titlebar. The
# expansion parameter (V) makes any special characters in the string
# visible.

preexec() {
set_xterm_title "${custom_tag:+$custom_tag - }%n@%m: %50>...>${(V)1}%<<"
}

# ZSH runs precmd() before each prompt. Because of the above preexec
# hack, I use it to display the pwd in the titlebar. Most people use
# chpwd for this, which is a bit more efficient, but that obviously
# wouldn't work in this case.

precmd() {
set_xterm_title "${custom_tag:+$custom_tag - }%n@%m: %50<...<%~%<<"
}

Wednesday, August 22, 2007

Various bugs

  1. TRAMP and zsh don't get along. In particular, it appears that the PROMPT_SP zsh option (which outputs special characters to mark command output that doesn't end in a newline) causes the zsh prompt to no longer match the shell-prompt-pattern emacs variable, which is set to "^[^#$%>\n]*[#$%>] *" by default. I added the following hack to my .emacs file to fix the problem:
    (eval-after-load "tramp"
    '(setcdr (assoc 'tramp-login-args (assoc "sudo" tramp-methods))
    '((("-u" "%u") ("-p" "Password:" "/bin/sh"))))

  2. Connecting to some servers via ssh was taking way too long, around 10 seconds. Running "strace ssh -vvv" showed that the program was hanging while trying to do a reverse DNS lookup on the IP address of the server (i.e. getnameinfo). The culprits were the mDNS resolver (libnss-mdns) and Avahi daemon — they were broadcasting reverse mDNS lookup requests to the local network and timing out very slowly. The fix was easy: remove the "mdns" entry from the "hosts:" line in /etc/nsswitch.conf (I love Linux...).