wezterm icon indicating copy to clipboard operation
wezterm copied to clipboard

Feature request to rename a tab manually

Open stevenxxiu opened this issue 3 years ago • 9 comments

Is your feature request related to a problem? Please describe. It is sometimes convenient to give a tab a manual label, so it is clear at a glance what we aim to do in that tab.

Describe the solution you'd like The ability to rename a tab manually by clicking on it. In my previous terminal emulator I just double clicked to create an input box, then I entered the text I wanted to set.

Setting it with an empty name restores the title set by the terminal for that tab.

Describe alternatives you've considered For idle tabs we can set it's title through terminal commands. But this is impossible for a long running command, e.g. when we're in ssh, or a command that's doing some compute.

Additional context N/A

stevenxxiu avatar Mar 08 '21 09:03 stevenxxiu

Feature highly anticipated :) Once you work with many tabs it's hard to remmeber what is where.

im-n1 avatar Aug 02 '21 08:08 im-n1

Wezterm comes with a lot of features and a powerful scripting language. The way to communicate with the terminal is via terminal escape codes.

┌──────────┐              ┌──────────┐           ┌──────────┐
│ Terminal │ -----------> │   Shell  │ --------> │    OS    │
│          │ <----------- │          │ <-------- │          │
└──────────┘ escape codes └──────────┘           └──────────┘

So if one could set a variable from the shell and change the tab title in the terminal based on that variable one could change the tab title ad hoc. Wezterm has the building blocks for that:

pane:get_user_vars https://wezfurlong.org/wezterm/config/lua/pane/get_user_vars.html

and

format-tab-title https://wezfurlong.org/wezterm/config/lua/window-events/format-tab-title.html

So one could make a shell function that sets a variable named fx panetitle:

# First and only argument is the desired term title
function rename_wezterm_title {
  echo "\x1b]1337;SetUserVar=panetitle=$(echo -n $1 | base64)\x07"
}

And set the pane/tab title based on that variable in the Wezterm configuration file:

local wezterm = require 'wezterm';

wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
  local pane_title = tab.active_pane.title
  local user_title = tab.active_pane.user_vars.panetitle

  if user_title ~= nil and #user_title > 0 then
    pane_title = user_title
  end

  return {
    {Background={Color="blue"}},
    {Foreground={Color="white"}},
    {Text=" " .. pane_title .. " "},
  }
end)

return {}

To set the tab title name from the shell:

rename_wezterm_title "My ad hoc name"

And to get the default name scheme for the title back:

rename_wezterm_title ""

I hope this help solve your feature request. For a more elaborate feature request, one could maybe wish for per pane background and gradient settings, i.e. red gradient for production and green for test etc. Or company logo background image on company servers and something else for local shell.

kar1 avatar Aug 19 '21 20:08 kar1

Thanks @kar1 :) FWIW, I think there is a legit use case raised in the OP, which is renaming a tab while a long running program is active inside it, but aside from that, the recommendation is to use escape sequences to manage the tab names.

wez avatar Aug 19 '21 20:08 wez

Just wanted to link my Discussion topic, as I think it has some additional context (and also mentions long running processes) https://github.com/wez/wezterm/discussions/1048

Tobbe avatar Aug 20 '21 06:08 Tobbe

2 cents from a noob: Renaming a tab or ideally a window, or a config to open a window with all the tabs named via a template would be nice because it would allow people using TWMs to find and apply transformations to that window. For instance you could create a quake/visor/scratchpad terminal and tie it to a hot key with SKHD or the like. I also tried the above solution, but this title isn't available to yabai.

From Yabai

{
        "id":52594,
        "pid":41188,
        "app":"WezTerm",
        "title":"[1/2] yabai -m query --windows --window ",
        "frame":{
                "x":846.0000,
                "y":52.0000,
                "w":822.0000,
                "h":518.0000
        },
        "level":0,
        "role":"AXWindow",
        "subrole":"AXStandardWindow",
        "movable":1,
        "resizable":1,
        "display":1,
        "space":1,
        "visible":1,
        "focused":1,
        "split":"vertical",
        "floating":0,
        "sticky":0,
        "minimized":0,
        "topmost":0,
        "opacity":1.0000,
        "shadow":0,
        "border":1,
        "stack-index":0,
        "zoom-parent":0,
        "zoom-fullscreen":0,
        "native-fullscreen":0
}

