Search this site


Metadata

Articles

Projects

Presentations

Better zsh xterm title function fix

Sometimes I run commands that have special characters in them, newlines, or are very long. 'xterm set title' sequence breaks on those cases. So, let's fix that.
function title() {
  # escape '%' chars in $1, make nonprintables visible
  a=${(V)1//\%/\%\%}

  # Truncate command, and join lines.
  a=$(print -Pn "%40>...>$a" | tr -d "\n")

  case $TERM in
  screen)
    print -Pn "\e]2;$a @ $2\a" # plain xterm title
    print -Pn "\ek$a\e\\"      # screen title (in ^A")
    print -Pn "\e_$2   \e\\"   # screen location
    ;;
  xterm*|rxvt)
    print -Pn "\e]2;$a @ $2\a" # plain xterm title
    ;;
  esac
}
The 3 cases are addressed individually.
  • Special characters are made printable by using the 'V' flag, ${(V)varname}. This is documented in zsh under 'Parameter Expansion Flags'
  • Long lines are truncated with "%40>...>$varname" with "print -P". The '-P' flag has print interpret in prompt-style expansion. "%40>...>whatever" will truncate 'whatever' to 40 characters, trailed with '...'
  • Multi-line entries are joined with 'tr -d "\n"' - Maybe there's a better way to do this with zsh without needing to run tr(1) every time?
The 'title' function takes 2 arguments, which get separated by a '-' in xterm titles. First argument is the 'what' and second argument is the 'where'. Separated, they can be used to tell screen what is running ina given session and where. Useful++

The only real changes to this function from the original was adding the fixes for those 3 cases. The rest of the function remains unchanged.

If you're still confused as to where this can be used, put it in a precmd and preexec function:

# precmd is called just before the prompt is printed
function precmd() {
  title "zsh" "%m(%55<...<%~)"
}

# preexec is called just before any command line is executed
function preexec() {
  title "$1" "%m(%35<...<%~)"
}
An example of this can be seen in this screenshot.