Skip to content

feat(tabs): add pin/unpin support for editor and non-editor tabs#1984

Merged
bajrangCoder merged 3 commits intoAcode-Foundation:mainfrom
bajrangCoder:feat/pin-tabs
Mar 27, 2026
Merged

feat(tabs): add pin/unpin support for editor and non-editor tabs#1984
bajrangCoder merged 3 commits intoAcode-Foundation:mainfrom
bajrangCoder:feat/pin-tabs

Conversation

@bajrangCoder
Copy link
Copy Markdown
Member

Fixes: #1330

@github-actions github-actions bot added the enhancement New feature or request label Mar 27, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 27, 2026

Greptile Summary

This PR implements pin/unpin support for both editor and terminal tabs (fixes #1330). A #pinned field is added to EditorFile with a full setPinnedState/togglePinned API, a dedicated tab tail icon, and guards in remove() that block closing pinned tabs. Terminal sessions persist their pin state across reconnects via terminalManager. The file menu and CodeMirror command registry both expose the toggle action, and saveState.js serialises pinned so the state survives restarts.\n\nKey additions:\n- EditorFile.setPinnedState() / togglePinned() with reorder / emit options\n- #createTabTail() replaces the close × with a pin icon when a tab is pinned\n- remove() guards with ignorePinned / silentPinned options\n- close-all-tabs skips pinned files; toggle-pin-tab command wired to menu, tab icon, and keyboard registry\n- addFile() uses getPinnedInsertIndex() to insert new pinned files at the correct position on session restore\n- Terminal: pinned threaded through persistTerminalSession, createTerminal, and reconnect paths\n\nOutstanding issue: moveFileByPinnedState only calls scrollIntoView and does not splice the file to its correct position in manager.files. Furthermore, togglePinned() always uses the default reorder: false, so moveFileByPinnedState is never invoked from the standard pin/unpin path. Tabs pinned via menu/icon stay in their original position, and the pinnedCount-based boundary in the drag handler can silently pin tabs the user only intended to reorder.

Confidence Score: 4/5

Safe to merge for basic pin/unpin UX, but tab ordering is broken after menu-pin, which can cause unintentional pinning during subsequent drag operations.

One confirmed P1 defect: moveFileByPinnedState does not reorder files, and togglePinned defaults to reorder: false, so menu/icon pinning never normalises tab order. This creates a state where pinned files are scattered in the array, causing the pinnedCount-based boundary logic in the drag handler to misfire and silently pin tabs the user only intended to reorder. All other paths (terminal persistence, close-all-tabs, session restore, remove guards) are correct.

src/lib/editorManager.js (moveFileByPinnedState implementation) and src/lib/editorFile.js (togglePinned reorder option) need attention before merge.

Important Files Changed

Filename Overview
src/lib/editorManager.js Adds addFile insertion ordering for pinned tabs and exposes moveFileByPinnedState / normalizePinnedTabOrder / syncOpenFileList; however moveFileByPinnedState only scrolls the active tab and does not reorder files in the array, making reorder: true in setPinnedState a no-op and breaking drag-drop pin boundary detection when tabs are pinned via menu.
src/lib/editorFile.js Adds #pinned field, setPinnedState/togglePinned/pinned getter-setter, #createTabTail for pin icon in tab, onpinstatechange callback, and guards in remove() for pinned tabs; implementation is mostly correct though tab reordering after menu-pin is not triggered due to reorder: false default in togglePinned.
src/handlers/editorFileTab.js Adds pinnedCount-based pin boundary detection during drag-drop with normalizePinnedTabOrder call when pin state changes; correctness depends on pinned tabs being contiguous at the start of the array, which breaks if tabs were pinned via menu without reordering.
src/components/terminal/terminalManager.js Propagates pinned property through terminal session persistence, creation, restoration, and title-rename paths; adds onpinstatechange callback to persist pin state on change and uses ignorePinned: true in forced terminal close paths.
src/lib/commands.js Adds toggle-pin-tab command and updates close-all-tabs to skip pinned files; correctly iterates with for...of instead of forEach to support proper await sequencing.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User action: Pin/Unpin tab] --> B{Via which path?}

    B --> C[Menu / Tab icon click]
    B --> D[Drag-drop tab]

    C --> E["togglePinned() → setPinnedState(!pinned, reorder:false)"]
    E --> F["#pinned updated, tab UI updated, events emitted"]
    F --> G["moveFileByPinnedState NOT called (reorder:false)"]
    G --> H["⚠️ Tab STAYS in current position\n(files array order unchanged)"]
    H --> I["pinnedCount in drag handler\nmay no longer reflect contiguous block"]
    I --> J["❌ Future drag boundary detection\ncan pin/unpin tabs incorrectly"]

    D --> K["updateFileList() called\npinnedCount computed from pre-drag list"]
    K --> L["DOM order → newFileList"]
    L --> M{Pin boundary\ncrossed?}
    M -- Yes --> N["setPinnedState(nextState, reorder:false)"]
    N --> O["normalizePinnedTabOrder() called\n(sort: pinned first, then unpinned)"]
    O --> P["✅ Correct order restored"]
    M -- No --> Q["No normalization\nOrder remains as dragged"]
Loading

Reviews (2): Last reviewed commit: "address the reviews" | Re-trigger Greptile

@UnschooledGamer
Copy link
Copy Markdown
Member

Check Greptile review comments. After that it's merge-able, With API Changes to be noted. 👍

@bajrangCoder

This comment was marked as outdated.

@bajrangCoder bajrangCoder merged commit a4b5eca into Acode-Foundation:main Mar 27, 2026
6 checks passed
@bajrangCoder bajrangCoder deleted the feat/pin-tabs branch March 27, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stick file in editor

2 participants