Tab in Wezterm does show that it's name is My ad hoc name though.

typkrft avatar Oct 22 '21 19:10 typkrft

This is what I do, maybe it will help someone. I use this with multiple different shells on windows, and only care about the label:

function get_file_name(path)
    local start, finish = path:find('[%w%s!-={-|]+[_%.].+')
    pcall(function()
        return path:sub(start,#path)
    end)
end


wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
    local lbl
	for shlindex = 1, #custom_shells do
		if tab.active_pane.title:match(custom_shells[shlindex].args[1], 1, true) then
			lbl = custom_shells[shlindex].label
			break
		end
	end
	return string.format(" %-15s ", lbl or get_file_name(tab.active_pane.title) or tab.active_pane.title);
end)

Where custom_shells is the value for launch_menu. Looks like this: image

Does it peg a whole core when you mouse over the tabs? Yes Do I care? No

Mattwmaster58 avatar Dec 14 '21 23:12 Mattwmaster58

@kar1's is a good idea, but it sets the title of the tab per pane. In a tab with multiple panes, the title displayed depends on the current pane focus. Is there a way to set a user var per tab, instead of doing it per pane?

I tried to set the title by iterating through all the panes, but confusingly this sets the title of ALL tabs:

wt.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
  -- local title = tab.active_pane.user_vars.panetitle
  local title = "Terminal"

  for i = 1,#panes do
    local t = panes[i].user_vars.panetitle
    if t ~= nil and #t > 0 then
      title = t
    end
  end

  return {
    {Text="  " .. title .. "  "},
  }
end)

nicolasbrailo avatar Dec 24 '21 15:12 nicolasbrailo

I'd like to keep this issue focused: it's about manually changing the title via the UI. The topic seems to have diverged into programmatically changing the title: I'd be happy to discuss that, but please open a separate issue or discussion thread so that we can keep things focused!

wez avatar Dec 24 '21 17:12 wez

it's about manually changing the title via the UI

would be cool if it could be tied into a keybinding as well -- if that falls under the same concept as UI-driven

atreidesend avatar Sep 07 '22 11:09 atreidesend

echo "\x1b]1337;SetUserVar=panetitle=$(echo -n "My tab new name" | base64)\x07"

On MacOS I can't get this to work when inside tmux.

Do I need to escape it somehow?

pergamomo avatar Nov 09 '22 15:11 pergamomo

@pergamomo see https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it

wez avatar Nov 11 '22 15:11 wez

if somebody is looking for a solution of having a title name being set to the current open dir's name you can set this function in your zshrc

function chpwd {
    echo "\x1b]1337;SetUserVar=panetitle=$(echo -n $(basename $(pwd)) | base64)\x07"
}

activaigor avatar Nov 19 '22 10:11 activaigor

Any updates to this? Can we expect something out of the box?

MikePresman avatar Dec 27 '22 00:12 MikePresman

I'm not used to Windows prompt. It took me a while to make @kar1 solution to work alongside Powershell. The working function that goes in Powershell profile:

function rename_wezterm_title($title) {
  echo "$([char]27)]1337;SetUserVar=panetitle=$([Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($title)))$([char]7)"
}

Thanks for WezTerm the best option I've found so far to bring some terminal sanity while on Windows.

Rodrigo-NH avatar Jan 31 '23 20:01 Rodrigo-NH

Is there any keyboard shortcut for this? This feature is very important for those who work with many tabs.

ShivamJoker avatar Feb 14 '23 08:02 ShivamJoker

just want to expand for anyone that wants to make this part of their daily routine.

https://github.com/wez/wezterm/issues/522#issuecomment-902203635

this works by:

  1. add this to your wezterm configuration vim ~/.wezterm.lua
local wezterm = require 'wezterm';

wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
  local pane_title = tab.active_pane.title
  local user_title = tab.active_pane.user_vars.panetitle

  if user_title ~= nil and #user_title > 0 then
    pane_title = user_title
  end

  return {
    {Background={Color="blue"}},
    {Foreground={Color="white"}},
    {Text=" " .. pane_title .. " "},
  }
end)

return {}
  1. update your shell .bashrc / .zshrc (initiation of your shell)
