Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5d990f5
feat: add pinned files to the working set model
devvaannsh Oct 18, 2026
4d33450
feat: show a pin on pinned files in the working set
devvaannsh Oct 18, 2026
d2bd6db
feat: tab bar context menu now uses the working set menu commands
devvaannsh Oct 18, 2026
b24100e
feat: update tabs in place instead of rebuilding the whole tab bar
devvaannsh Oct 18, 2026
38536ff
fix: overflow button staying visible when the tabs fit without it
devvaannsh Oct 18, 2026
8ec76b9
fix: tabs of the inactive pane not following its current file
devvaannsh Oct 18, 2026
60f38bf
fix: pinned working set items not showing the dirty indicator
devvaannsh Oct 18, 2026
458c3e9
fix: context menu commands acting on the active pane for the other pa…
devvaannsh Oct 18, 2026
edc46cf
fix: working set not updating when a tab is dragged to another pane
devvaannsh Oct 18, 2026
ae8a173
fix: maximum call stack error when switching panes with a file open i…
devvaannsh Oct 18, 2026
9742d8f
fix: rename and show in file tree not working when the sidebar is hidden
devvaannsh Oct 18, 2026
7f046fd
fix: resize observer loop error when the overflow button toggles
devvaannsh Oct 18, 2026
f57c23a
feat: add tab bar settings menu with smooth scrolling option
devvaannsh Oct 18, 2026
7220c6e
feat: use the live preview pin icon for pinned files
devvaannsh Oct 18, 2026
0b284ca
fix: right click selecting the item before opening its context menu
devvaannsh Oct 18, 2026
96130d5
feat: show placeholder item in the working set for single clicked files
devvaannsh Oct 18, 2026
b80b2d3
feat: number of tabs submenu in the tab bar settings and remove the s…
devvaannsh Oct 18, 2026
9220550
fix: editor flashing when clicking on the already active tab
devvaannsh Oct 18, 2026
b80b917
fix: tab width changing on pin and pin icon misaligned in the working…
devvaannsh Oct 18, 2026
a4fadb3
fix: right clicked file still remembered after the context menu closes
devvaannsh Oct 18, 2026
2e7210c
fix: closed file briefly showing as a placeholder while the next file…
devvaannsh Oct 18, 2026
ff60e72
fix: save keeping the wrong placeholder when triggered from the conte…
devvaannsh Oct 18, 2026
c706f56
fix: renaming a single clicked file leaving a stale tab and working s…
devvaannsh Oct 18, 2026
b3517d8
fix: dropping a tab in a pane that already has the file lands at the …
devvaannsh Oct 18, 2026
083de8f
fix: ctrl click on mac opening the tab and presses ending on the empt…
devvaannsh Oct 18, 2026
cc4fbcc
fix: overflow button showing up with an empty menu
devvaannsh Oct 18, 2026
8f6f3f9
fix: icon providers registered late not reflected on existing tabs
devvaannsh Oct 18, 2026
c5ba2d3
chore: auto update API docs
devvaannsh Oct 18, 2026
a691676
fix: pane header growing on hover and pushing the tab bar and editor
devvaannsh Oct 20, 2026
155980f
fix: keyboard shortcut icon touching the menu item label
devvaannsh Oct 20, 2026
fb0d845
fix: tab bar settings menu offering impractical tab counts and an ext…
devvaannsh Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/API-Reference/command/Commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ Closes all open files
## FILE\_CLOSE\_LIST
Closes files from list

**Kind**: global variable
<a name="FILE_PIN"></a>

## FILE\_PIN
Pins or unpins a file in the working set

**Kind**: global variable
<a name="FILE_REOPEN_CLOSED"></a>

Expand Down Expand Up @@ -470,6 +476,12 @@ Toggles live-preview full screen (design mode with the sidebar hidden)
## TOGGLE\_TABBAR
Toggles tabbar visibility

**Kind**: global variable
<a name="TOGGLE_TABBAR_SMOOTH_SCROLL"></a>

## TOGGLE\_TABBAR\_SMOOTH\_SCROLL
Toggles whether the tabbar animates when it scrolls to the active tab

**Kind**: global variable
<a name="VIEW_ZOOM_IN"></a>

