Files
vs-code-vertical-tabs/README.md
T
maxandClaude Opus 5 7e104450e8 Vertical Tabs: open editors as a project-coloured flat list
For working with the tab bar off, where a side list is the tab bar. VS Code's
Open Editors view already does pinning; what it does not do is colour by
project, and it is a tree rather than a flat list.

- A Tabs view in the Explorer: one row per open editor, no group nodes. A
  TreeDataProvider whose items have no children renders as a list, since
  there is no separate list API.
- Each row's icon is tinted by the project containing the file — the nearest
  .csproj/.fsproj/.vbproj, package.json, Cargo.toml, go.mod, pyproject.toml,
  pom.xml or build.gradle above it, configurable. The colour comes from a
  hash of the project name, so a project keeps its colour across sessions
  rather than depending on the order tabs happened to open in. Eight
  contributed theme colours, all overridable.
- Sort by open order, project (so the colours run in blocks), or file name,
  with pinned tabs lifted to the top.
- Close, close others (keeping pinned), pin/unpin, copy path, reveal.
- The list follows the active editor.

Two API limits shape this, both covered by tests:

- Nothing can activate an arbitrary tab. A file-backed tab is focused by
  re-opening its resource in its own group, which handles text, diffs,
  notebooks and custom editors. Webview tabs have no resource, so they are
  listed and marked as unfocusable instead of pretending.
- Only the *active* editor can be pinned, so pinning another row focuses it
  first.

Commands act on live vscode.Tab objects rather than the row snapshots handed
to them. The first cut compared against a snapshot's isPinned and so silently
did nothing on unpin, and read the provider's cached list, which is empty
until the tree has been rendered.

Also worth recording, both found by the tests: VS Code moves a pinned tab to
the front of its group, so `open` order shows pinned first regardless of the
pinnedFirst setting; and closeAllEditors leaves pinned editors open, so test
cleanup closes through the tab API instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 18:13:42 +02:00

3.9 KiB
Raw Blame History

Vertical Tabs

Your open editors as a flat vertical list, colour-coded by project. Built for working with the tab bar turned off ("workbench.editor.showTabs": "none"), where a side list is the tab bar.

It shows up as a Tabs view in the Explorer — drag it wherever you want it, including the secondary side bar.

What it adds over the built-in Open Editors view

  • A colour per project. Each row's icon is tinted by the project that contains the file — the nearest .csproj/.fsproj/.vbproj, package.json, Cargo.toml, go.mod, pyproject.toml, pom.xml or build.gradle above it. The colour comes from a hash of the project name, so a project keeps the same colour across sessions and windows.
  • A flat list, not a tree. One row per open editor, no group nodes to expand.
  • Sorting. Open order (matching the tab bar), by project so the colours run in blocks, or by file name. Pinned tabs stay on top.
  • The project name beside the file, along with the directory when two files share a name.

Pinning is VS Code's own — this view just exposes it per row, and pinned tabs sort first.

Usage

Action How
Focus a tab Click the row
Close The × on hover, or the context menu
Pin / unpin The pin icon on hover, or the context menu
Close others Context menu — keeps pinned tabs
Change sorting The view's menu

The list follows the active editor, so whatever you switch to is selected.

Settings

  • verticalTabs.orderopen (default), project, or name
  • verticalTabs.pinnedFirst — list pinned tabs above the rest (default true)
  • verticalTabs.showProject — show the project name beside the file (default true)
  • verticalTabs.showDirectory — show the directory beside the file (default true)
  • verticalTabs.colorByProject — tint each row's icon by project (default true)
  • verticalTabs.allGroups — list every editor group, not just the active one (default true)
  • verticalTabs.projectFiles — file names or extensions that mark a project root

The eight project colours are theme colours (verticalTabs.project1project8, plus verticalTabs.noProject), so you can override any of them in workbench.colorCustomizations.

Known limitations

  • Webview tabs cannot be focused from the list. There is no API to activate an arbitrary tab; a file-backed tab is focused by re-opening its resource, which webviews (Settings, Keyboard Shortcuts, Markdown preview, extension panels) do not have. They are listed, with a tooltip saying so, but clicking them does nothing.
  • Pinning another tab focuses it first. VS Code can only pin the active editor, so pinning a row means opening it and then pinning. Clicking a row's pin icon therefore also switches to it.
  • No drag to reorder. The list reflects VS Code's own tab order; it cannot rearrange it. Note that VS Code moves a pinned tab to the front of its group, so open order shows pinned tabs first regardless of verticalTabs.pinnedFirst — that setting only changes the project and name orders.
  • The colour replaces the file-type icon. Each row shows a tinted dot instead of the usual .cs/.json icon. Set verticalTabs.colorByProject to false to get file icons back and keep the project name in the description.
  • The colour is on the row's icon, not its label. Labels get the theme's own colouring (including Git status), which an extension cannot override without also recolouring the Explorer.

Tests

npm test launches VS Code with all other extensions disabled on a multi-project folder, opens editors, and asserts on the resulting list — projects resolved, ordering, pinning through the commands, diff tabs reporting their modified side, and webview tabs correctly reporting that they cannot be activated.

Point it at your own multi-project folder with VERTICAL_TABS_TEST_FOLDER:

VERTICAL_TABS_TEST_FOLDER=/path/to/solution npm test