I have scoured the internet for an explanation, but the cryptic terseness of t_ts
and t_fs
makes it impossible to find helpful information about how I can expect systems to work.
Here is an overview of my existing knowledge, and I'd love it if someone wise could fill in the last few dots...
I "started" somewhere here: http://tldp.org/HOWTO/Xterm-Title-3.html
I verified running this in my bash shell (where the ^[
is produced by Ctrl+V,Esc):
printf "^[]0;testTITLEzzz"
This works. It works to set the title on a raw terminal and it works to set the title for a pane in tmux.
Note! I did not need to use a trailing "\007"
char.
Inside my .vimrc
, when I use set title
, and set a titlestring
, it always correctly sets the raw terminal title correctly, but failed to set the tmux pane title.
Once I set this, though (same thing with the ^[
, it is a raw ESC char):
if &term == "tmux-256color-italic"
set t_ts=^[]0;
set t_fs=
endif
It started to work for setting the tmux pane title. I rejoiced.
Now the trouble I have is how to turn this procedural knowledge into practical knowledge that I can use in the future.
I looked up the help in vim, I get this:
t_ts set window title start (to status line) t_ts 't_ts'
t_fs set window title end (from status line) t_fs 't_fs'
I don't know what "status line" means here.
I want to know how these terminal-output-codes as documented in vim correspond to the rest of the xterm world, or whatever I should call it.
For example I can query infocmp
to get my current terminal config and xterm
terminal config's values:
$ infocmp xterm
# Reconstructed via infocmp from file: /lib/terminfo/x/xterm
xterm|xterm-debian|X11 terminal emulator,
am, bce, km, mc5i, mir, msgr, npc, xenl,
colors#8, cols#80, it#8, lines#24, pairs#64,
acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, civis=\E[?25l,
clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=\r,
csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
cud=\E[%p1%dB, cud1=\n, cuf=\E[%p1%dC, cuf1=\E[C,
cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
cvvis=\E[?12;25h, dch=\E[%p1%dP, dch1=\E[P, dim=\E[2m,
dl=\E[%p1%dM, dl1=\E[M, ech=\E[%p1%dX, ed=\E[J, el=\E[K,
el1=\E[1K, flash=\E[?5h$<100/>\E[?5l, home=\E[H,
hpa=\E[%i%p1%dG, ht=^I, hts=\EH, ich=\E[%p1%d@,
il=\E[%p1%dL, il1=\E[L, ind=\n, indn=\E[%p1%dS,
invis=\E[8m, is2=\E[!p\E[?3;4l\E[4l\E>, kDC=\E[3;2~,
kEND=\E[1;2F, kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D,
kNXT=\E[6;2~, kPRV=\E[5;2~, kRIT=\E[1;2C, kb2=\EOE, kbs=^?,
kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
kdch1=\E[3~, kend=\EOF, kent=\EOM, kf1=\EOP, kf10=\E[21~,
kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P, kf14=\E[1;2Q,
kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~, kf18=\E[17;2~,
kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~,
kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~,
kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S,
kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~,
kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~,
kf35=\E[23;5~, kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q,
kf39=\E[1;6R, kf4=\EOS, kf40=\E[1;6S, kf41=\E[15;6~,
kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~,
kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~,
kf48=\E[24;6~, kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q,
kf51=\E[1;3R, kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~,
kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~,
kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~,
kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~,
kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,
kind=\E[1;2B, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
kri=\E[1;2A, mc0=\E[i, mc4=\E[4i, mc5=\E[5i, meml=\El,
memu=\Em, op=\E[39;49m, rc=\E8, rep=%p1%c\E[%p2%{1}%-%db,
rev=\E[7m, ri=\EM, rin=\E[%p1%dT, ritm=\E[23m, rmacs=\E(B,
rmam=\E[?7l, rmcup=\E[?1049l\E[23;0;0t, rmir=\E[4l,
rmkx=\E[?1l\E>, rmm=\E[?1034l, rmso=\E[27m, rmul=\E[24m,
rs1=\Ec, rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7,
setab=\E[4%p1%dm, setaf=\E[3%p1%dm,
setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
sgr0=\E(B\E[m, sitm=\E[3m, smacs=\E(0, smam=\E[?7h,
smcup=\E[?1049h\E[22;0;0t, smir=\E[4h, smkx=\E[?1h\E=,
smm=\E[?1034h, smso=\E[7m, smul=\E[4m, tbc=\E[3g,
u6=\E[%i%d;%dR, u7=\E[6n, u8=\E[?%[;0123456789]c,
u9=\E[c, vpa=\E[%i%p1%dd,
$ infocmp
# Reconstructed via infocmp from file: /home/slu/.terminfo/t/tmux-256color-italic
tmux-256color-italic|screen with 256 colors and italic,
am, km, mir, msgr, xenl,
colors#0x100, cols#80, it#8, lines#24, pairs#0x7fff,
acsc=++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, civis=\E[?25l,
clear=\E[H\E[J, cnorm=\E[34h\E[?25h, cr=\r,
csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
cud=\E[%p1%dB, cud1=\n, cuf=\E[%p1%dC, cuf1=\E[C,
cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\EM,
cvvis=\E[34l, dch=\E[%p1%dP, dch1=\E[P, dim=\E[2m,
dl=\E[%p1%dM, dl1=\E[M, ed=\E[J, el=\E[K, el1=\E[1K,
enacs=\E(B\E)0, flash=\Eg, home=\E[H, hpa=\E[%i%p1%dG,
ht=^I, hts=\EH, ich=\E[%p1%d@, il=\E[%p1%dL, il1=\E[L,
ind=\n, indn=\E[%p1%dS, is2=\E)0, kbs=^?, kcbt=\E[Z,
kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
kdch1=\E[3~, kend=\E[4~, kf1=\EOP, kf10=\E[21~,
kf11=\E[23~, kf12=\E[24~, kf2=\EOQ, kf3=\EOR, kf4=\EOS,
kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~,
khome=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
nel=\EE, op=\E[39;49m, rc=\E8, rev=\E[7m, ri=\EM,
ritm=\E[23m, rmacs=^O, rmcup=\E[?1049l, rmir=\E[4l,
rmkx=\E[?1l\E>, rmso=\E[27m, rmul=\E[24m,
rs2=\Ec\E[?1000l\E[?25h, sc=\E7,
setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
sgr=\E[0%?%p6%t;1%;%?%p1%t;3%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;m%?%p9%t\016%e\017%;,
sgr0=\E[m\017, sitm=\E[3m, smacs=^N, smcup=\E[?1049h,
smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m, smul=\E[4m,
tbc=\E[3g, vpa=\E[%i%p1%dd,
Nothing seems to line up with ts
or fs
.
At this point I don't think that the 2 letter codes map together, which is something that I have suspected for years.
Furthermore, since I learned that emitting <Esc>]0;
followed by a string works to set the title, through my testing, I see that this always works regardless of the terminal capabilities that are specified in $TERM
. This makes me question if looking at infocmp
and wondering about whether something specified here is relevant to my ability to control the title.
Though, honestly, I hardly understand what the significance of the $TERM
env var even is, aside from that programs such as vim
and less
complain if I haven't tic
'd a terminfo file corresponding to the current value of $TERM
. Again, just procedural knowledge, and I'm seeking something a little deeper and meaningful.
Now that I've found a combination of configuration that allows tmux's pane titles to be set properly by vim, I wonder what it was that vim was sending prior to my setting of t_ts
that worked on raw terminals but did not work for tmux. I know there is a way to trick vim into thinking i'm running it interactively while piping all of its output into a binary file, and then go hex spelunking for the difference in codes, but I have forgotten how this is done, and suspect that there is a less painful way to find out.
It is entirely unclear what i should set, if anything, for t_fs
, and this touches also upon the question of why the \007
BEL character is not necessary to terminate the title sequence. Why is it not necessary, and what should I expect will terminate the sequence? A newline?
You definitely need the trailing \007 (or \033\\) or some terminals will stop responding waiting for the end of the sequence. Did you try this inside tmux? tmux has a timeout to prevent panes hanging, but most other terminals do not. If you try it in xterm without the \007, it will hang.
For information on the title setting sequences themselves, look at https://invisible-island.net/xterm/ctlseqs/ctlseqs.html (title setting is OSC 0 and 2 - look under "Operating System Commands").
ts and fs are termcap names (terminfo is tsl/fsl) meaning "to status line" and "from status line" (as the name implies, infocmp is showing you terminfo, not termcap). These are somewhat historical from the days when hardware terminals had a separate status line, but in recent years have been reused sometimes for the X terminal title. Look at the "Status Lines" section in terminfo(5) for some bits about status line capabilities. In practice, tsl and fsl are not often provided or used and instead most applications look at the XT capability ("xterm titles") to work out if they should use the OSC sequences. XT is an extension capability - you need to use "infocmp -x" to see it.
You can always set the title inside tmux using the OSC sequences, by default the title (#{pane_title} format) is shown in quotes in status-right. tmux will not also set the external terminal title (the terminal tmux is running in) unless the set-titles option is on. The set-titles-string option controls the format of the title tmux sets (by default it includes the active pane's title and some other information). set-titles will only work if TERM outside tmux specifies an entry that contains XT or tsl/fsl (xterm does have XT).
I don't know how to configure vim to set the title but it seems like you are on the right track there with t_ts and t_fs - it seems like vim is using the tsl/fsl but using the termcap names (probably a legacy from vi which was started long before terminfo existed).
I can give you a brief description of how it works:
termcap was originally written in the 70s to allow vi to run on different (hardware) terminals;
terminfo was written as a replacement in the 80s to fix a number of problems and limitations with termcap;
both are still used (terminfo much more commonly) for both software and hardware terminals;
they both work in a similar way - there is a database of named entries (like "xterm" or "tmux-256color") which give a set of named capabilities of the terminal; some capabilities are flags (eg "XT") or numbers (eg "colors") but most are strings which specify the sequence an application should send to a terminal to make something happen (eg "cuu1" make the cursor move one line up - "\033[A" on vt100-compatible terminals);
termcap has short most two-character names, terminfo tend to be longer; termcap has a small limit of 1024 bytes on the length of a database entry so it is often missing many capabilities that terminfo has;
TERM is set to the name of the termcap or terminfo entry the application should look for in the database;
the terminfo database is maintained and shipped as part of ncurses (a library for drawing to the terminal which is used by many terminal applications); the termcap database is generated from terminfo using tic.
There isn't really a single source with all the information put together. For the escape sequences, https://vt100.net/ has a lot of manuals for old hardware terminals (much of which is now irrelevent however) and the link I gave above for xterm documents the escape sequences supported by xterm and most other modern terminal emulators support a subset of these (almost all terminals still around are vt100-compatible and xterm is the de facto standard terminal). ncurses has some manuals: terminfo(5) and termcap(5). There is an O'Reilly book called "termcap and terminfo" which covers much as well, but it was written in the late 80s so some of it is out of date.