Expand Down Expand Up @@ -500,6 +512,12 @@ Submenu for Open in project context menu
## OPEN\_IN\_SUBMENU\_WS
Submenu for Open in working set context menu

**Kind**: global variable
<a name="OPEN_IN_SUBMENU_FILE_TABS"></a>

## OPEN\_IN\_SUBMENU\_FILE\_TABS
Submenu for Open in file tab bar context menu

**Kind**: global variable
<a name="VIEW_INCREASE_FONT_SIZE"></a>

Expand Down
2 changes: 2 additions & 0 deletions docs/API-Reference/command/Menus.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ Brackets Context Menu Constants
| PROJECT_MENU | <code>string</code> | <code>&quot;project-context-menu&quot;</code> |
| WORKING_SET_CONTEXT_MENU | <code>string</code> | <code>&quot;workingset-context-menu&quot;</code> |
| WORKING_SET_CONFIG_MENU | <code>string</code> | <code>&quot;workingset-configuration-menu&quot;</code> |
| FILE_TABS_CONTEXT_MENU | <code>string</code> | <code>&quot;tabbar-context-menu&quot;</code> |
| FILE_TABS_SETTINGS_MENU | <code>string</code> | <code>&quot;tabbar-settings-context-menu&quot;</code> |
| SPLITVIEW_MENU | <code>string</code> | <code>&quot;splitview-menu&quot;</code> |

<a name="SubMenuIds"></a>
Expand Down
1 change: 1 addition & 0 deletions docs/API-Reference/features/TaskManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ like `showStopIcon`, `hideStopIcon`, etc.
| [options.onRetryClick] | <code>function</code> | | Callback function triggered when the retry button is clicked. |
| [options.onSelect] | <code>function</code> | | Callback function triggered when the task is selected from the dropdown. |
| [options.progressPercent] | <code>number</code> | | Initial progress percentage of the task. |
| [options.hideProgressBar] | <code>boolean</code> | | Hide progress for tasks waiting on a user action. |
| [options.noSpinnerNotification] | <code>boolean</code> | | If set to true, will not show the task spinners for this task. This can be used for silent background tasks where user attention is not needed. |

**Example**
Expand Down
21 changes: 21 additions & 0 deletions docs/API-Reference/project/FileViewController.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,24 @@ Opens the specified document with its associated external editor,
returns either WORKING_SET_VIEW or PROJECT_MANAGER

**Kind**: global function
<a name="setWorkingSetContext"></a>

## setWorkingSetContext(file, [paneId])
Remembers the file a working set or tab bar context menu was opened on. Pass null when the
menu closes. Fires `workingSetContextChange` with the context so the views can mark the file
while the menu is up.

**Kind**: global function

| Param | Type | Description |
| --- | --- | --- |
| file | <code>File</code> | the right-clicked file, or null to forget it |
| [paneId] | <code>string</code> | the pane the file is shown or listed in, defaults to the active pane |

<a name="getWorkingSetContext"></a>

## getWorkingSetContext() ⇒ <code>Object</code>
The file a working set or tab bar context menu is currently open for

**Kind**: global function
**Returns**: <code>Object</code> - null when no such menu is up
11 changes: 9 additions & 2 deletions docs/API-Reference/project/WorkingSetView.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,14 @@ to update an existing item, all previously applied classes have been cleared.

<a name="getContext"></a>

## getContext()
Gets the filesystem object for the current context in the working set.
## getContext() ⇒ <code>File</code>
Gets the file a working set or tab bar context menu is open for. Right-clicking an item doesn't
select it, so this is what the menu commands act on.

**Kind**: global function
<a name="getContextPaneId"></a>

## getContextPaneId() ⇒ <code>string</code>
Gets the id of the pane the file of `getContext()` is shown or listed in

**Kind**: global function
3 changes: 2 additions & 1 deletion docs/API-Reference/utils/DragAndDrop.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Returns true if the drag and drop items contains valid drop objects.
<a name="openDroppedFiles"></a>

## openDroppedFiles(paths) ⇒ <code>Promise</code>
Open dropped files
Open dropped files in order so the last file becomes active, regardless of load times.
Continue processing the remaining paths if an earlier file cannot be opened.

