I previously posted about generating title escapes for screen and rxvt-unicode from zsh. I’ve since worked on getting a consistent title from vim, too. It’s become complex enough that I’m spinning it out into a new post.
To set both titles from vim, use its termcap-title options to push the title to screen using the iconstring. When not running under screen, the right titlestring escapes will be inferred from terminfo.
set title auto BufEnter * let &titlestring = s:MyTitle() if &term =~ 'screen\(\.\(xterm\|rxvt\)\(-\(256\)\?color\)\?\)\?' " Set the screen title using the vim "iconstring"." set t_IS=^[k set t_IE=^[\ set icon auto BufEnter * let &iconstring = &titlestring " Set the xterm title using the vim "titlestring"." set t_ts=^[]2; set t_fs=^G endif
where the underlined characters are actual escapes input with ^V, not with literal carets.
As for generating a fancy title string like vim: there are some gotchas. The biggest is that vim does not preserve logical directory names, so getcwd() will resolve symlinks, leading to a different location string than generated by zsh’s %~
. Rather than call pwd -L, we might as well unify the expansion syntax and call zsh. Of course, it’s nice to have a fallback, too:
" Perform zsh-like prompt expansion using the template {prompt}. See
" "EXPANSION OF PROMPT SEQUENCES" in zshmisc(1).
function s:ZshPromptExpn(prompt)
if &shell == "/bin/zsh"
return system("print -Pn " . shellescape(a:prompt))
else
" Fallback to poor man's prompt expansion.
" By no means equivalent to zsh.
let idx = 0
let result = ''
let escapere = '%\([%)m]\|\(\(-\?[0-9]\+\)\?[~]\)\)'
while idx < len(a:prompt)
let nextesc = match(a:prompt, escapere, idx)
if nextesc < 0
let result .= a:prompt[idx :]
break
elseif idx < nextesc
let result .= a:prompt[idx : (nextesc - 1)]
endif
let idx = matchend(a:prompt, escapere, nextesc)
let esc = a:prompt[nextesc : (idx - 1)]
if esc == '%m'
let result .= substitute(hostname(), '^\([^.]*\).*', '\1', '')
elseif esc =~ '%-\?[0-9]*[~]'
let result .= fnamemodify(getcwd(), ':~')[:-2]
elseif esc == '%%'
let result .= '%'
endif
endwhile
return result
endfunction
function s:MyTitle()
return s:ZshPromptExpn("%m:%-3~ ") .
\ v:progname . " " . fnamemodify(expand("%:f"), ":.")
endfunction