# 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. ## Two ways to use it **Just the colours.** `verticalTabs.decorateFiles` colours files by project wherever VS Code shows file decorations — the Explorer, the built-in **Open Editors** view, and the editor tabs. If colour coding is all you want, use this and keep the built-in view: it drags to dock, shows file icons, and can focus every kind of tab. Set it to `colorAndBadge` to add a two-letter project badge such as `AC` for `Acme.Shop.Client`. **The Tabs view.** A drawn list that the built-in view cannot be: a project border down each row, real spacing, and file names that keep their extension. Costs drag-and-drop and file icons — see *Known limitations*. ## What it adds over the built-in Open Editors view - **A colour per project**, as a border down the left of each row — the way Visual Studio marks them. The project is the nearest `.asmdef`, `.csproj`/`.fsproj`/`.vbproj`, `package.json`, `Cargo.toml`, `go.mod`, `pyproject.toml`, `pom.xml` or `build.gradle` above the file. 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. - **Names that stay readable in a narrow strip.** The stem is ellipsized but the extension never is, so you get `ClientDogSurgeryCompanionBeha… .cs` rather than losing the `.cs`. - **Sorting.** Open order (matching the tab bar), by project so the colours run in blocks, or by file name. Pinned tabs stay on top, with a rule under the pinned block. - **Room to breathe.** Row spacing and border width are settings. Pinning is VS Code's own — this view exposes it per row as a single toggle, and pinned tabs sort first. ## Usage | Action | How | | --- | --- | | Focus a tab | Click the row | | Close | The `×` on hover, middle-click, or `Delete` | | Pin / unpin | The pin icon on the left of the row — one button, filled when pinned | | Close others | Right-click → *Close Others* — keeps pinned tabs | | Copy path, reveal in Explorer | Right-click | | Move around | Arrow keys, `Home`, `End`, `Enter` to open | | Change sorting | The view's `…` menu | The list follows the active editor, so whatever you switch to is selected. An unsaved file shows a dot, which the close button replaces on hover. ## Settings - `verticalTabs.decorateFiles` — colour files by project in the Explorer, Open Editors and tabs: `off`, `color` (default), or `colorAndBadge` - `verticalTabs.order` — `open` (default), `project`, or `name` - `verticalTabs.pinnedFirst` — list pinned tabs above the rest (default `true`) - `verticalTabs.colorByProject` — colour each row's left border by project (default `true`) - `verticalTabs.borderWidth` — width of that border in pixels (default `3`) - `verticalTabs.rowSpacing` — pixels between rows (default `3`) - `verticalTabs.showProject` — also show the project name as text (default `false`, so the file name gets the whole row and the border alone tells you the project); turn it on for the name in text too - `verticalTabs.showDirectory` — when to show the directory: `never`, `duplicates` (default — only when two open tabs share a file name), or `always` - `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 twelve project colours are theme colours (`verticalTabs.project1` … `project12`, plus `verticalTabs.noProject`), so you can pin a project to a specific colour 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 in italics, with a tooltip saying so, and clicking does nothing rather than pretending. - **Pinning another tab focuses it first.** VS Code can only pin the *active* editor, so the pin button also switches to that tab. - **No drag to reorder.** The list reflects VS Code's own tab order. 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. - **No file-type icons.** The row shows the project border instead. Adding icons back would mean bundling an icon set, since a webview cannot reach the active file-icon theme. - Rows are drawn rather than native, so they do not pick up list styling from every theme the way a tree view would, and there is no native drag-and-drop. - **Drag to dock is not possible in this view, at all.** Dragging a row into the editor area needs `TreeDragAndDropController` and its `text/uri-list` support, which only tree views have — a drag started inside a webview iframe cannot be handed to the workbench. If dragging matters more than the borders and spacing, use `decorateFiles` with the built-in Open Editors view instead. - Decorations colour the Explorer as well as the Open Editors view; there is no way to target one. Git also decorates modified files and only one colour wins, so a dirty file may show Git's colour rather than its project's. ## 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 real actions, 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`: ```bash VERTICAL_TABS_TEST_FOLDER=/path/to/solution npm test ``` The rendering itself is checked in a browser harness at side-bar width, driving the same `media/tabs.js` with stub tab data.