Skip to content

Use b:term_title for terminal buffer display names.#138

Open
charlesg3 wants to merge 1 commit intojlanzarotta:masterfrom
charlesg3:term-title-display
Open

Use b:term_title for terminal buffer display names.#138
charlesg3 wants to merge 1 commit intojlanzarotta:masterfrom
charlesg3:term-title-display

Conversation

@charlesg3
Copy link

Problem

When multiple terminal buffers are open, BufExplorer displays each one as !PID:shell (e.g. !22290:zsh). With several terminals running it is difficult to tell them apart — the PID is meaningless at a glance.

Solution

Neovim stores the OSC 0/2 title emitted by the terminal program in the buffer-local variable b:term_title. When a shell has preexec/precmd hooks that set the title to the running command or current directory, this variable contains something much more useful than the PID.

This change checks b:term_title after the existing !PID:shell name is constructed, and substitutes it when a meaningful title is present:

let term_title = getbufvar(buf.bufNbr, 'term_title', '')
if !empty(term_title) && term_title !~# '^term://'
    let name = '!' . term_title
endif

The ^term:// guard is necessary because Neovim initialises b:term_title to the raw terminal URI (e.g. term://~//22290:/bin/zsh) before any OSC sequence has arrived. Without it, that default value would be used verbatim.

Result

With a shell configured to emit OSC titles (e.g. zsh preexec/precmd hooks), terminals appear in the buffer list as:

 3  a   !nvim init.vim
 4  a   !~/src/myproject
 5  a   !sleep 100

instead of:

 3  a   !22290:zsh
 4  a   !22291:zsh
 5  a   !22292:zsh

Falls back gracefully to the existing !PID:shell format when b:term_title has not been set by the terminal.

When a terminal buffer's b:term_title has been set by an OSC 0/2 title
sequence (e.g. via shell preexec/precmd hooks), use it as the display
name instead of the opaque `!PID:shell` fallback.  This makes it easy
to distinguish multiple terminal buffers by showing the running command
or current directory rather than an arbitrary process ID.

Neovim initialises b:term_title to the raw `term://` URI before any
title sequence has arrived, so values matching that prefix are ignored
and the existing fallback is used instead.
@drmikehenry
Copy link
Contributor

This looks like a useful extension. I don't use the :terminal feature myself, but I tried out this change. On my system, b:term_title has the form username@hostname CUR_DIR regardless of what's running in the terminal. I'm sure I could adjust things to make b:term_title more useful, and I would expect to do so if/when I start using :terminal more. But without such adjustment, terminals now end up looking much the same in BufExplorer, at least if the current working directory is the same. For example, after cd / and nvim, if I launch :terminal window and create a pair of :terminal windows, BufExplorer shows:

  2 %aR   !mike@f16: / / line 1
  1 #aR   !mike@f16: / / line 1

There's not much (other than the buffer number) to distinguish these terminals on my system.

If I then cd /usr/local/lib in one, BufExplorer now shows:

  2 %aR   !mike@f16: lib /usr/local/lib line 2
  1 #aR   !mike@f16: /   /              line 1

It's a bit redundant having the directory name duplicated by the path column.

The PID distinguisher is lost here; but a user would likely rather remember the the (probably shorter) buffer number instead of the PID anyway, if the s:term_title doesn't have better information in it. But if the PID seems desirable to display, it could be retained by moving the new logic above the if pid < 0 line and setting shellName instead of name, e.g.:

        let term_title = getbufvar(buf.bufNbr, 'term_title', '')
        if !empty(term_title) && term_title !~# '^term://'
            let shellName = term_title
        endif

        if pid < 0

With BufExplorer showing:

  2 %aR   !321637:mike@f16: / / line 1
  1 #aR   !321625:mike@f16: / / line 1

However, this comes at the expense of quite a few columns in the display, and probably isn't that valuable. Users wanting a better display in BufExplorer would likely want to configure things so that b:term_title itself is more useful.

I also didn't test what happens if the currently running command is very long; that might push subsequent columns off the right side of the display. Perhaps if b:term_title is longer than some threshold, only a prefix should be retained.

In any event, I think this idea has merit. As a very infrequent user of :terminal, the pull request as-is won't hurt me at all (since I have no terminal windows open in general). Heavy users of :terminal would also likely be interested in setting up their systems so that b:term_title is more valuable. It would be useful to extend the BufExplorer documentation to show how to set things up on a typical system (ideally at least Linux and Windows) to set b:term_title in a better manner. It might make sense to allow BufExplorer users to configure how terminal names are displayed if there are multiple reasonable ways different users might prefer, though I don't have any feel for what would be most beneficial.

I expect @jlanzarotta will weigh in when he gets some time; I know he's frequently fairly swamped with other things.

@jlanzarotta
Copy link
Owner

jlanzarotta commented Mar 9, 2026

I am currently stuck on Windows development, so I am pretty sure this is not reproduceable there... I do not use NeoVim either. As long as this change does not break Windows Vim, I will merge it. Let me take a look and I hope to merge in the next day or so.

@charlesg3
Copy link
Author

Great -- thanks so much for taking a look and merging. It's definitely a QoL improvement on my end where many of my terminal apps set nice "titles" (and I have my shell do the same) so now I can easily differentiate what's running in each of the shells and not left guessing based on PID. 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants