New Tab Here

by Ash RuDral
5
4
3
2
1
Score: 50/100

Description

Obsidian plugin that makes new tabs open next to the active tab — from the "+" button, command palette, or hotkey — instead of at the end of the tab strip.

Reviews

No reviews yet.

Stats

0
stars
43
downloads
0
forks
42
days
43
days
43
days
0
total PRs
0
open PRs
0
closed PRs
0
merged PRs
0
total issues
0
open issues
0
closed issues
3
commits

Latest Version

a month ago

Changelog

Opens new tabs directly next to the active tab instead of at the end of the tab strip.

README file from

Github

New Tab Here

Makes new tabs — from the "+" button, the command palette, or your configured "New tab" hotkey — open directly next to the active tab, instead of at the end of the tab strip.

Installation
  1. In your vault, go to .obsidian/plugins/.
  2. Create a folder named new-tab-here.
  3. Copy manifest.json and main.js into that folder.
  4. In Obsidian: Settings → Community plugins → make sure "Restricted mode" is off → click the refresh icon next to "Installed plugins" → enable "New Tab Here".

No build step needed — main.js is plain JS that Obsidian loads directly.

How it works

There are two independent interception paths, because Obsidian's core "New tab" command turned out to be reachable in ways that don't all go through the same code path:

  1. Command patch — covers the command palette, the ribbon "+" button, and anything else that calls executeCommandById on the "New tab" command. The command is located dynamically (by id, with a name-based fallback) so a future Obsidian rename doesn't disable this. Both callback and checkCallback are wrapped, since it's not guaranteed which one a given Obsidian version uses.
  2. Hotkey interception — a keydown listener on document (capture phase) that fires before Obsidian's own key handling. This exists because pressing the "New tab" hotkey doesn't reliably route through the patched command object the way palette invocation does — Obsidian appears to resolve some core hotkeys through a lower-level keymap. The listener reads your actual configured hotkey for "New tab" (custom or default) via Obsidian's hotkey manager, so it keeps working if you ever rebind it, falling back to Ctrl/Cmd+T only if that lookup isn't available.

Both paths call the same placement logic:

  • Find the active tab and its tab group.
  • Call Obsidian's own public Workspace.createLeafInParent(parent, index) API to insert the new leaf directly at the correct position — no after-the-fact shuffling needed.
  • Set the new leaf to Obsidian's built-in blank-tab view (type: 'empty') and focus it.
  • If that public API ever throws (e.g. a future Obsidian version changes its behavior), fall back to letting core create the tab at the end, then reposition it by adjusting both the tab group's internal order and the visible tab-header DOM order.
  • If the new tab ever lands in a different tab group, split, sidebar, or popout window than where you started, nothing is touched — no guessing.
Why this approach

Rather than building an independent new-tab feature with its own hotkey, this hooks the single command Obsidian already uses for every "New tab" trigger, plus a hotkey-level safety net for the one trigger that doesn't reliably go through that command. That keeps the change scoped: only "New tab" behavior is touched, and core's own tab-creation, history, and session logic still does the actual work.

Robustness notes
  • Every internal-API touch is wrapped in try/catch. Worst case, a tab opens at the end (core's default) rather than the plugin breaking tab creation or corrupting your layout.
  • Toggle the plugin off instantly from Settings → New Tab Here to isolate it if something looks off.
  • Turn on "Debug logging" in settings to see, via the developer console (Ctrl/Cmd+Shift+I), exactly which path handled each new tab and what it decided to do.
Known limitation

The fallback reposition path (only used if createLeafInParent fails) depends on undocumented internals (WorkspaceTabs.children, WorkspaceLeaf.tabHeaderEl). A major Obsidian UI rewrite could disable just that fallback; the primary createLeafInParent path is public API and much less likely to be affected.

Contributing

See CONTRIBUTING.md for how to build, release, and submit changes to this plugin.