# First and only argument is the desired term title
function rename_wezterm_title {
  echo "\x1b]1337;SetUserVar=panetitle=$(echo -n $1 | base64)\x07"
}
  1. source your shell or exit and reopen your shell
  2. type rename_wezterm_title "my new tab title"

eleijonmarck avatar Mar 09 '23 22:03 eleijonmarck

@eleijonmarck how can we execute this with a keyboard shortcut?

ShivamJoker avatar Mar 09 '23 22:03 ShivamJoker

@ShivamJoker not sure exactly, you would have to ask for input on the command. But the way to do is to use bind in your shell

eleijonmarck avatar Mar 09 '23 22:03 eleijonmarck

see zsh docs for binding a key - https://jdhao.github.io/2019/06/13/zsh_bind_keys/

eleijonmarck avatar Mar 09 '23 22:03 eleijonmarck

ohh okay thanks

ShivamJoker avatar Mar 09 '23 23:03 ShivamJoker

I would be interested in a wezterm built in solution as well.

I have found that with pwsh on windows, I can use this command to rename the tab

# This command is not cross platform I think
[Console]::Title = 'New tab name from pwsh function'

The function shared from @Rodrigo-NH works for me to rename the tab as well.

One other thing I noticed is that use the wezterm action ShowTabNavigator it does not show the renamed tabs from the escape code method. But it does show the changed tab name using the pwsh method.

    { key = 'F9', mods = 'NONE', action = wezterm.action.ShowTabNavigator },

Tab 5 in this image shows the changed name from using [Console]::Title = 'New tab name from pwsh function Tab 6, does not show the new set title using the escape code method. image

derekthecool avatar Mar 20 '23 15:03 derekthecool

I've just started looking at using Wezterm, coming from Kitty. This is a feature Kitty has (I use a shortcut key for it) that I use for all my tabs. Many of my tabs have multiple panes, so the included work around is cool, but isn't very useful when the pane count > 1

jyemeier avatar Apr 02 '23 01:04 jyemeier

Over in #1598, I just pushed some changes:

  • make the multiplexer aware of tab and window title changes
  • added some shortcuts so that you can do something like this via the debug overlay as a one-liner:
window:active_tab():set_title("w00t!")

without having to write a complicated alias function.

  • made the default format-tab-title logic take the tab title if it is non-empty, so you shouldn't need to write your own event just for tab titles.

Still missing is a proper UI for setting the title, but the debug overlay snippet above is kinda close.

wez avatar Apr 02 '23 04:04 wez

And now there is wezterm cli set-tab-title for setting via the CLI

wez avatar Apr 02 '23 06:04 wez

And now there is wezterm cli set-tab-title for setting via the CLI

If format-tab-title defined, set-tab-title does nothing. Is there a way to read set title from format-tab-title to display proper title?

damanis avatar Apr 04 '23 09:04 damanis

main lets you do activate an overlay prompt. It's not quite the same as click tab title to edit, but it is composable with other actions. Here's an example of renaming the current tab:

local wezterm = require 'wezterm'
local act = wezterm.action

local config = wezterm.config_builder()
config.keys = {
  {
    key = 'E',
    mods = 'CTRL|SHIFT',
    action = act.PromptInputLine {
      description = 'Enter new name for tab',
      action = wezterm.action_callback(function(window, pane, line)
        -- line will be `nil` if they hit escape without entering anything
        -- An empty string if they just hit enter
        -- Or the actual line of text they wrote
        if line then
          window:active_tab():set_title(line)
        end
      end),
    },
  },
}

return config

wez avatar Apr 05 '23 04:04 wez

@wez I tried this on latest main, the prompt shows, but after pressing enter it falls back to the zsh prompt, using the exact snippet you pasted above:

https://user-images.githubusercontent.com/75008413/229996712-b6baab41-94be-463e-a6d0-0f3c47190c55.mp4

cd-a avatar Apr 05 '23 06:04 cd-a

I had the same result and my guess would be that a zsh hock which sets the title (i.e. I use one from oh my zsh) overwrites it again.

jankatins avatar Apr 05 '23 10:04 jankatins

If you have a format-tab-title event handler, you need to update it to read tab:get_title().

wez avatar Apr 05 '23 13:04 wez