# ── tab_bar.py · kitty tab titles: repo dir, or the file nvim is editing ── # # kitty loads this file from the config dir and exposes `draw_title` as the # `{custom}` field of tab_title_template (kitty/tab_bar.py: # load_custom_draw_title). kitty still draws the powerline chrome; only the text # inside a tab comes from here. # # A title is one of: # 2 chezmoi <- repo the tab's cwd belongs to (dir name if no repo) # 3 astrocore.lua <- nvim is the active process: the file it is editing # # No subprocesses, no timers: the repo root is found by walking up for `.git`, # and the edited file comes from the window title nvim already sets # (~/.config/nvim/lua/plugins/astrocore.lua, custom_title autocmd: # " | " or " | Nvim", and "" / "Nvim" with no # file). kitty repaints the tab bar whenever that title changes, so the tab # tracks buffer switches for free. from __future__ import annotations import os from typing import Any # Nerd Font glyphs; VictorMono Nerd Font Mono covers both. FOLDER = '\uf07b' # nf-fa-folder NVIM = '\ue62b' # nf-custom-neovim EDITORS = frozenset({'nvim', 'vim', 'nvim-qt'}) MAX_LEN = 28 # wd -> repo root (or ''), memoized: a working dir keeps its answer for the life # of the kitty instance, so `git init` in an already-open dir needs a config # reload (ctrl+shift+alt+, in the herdr host, ctrl+shift+f5 here) to show up. _repo: dict[str, str] = {} def draw_title(data: dict[str, Any]) -> str: tab = data['tab'] label = '' if tab.active_exe in EDITORS: label = _nvim_file(data['title']) if label: return f'{data["index"]} {NVIM} {_elide(label)}' wd = tab.active_wd if wd: label = os.path.basename(_repo_root(wd) or wd.rstrip('/')) if wd == os.path.expanduser('~'): label = '~' return f'{data["index"]} {FOLDER} {_elide(label or data["title"])}' def _repo_root(wd: str) -> str: root = _repo.get(wd) if root is None: root = '' path = wd while True: if os.path.exists(os.path.join(path, '.git')): root = path break parent = os.path.dirname(path) if parent == path: break path = parent _repo[wd] = root return root def _nvim_file(title: str) -> str: """The file name out of an nvim window title, '' when it is editing none. Handles this config's " | " / " | Nvim" and nvim's own default "%t - Nvim" / " () - NVIM". """ text = title.strip() for suffix in (' - NVIM', ' - Nvim', ' - nvim'): if text.endswith(suffix): text = text[: -len(suffix)] text = text.split(' | ', 1)[0].strip() if text.endswith(')') and ' (' in text: text = text.split(' (', 1)[0].strip() # Left with a bare repo slug ("org/repo") or the placeholder: no file open. if not text or '/' in text or text.lower() == 'nvim': return '' return text def _elide(label: str) -> str: return label if len(label) <= MAX_LEN else label[: MAX_LEN - 1] + '…'