Vertical Tabs for Obsidian

repository·master·Indexed 20 days ago

https://github.com/oxdc/obsidian-vertical-tabs

An Obsidian plugin (v0.17.7) that replaces the default horizontal tab bar with a vertical list. It provides advanced workspace management including tab grouping, IDE-like navigation, per-tab zooming, Zen mode, and automatic tab deduplication to improve navigation and organization of large numbers of open notes.

Tokens
10.7K
Snippets
38
Records
55
Agent score
66%

What's inside oxdc-obsidian-vertical-tabs

  1. Overview of Vertical Tabs for Obsidian

    master

    Vertical Tabs is a workspace manager for Obsidian designed to solve the limitations of the default horizontal tab layout. It introduces a vertical list of tabs, making it easier to manage, group, and organize a large number of open notes without losing readability as tabs become narrower.

    Key features include:

    • Tab Organization: Grouping and organizing tabs for efficient navigation.
    • Enhanced Navigation: Advanced tab navigation with customizable presets (e.g., IDE mode), an extended keyboard tab switcher, and a tab history browser.
    • Workspace Management: Per-tab zooming, Zen mode, ephemeral tabs, and automatic tab deduplication.
    • Customization: Ability to create personalized tab navigation strategies.
  2. Tab Zoom Feature

    master

    The plugin supports a tab zoom feature that adjusts the visual scale of tabs. This is implemented by patching ItemView and applying a CSS variable --vt-tab-zoom-factor to the view's container element.

    • Requirement: enableTabZoom must be enabled in settings.
    • Mechanism: The zoom factor is stored in the view's ephemeral state to ensure it persists during the view's lifecycle.
  3. Understand Tab Closing Behavior

    master

    When a tab is closed, the plugin can automatically select a new active tab based on the configured tabClosingBehavior. This is controlled via the TabClosingBehavior enum.

    Supported behaviors:

    • ActiveLeft: Selects the tab to the left of the closed tab.
    • ActiveRight: Selects the tab to the right, or falls back to the left if no right tab exists.
    • ActiveRecent: Selects the tab that was most recently active among the remaining tabs.
  4. Advanced Tab Navigation and Deduplication

    master

    The plugin patches WorkspaceLeaf.openFile and WorkspaceLeaf.canNavigate to implement several advanced behaviors:

    • Deduplication: If enabled, the plugin checks if a file is already open in another leaf. If a match is found, it avoids opening a duplicate and instead focuses the existing leaf and detaches the current one. This can be scoped to deduplicateTabs, deduplicateSameGroupTabs, deduplicateSidebarTabs, or deduplicatePopupTabs.
    • Ephemeral Tabs: Controlled by ephemeralTabs setting, these tabs follow specific navigation rules.
    • Smart Navigation: Uses executeSmartNavigation to decide if a navigation request should proceed based on the current view state.
    • Always Open in New Tab: If alwaysOpenInNewTab is enabled, canNavigate returns false to force new tab creation.
  5. Manage Group View Types with GroupViewType

    master

    The plugin uses GroupViewType to define how a group of tabs (a WorkspaceParent) is rendered and behaves. You can identify or change the layout mode of a workspace group using these types.

    Available view types:

    • GroupViewType.Default: The standard vertical tab view.
    • GroupViewType.ContinuousView: A continuous scrolling view. When active, it respects settings for showing metadata (vt-continuous-view-show-metadata) and backlinks (vt-continuous-view-show-backlinks).
    • GroupViewType.ColumnView: A column-based layout.
    • GroupViewType.MissionControlView: A specialized view for overviewing many leaves, which enables dragging and specific zoom factors.
    export enum GroupViewType {
    	Default = "vt-default-view",
    	ContinuousView = "vt-continuous-view",
    	ColumnView = "vt-column-view",
    	MissionControlView = "vt-mission-control-view",
    }
  6. Navigate tabs using View Cues

    master

    The plugin implements a 'View Cue' system to allow users to navigate through tabs using indices (e.g., 1-8). This system maps user-facing indices to actual Obsidian WorkspaceLeaf objects, accounting for an offset that allows cycling through groups of tabs.

    • mapViewCueIndex: Converts a real index to a user-facing ViewCueIndex (which can be a number, or special tokens like VIEW_CUE_NEXT () or VIEW_CUE_PREV ()).
    • convertBackToRealIndex: Converts a user-facing index back to the actual Obsidian leaf index.
    • revealTabOfUserIndex: The primary method to trigger navigation to a specific tab based on the user's perceived index.
    • viewCueOffset: An internal offset used to shift the window of visible indices.
  7. Configure Vertical Tabs via Settings

    master

    The plugin provides a dedicated settings tab (ObsidianVerticalTabsSettingTab) to control various behaviors. Settings are applied by toggling specific CSS classes on the document body.

    Key configuration categories include:

    • UI Appearance: hideSidebars, showActiveTabs, scrollableTabs, autoHideHorizontalTabs, trimTabNames, zenMode, enableTabZoom.
    • Tab Behavior: sidebarExcludeSelf, useTabEditing, ephemeralTabs, alwaysOpenInNewTab, allowWorkspaceSplitOnPhone.
    • Advanced Features: backgroundMode, disablePointerInMissionControlView.
  8. Configure Obsidian Vertical Tabs settings

    master

    The ObsidianVerticalTabsSettings interface defines the configuration schema for the plugin. Users can customize tab visibility, navigation strategies, deduplication behaviors, and view modes (like Zen Mode or Mission Control).

    Key configuration categories include:

    • Tab Visibility & Display: showActiveTabs, trimTabNames, showMoreButtons, enableTabZoom, scrollableTabs, and autoHideHorizontalTabs.
    • Sidebar Behavior: sidebarTabTypes (e.g., ['markdown']), sidebarExcludeSelf, and hideSidebars.
    • Navigation & Interaction: navigationStrategy (using TabNavigationStrategy), smartNavigation, enhancedKeyboardTabSwitch, and tabClosingBehavior (using TabClosingBehavior).
    • Deduplication: deduplicateTabs, deduplicateSameGroupTabs, deduplicateSidebarTabs, and deduplicatePopupTabs.
    • Special Modes: zenMode, missionControlViewZoomFactor, and backgroundMode.
    • New Tab Behavior: newTabButtonPlacement (using NewTabButtonPlacement) and alwaysOpenInNewTab.
    // Example of the settings structure
    const settings: ObsidianVerticalTabsSettings = {
      showActiveTabs: false,
      hideSidebars: true,
      sidebarTabTypes: ["markdown"],
      navigationStrategy: TabNavigationStrategy.ObsidianPlus,
      newTabButtonPlacement: NewTabButtonPlacement.GroupToolbar,
      tabClosingBehavior: TabClosingBehavior.ActiveRight,
      // ... other settings
    };
  9. Reference the default Obsidian Vertical Tabs settings

    master

    The DEFAULT_SETTINGS object provides the baseline configuration for the plugin. If a setting is not explicitly defined by the user, these values are used.

    KeyDefault Value
    showActiveTabsfalse
    autoUncollapseGroupfalse
    hideSidebarstrue
    sidebarTabTypes["markdown"]
    sidebarExcludeSelftrue
    trimTabNamesfalse
    showMoreButtonsfalse
    useTabEditingtrue
    zenModefalse
    showActiveTabsInZenModefalse
    enableTabZoomfalse
    enhancedKeyboardTabSwitchfalse
    alwaysOpenInNewTabfalse
    deduplicateTabsfalse
    ephemeralTabsfalse
    smartNavigationtrue
    navigationStrategyTabNavigationStrategy.ObsidianPlus
    autoCloseEphemeralTabstrue
    deduplicateSameGroupTabsfalse
    deduplicateSidebarTabsfalse
    deduplicatePopupTabsfalse
    linkedFolderLimit5
    linkedFolderSortStrategy"fileNameAToZ"
    continuousViewShowMetadatafalse
    continuousViewShowBacklinksfalse
    columnViewMinWidth300
    missionControlViewZoomFactor0.5
    disablePointerInMissionControlViewtrue
    showMissionControlToggletrue
    backgroundModefalse
    scrollableTabstrue
    scrollableTabsMinWidth100
    autoHideHorizontalTabsfalse
    disableOnThisDevicefalse
    allowWorkspaceSplitOnPhonefalse
    enableUpdateChecktrue
    newTabButtonPlacementNewTabButtonPlacement.GroupToolbar
    tabClosingBehaviorTabClosingBehavior.ActiveRight
  10. Safely detach a WorkspaceLeaf

    master

    The safeDetach function detaches a WorkspaceLeaf from the workspace. If the leaf's view is an instance of FileView, it sets isDetachingFromVT to true to signal the detachment process to the Vertical Tabs plugin. The function catches and ignores errors during detachment, which can occur when detaching Bases during tab deduplication (a known behavior in Obsidian v1.9).

    import { WorkspaceLeaf } from "obsidian";
    import { safeDetach } from "./services/CloseTabs";
    
    safeDetach(leaf);
  11. Manage plugin settings with useSettings

    master

    The useSettings hook (created via createSelectors from useSettingsBase) provides a reactive way to read and mutate plugin settings. It combines the current Settings state with several action methods to modify that state.

    Key Actions

    • setSettings(mutator): Updates settings. The mutator can be a partial Settings object or a function that receives the current settings and returns new ones.
    • toggleZenMode(): Toggles Zen Mode, handling the persistence of showActiveTabs state.
    • toggleBackgroundMode(app, enable?): Toggles Background Mode. If enabled, it moves the plugin view to a new group and hides it.
    • setTabNavigationStrategy(app, name, preset?): Changes the tab navigation strategy using a name and an optional preset.
    • setGroupViewOptions(app, options): Updates group view configurations like columnViewMinWidth or missionControlViewZoomFactor.
    import { useSettings } from 'src/models/PluginContext';
    
    const SettingsControl = () => {
      const { zenMode, toggleZenMode, setSettings } = useSettings();
    
      return (
        <button onClick={() => toggleZenMode()}>
          {zenMode ? 'Exit Zen Mode' : 'Enter Zen Mode'}
        </button>
      );
    };