**Kind**: global function
**Returns**: <code>Promise</code> - Promise that is resolved if all files are opened, or rejected
Expand Down
35 changes: 34 additions & 1 deletion docs/API-Reference/view/MainViewManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ This module dispatches several events:
(e, fileRemoved:File, suppressRedraw:boolean, paneId:string)
- workingSetRemoveList -- When multiple files are removed from the working set
(e, filesRemoved:Array."File", paneId:string)
- workingSetSort -- When a pane's view array is reordered without additions or removals.
- workingSetSort -- When a pane's view array is reordered without additions or removals. Also fired when a
file is pinned or unpinned, as pinned files are kept at the front of the working set.
(e, paneId:string)
- workingSetUpdate -- When changes happen due to system events such as a file being deleted.
listeners should discard all working set info and rebuilt it from the pane
Expand Down Expand Up @@ -85,6 +86,8 @@ To listen for events, do something like this: (see EventDispatcher for details o
* [.addToWorkingSet(paneId, file, [index], [forceRedraw])](#module_view/MainViewManager..addToWorkingSet)
* [.addListToWorkingSet(paneId, fileList)](#module_view/MainViewManager..addListToWorkingSet)
* [.switchPaneFocus()](#module_view/MainViewManager..switchPaneFocus)
* [.setFilePinned(paneId, file, pinned)](#module_view/MainViewManager..setFilePinned) ⇒ <code>boolean</code>
* [.isPathPinned(paneId, fullPath)](#module_view/MainViewManager..isPathPinned) ⇒ <code>boolean</code>
* [.traverseToNextViewByMRU(direction)](#module_view/MainViewManager..traverseToNextViewByMRU) ⇒ <code>Object</code>
* [.traverseToNextViewInListOrder(direction)](#module_view/MainViewManager..traverseToNextViewInListOrder) ⇒ <code>Object</code>
* [.beginTraversal()](#module_view/MainViewManager..beginTraversal)
Expand Down Expand Up @@ -381,6 +384,36 @@ Adds the given file list to the end of the workingset.
Switch between panes

**Kind**: inner method of [<code>view/MainViewManager</code>](#module_view/MainViewManager)
<a name="module_view/MainViewManager..setFilePinned"></a>

### view/MainViewManager.setFilePinned(paneId, file, pinned) ⇒ <code>boolean</code>
Pins or unpins a file in a pane. Pinned files are kept at the front of the working set, in the order the
user arranged them, and the bulk close commands (close others, close all...) leave them alone.
Pinning a file that is only being previewed (not in the working set yet) adds it to the working set first.
Fires `workingSetSort` for the pane when the pinned state changes.

**Kind**: inner method of [<code>view/MainViewManager</code>](#module_view/MainViewManager)
**Returns**: <code>boolean</code> - true if the pinned state changed

| Param | Type | Description |
| --- | --- | --- |
| paneId | <code>string</code> | the id of the pane the file is in or ACTIVE_PANE |
| file | <code>File</code> | the file to pin or unpin |
| pinned | <code>boolean</code> | true to pin, false to unpin |

<a name="module_view/MainViewManager..isPathPinned"></a>

### view/MainViewManager.isPathPinned(paneId, fullPath) ⇒ <code>boolean</code>
Whether the file is pinned in the given pane

**Kind**: inner method of [<code>view/MainViewManager</code>](#module_view/MainViewManager)
**Returns**: <code>boolean</code> - true if the file is pinned

| Param | Type | Description |
| --- | --- | --- |
| paneId | <code>string</code> | the id of the pane or ACTIVE_PANE |
| fullPath | <code>string</code> | the full path of the file |

<a name="module_view/MainViewManager..traverseToNextViewByMRU"></a>

### view/MainViewManager.traverseToNextViewByMRU(direction) ⇒ <code>Object</code>
Expand Down
50 changes: 49 additions & 1 deletion docs/API-Reference/view/Pane.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Hidden views can be later shown by calling `pane.showView(view)`
* [.ITEM_NOT_FOUND](#module_view/Pane..Pane+ITEM_NOT_FOUND)
* [.ITEM_FOUND_NO_SORT](#module_view/Pane..Pane+ITEM_FOUND_NO_SORT)
* [.ITEM_FOUND_NEEDS_SORT](#module_view/Pane..Pane+ITEM_FOUND_NEEDS_SORT)
* [.getTemporaryViewFile()](#module_view/Pane..Pane+getTemporaryViewFile) ⇒ <code>File</code>
* [.mergeFrom(other)](#module_view/Pane..Pane+mergeFrom)
* [.destroy()](#module_view/Pane..Pane+destroy)
* [.getViewList()](#module_view/Pane..Pane+getViewList) ⇒ <code>Array.&lt;File&gt;</code>
Expand All @@ -161,6 +162,9 @@ Hidden views can be later shown by calling `pane.showView(view)`
* [.makeViewMostRecent(file)](#module_view/Pane..Pane+makeViewMostRecent)
* [.sortViewList(compareFn)](#module_view/Pane..Pane+sortViewList)
* [.swapViewListIndexes(index1, index2)](#module_view/Pane..Pane+swapViewListIndexes) ⇒ <code>boolean</code>
* [.isPathPinned(fullPath)](#module_view/Pane..Pane+isPathPinned) ⇒ <code>boolean</code>
* [.getPinnedCount()](#module_view/Pane..Pane+getPinnedCount) ⇒ <code>number</code>
* [.setPathPinned(fullPath, pinned)](#module_view/Pane..Pane+setPathPinned) ⇒ <code>boolean</code>
* [.traverseViewListByMRU(direction, [current])](#module_view/Pane..Pane+traverseViewListByMRU) ⇒ <code>File</code>
* [.showInterstitial(show)](#module_view/Pane..Pane+showInterstitial)
* [.getViewForPath(path)](#module_view/Pane..Pane+getViewForPath) ⇒ <code>boolean</code>
Expand Down Expand Up @@ -198,6 +202,7 @@ Hidden views can be later shown by calling `pane.showView(view)`
* [.ITEM_NOT_FOUND](#module_view/Pane..Pane+ITEM_NOT_FOUND)
* [.ITEM_FOUND_NO_SORT](#module_view/Pane..Pane+ITEM_FOUND_NO_SORT)
* [.ITEM_FOUND_NEEDS_SORT](#module_view/Pane..Pane+ITEM_FOUND_NEEDS_SORT)
* [.getTemporaryViewFile()](#module_view/Pane..Pane+getTemporaryViewFile) ⇒ <code>File</code>
* [.mergeFrom(other)](#module_view/Pane..Pane+mergeFrom)
* [.destroy()](#module_view/Pane..Pane+destroy)
* [.getViewList()](#module_view/Pane..Pane+getViewList) ⇒ <code>Array.&lt;File&gt;</code>
Expand All @@ -211,6 +216,9 @@ Hidden views can be later shown by calling `pane.showView(view)`
* [.makeViewMostRecent(file)](#module_view/Pane..Pane+makeViewMostRecent)
* [.sortViewList(compareFn)](#module_view/Pane..Pane+sortViewList)
* [.swapViewListIndexes(index1, index2)](#module_view/Pane..Pane+swapViewListIndexes) ⇒ <code>boolean</code>
* [.isPathPinned(fullPath)](#module_view/Pane..Pane+isPathPinned) ⇒ <code>boolean</code>
* [.getPinnedCount()](#module_view/Pane..Pane+getPinnedCount) ⇒ <code>number</code>
* [.setPathPinned(fullPath, pinned)](#module_view/Pane..Pane+setPathPinned) ⇒ <code>boolean</code>
* [.traverseViewListByMRU(direction, [current])](#module_view/Pane..Pane+traverseViewListByMRU) ⇒ <code>File</code>
* [.showInterstitial(show)](#module_view/Pane..Pane+showInterstitial)
* [.getViewForPath(path)](#module_view/Pane..Pane+getViewForPath) ⇒ <code>boolean</code>
Expand Down Expand Up @@ -319,6 +327,14 @@ and the workingset needs to be resorted

**Kind**: instance constant of [<code>Pane</code>](#module_view/Pane..Pane)
**See**: [Pane#reorderItem](Pane#reorderItem)
<a name="module_view/Pane..Pane+getTemporaryViewFile"></a>

#### pane.getTemporaryViewFile() ⇒ <code>File</code>
Gets the file of the current view when it isn't in the working set, a file opened from the file
tree with a single click just to have a look at it. A file that was just closed stays up until
the next one is ready but is on its way out, so it doesn't count

**Kind**: instance method of [<code>Pane</code>](#module_view/Pane..Pane)
<a name="module_view/Pane..Pane+mergeFrom"></a>

#### pane.mergeFrom(other)
Expand Down Expand Up @@ -443,7 +459,7 @@ Moves the specified file to the front of the MRU (Most Recently Used) list.
<a name="module_view/Pane..Pane+sortViewList"></a>

#### pane.sortViewList(compareFn)
Sorts items in the pane's view list.
Sorts items in the pane's view list. Pinned files are sorted amongst themselves and stay in front.

**Kind**: instance method of [<code>Pane</code>](#module_view/Pane..Pane)

Expand All @@ -464,6 +480,38 @@ Swaps two items in the file view list (used while dragging items in the working
| index1 | <code>number</code> | the index of the first item to swap |
| index2 | <code>number</code> | the index of the second item to swap |

<a name="module_view/Pane..Pane+isPathPinned"></a>

#### pane.isPathPinned(fullPath) ⇒ <code>boolean</code>
Whether the file is pinned in this pane

**Kind**: instance method of [<code>Pane</code>](#module_view/Pane..Pane)

| Param | Type | Description |
| --- | --- | --- |
| fullPath | <code>string</code> | the full path of the file |

<a name="module_view/Pane..Pane+getPinnedCount"></a>

#### pane.getPinnedCount() ⇒ <code>number</code>
Returns the number of pinned files. As pinned files are always kept at the front of the view list,
this is also the index of the first unpinned file.

**Kind**: instance method of [<code>Pane</code>](#module_view/Pane..Pane)
<a name="module_view/Pane..Pane+setPathPinned"></a>

#### pane.setPathPinned(fullPath, pinned) ⇒ <code>boolean</code>
Pins or unpins a file in the view list. Pinning moves the file to the end of the pinned block and
unpinning moves it to the start of the unpinned block, so nothing else changes position.

**Kind**: instance method of [<code>Pane</code>](#module_view/Pane..Pane)
**Returns**: <code>boolean</code> - true if the pinned state changed

| Param | Type | Description |
| --- | --- | --- |
| fullPath | <code>string</code> | the full path of the file, it must be in the view list |
| pinned | <code>boolean</code> | true to pin, false to unpin |

<a name="module_view/Pane..Pane+traverseViewListByMRU"></a>

#### pane.traverseViewListByMRU(direction, [current]) ⇒ <code>File</code>
Expand Down
10 changes: 10 additions & 0 deletions src/command/Commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ define(function (require, exports, module) {
/** Closes files from list */
exports.FILE_CLOSE_LIST = "file.close_list"; // DocumentCommandHandlers.js handleFileCloseList()

/** Pins or unpins a file in the working set */
exports.FILE_PIN = "file.pin"; // DocumentCommandHandlers.js handleFilePin()

/** Reopens last closed file */
exports.FILE_REOPEN_CLOSED = "file.reopen_closed"; // DocumentCommandHandlers.js handleReopenClosed()

Expand Down Expand Up @@ -267,6 +270,10 @@ define(function (require, exports, module) {
exports.TOGGLE_TABBAR = "view.toggleTabbar";
// extensionsIntegrated/TabBar/main.js

/** Toggles whether the tabbar animates when it scrolls to the active tab */
exports.TOGGLE_TABBAR_SMOOTH_SCROLL = "view.toggleTabbarSmoothScroll";
// extensionsIntegrated/TabBar/main.js

/** Zooms in the editor view */
exports.VIEW_ZOOM_IN = "view.zoomIn"; // ViewCommandHandlers.js _handleZoomIn()

Expand All @@ -282,6 +289,9 @@ define(function (require, exports, module) {
/** Submenu for Open in working set context menu */
exports.OPEN_IN_SUBMENU_WS = "file-open-in-submenu-ws";

/** Submenu for Open in file tab bar context menu */
exports.OPEN_IN_SUBMENU_FILE_TABS = "file-open-in-submenu-file-tabs";

/** Increases editor font size */
exports.VIEW_INCREASE_FONT_SIZE = "view.increaseFontSize"; // ViewCommandHandlers.js _handleIncreaseFontSize()

Expand Down
Loading
Loading