← all posts

Ghostty tab titles from git repo names

Gordon Beeming
Gordon Beeming
On this page2 sections ▾

When I run Claude Code and GitHub Copilot CLI across several Ghostty tabs, process names such as "claude" and "copilot" don't tell me which project is open. I wanted each tab to show the git repo name, with a short directory path as the fallback outside a repo.

A zsh hook sets the title, and a Ghostty setting stops its shell integration from overwriting it.

If you're using copilot_here (my sandboxed Docker wrapper for GitHub Copilot CLI), this is actually better. It sets custom tab titles that tell you what's going on at a glance. Normal mode shows "🤖 xylem", YOLO mode (auto-approve everything) shows "🤖⚡️ xylem", and if you've got Airlock enabled (the secure network isolation mode that restricts which domains the container can reach) you get "🤖 xylem 🛡️". You can immediately tell which project, which mode, and whether network isolation is active, all from the tab title. But it only applies to the copilot_here panels, not to your Claude Code sessions or regular shells.

#The fix

Two changes: a zsh function that sets the tab title, and a Ghostty config tweak to stop Ghostty from stepping on it.

#The zsh hook

Add this to your .zshrc:

.zshrc
# Update Ghostty tab title to git repo name (or current folder)
set_ghostty_title() {
  local dir="$PWD"
  while [[ "$dir" != "/" ]]; do
    if [[ -d "$dir/.git" ]]; then
      echo -ne "\e]0;${dir##*/}\a"
      return
    fi
    dir="${dir:h}"
  done
  # Not in a git repo — show last 3 path segments
  local short_path
  short_path=$(echo "$PWD" | awk -F/ '{
    n=NF;
    if(n>=3) print $(n-2)"/"$(n-1)"/"$n;
    else if(n==2) print $(n-1)"/"$n;
    else print $n
  }')
  echo -ne "\e]0;${short_path}\a"
}

autoload -Uz add-zsh-hook
add-zsh-hook chpwd set_ghostty_title

# Also run on shell startup so the first tab gets named
set_ghostty_title

Here's what it does:

  • chpwd hook: zsh fires this every time you cd to a different directory, so the title updates as you move around
  • Walk up the tree: starting from $PWD, it checks each parent directory for a .git folder
  • Repo name: when it finds .git, it uses that directory's basename as the title (so /Users/gordonbeeming/Developer/github/gordonbeeming/xylem becomes "xylem")
  • Fallback: if it hits / without finding .git, it shows the last three path segments instead of the full path
  • Startup: runs once when the shell starts so the first tab gets named immediately, not just after your first cd

The echo -ne "\e]0;...\a" part is an OSC 0 escape sequence that tells the terminal to set the window/tab title. Most terminals support this.

#The Ghostty config

After adding the zsh hook and reloading my shell, the tab still showed the directory path.

Ghostty's built-in shell integration sets the tab title to the working directory, and it was overwriting my custom title on every prompt. The fix is one line in your Ghostty config (~/.config/ghostty/config):

~/.config/ghostty/config
shell-integration-features = no-title

This tells Ghostty to keep all its other shell integration features (marking prompt boundaries, tracking the current directory for Cmd+Click on paths) but leave the tab title alone. Your zsh hook takes it from there.

You'll need to restart Ghostty (not just open a new tab) for this config change to take effect.

#My workflow

I tend to work with multiple panels per tab in Ghostty, usually one tab per project. A typical layout is four panels: Claude Code running in one, GitHub Copilot CLI in another, and two regular shells for running builds, tests, or git commands.

The keyboard shortcuts I use:

  • Cmd+D to split right (new panel to the right)
  • Cmd+Shift+D to split down (new panel below)
  • Cmd+Shift+Enter to toggle a panel to full screen and back
  • Ctrl+Tab / Ctrl+Shift+Tab to navigate between tabs
  • Cmd+Option+Arrows to move focus between panels within a tab

With this configuration, a tab in the xylem repo keeps that name as I move between its subdirectories. Outside a repo, the last three path segments give me enough context to identify the directory.

Gordon Beeming
Gordon Beeming

Father • Husband • Triathlete • SSW Solution Architect

Related posts