Skip to content

Commit 74475b1

Browse files
committed
feat: implement close and close active tab in more options context menu
1 parent 9a4f60d commit 74475b1

File tree

3 files changed

+101
-67
lines changed

3 files changed

+101
-67
lines changed

src/extensionsIntegrated/TabBar/main.js

Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -368,50 +368,6 @@ define(function (require, exports, module) {
368368
}
369369

370370

371-
/**
372-
* Handle close button click on tabs
373-
* This function will remove the file from the working set
374-
*
375-
* @param {String} filePath - path of the file to close
376-
*/
377-
function handleTabClose(filePath) {
378-
// Logic: First open the file we want to close, then close it and finally restore focus
379-
// Why? Because FILE_CLOSE removes the currently active file from the working set
380-
381-
// Get the current active editor to restore focus later
382-
const currentActiveEditor = EditorManager.getActiveEditor();
383-
const currentActivePath = currentActiveEditor ? currentActiveEditor.document.file.fullPath : null;
384-
385-
// Only need to open the file first if it's not the currently active one
386-
if (currentActivePath !== filePath) {
387-
// open the file we want to close
388-
CommandManager.execute(Commands.FILE_OPEN, { fullPath: filePath })
389-
.done(function () {
390-
// close it
391-
CommandManager.execute(Commands.FILE_CLOSE)
392-
.done(function () {
393-
// If we had a different file active before, restore focus to it
394-
if (currentActivePath && currentActivePath !== filePath) {
395-
CommandManager.execute(Commands.FILE_OPEN, { fullPath: currentActivePath });
396-
}
397-
})
398-
.fail(function (error) {
399-
console.error("Failed to close file:", filePath, error);
400-
});
401-
})
402-
.fail(function (error) {
403-
console.error("Failed to open file for closing:", filePath, error);
404-
});
405-
} else {
406-
// if it's already the active file, just close it
407-
CommandManager.execute(Commands.FILE_CLOSE)
408-
.fail(function (error) {
409-
console.error("Failed to close file:", filePath, error);
410-
});
411-
}
412-
}
413-
414-
415371
/**
416372
* handle click events on the tabs to open the file
417373
*/
@@ -423,8 +379,20 @@ define(function (require, exports, module) {
423379
if ($(event.target).hasClass('fa-times') || $(event.target).closest('.tab-close').length) {
424380
// Get the file path from the data-path attribute of the parent tab
425381
const filePath = $(this).attr("data-path");
382+
426383
if (filePath) {
427-
handleTabClose(filePath);
384+
// determine the pane inside which the tab belongs
385+
const isSecondPane = $(this).closest("#phoenix-tab-bar-2").length > 0;
386+
const paneId = isSecondPane ? "second-pane" : "first-pane";
387+
388+
// get the file object
389+
const fileObj = FileSystem.getFileForPath(filePath);
390+
// close the file
391+
CommandManager.execute(
392+
Commands.FILE_CLOSE,
393+
{ file: fileObj, paneId: paneId }
394+
);
395+
428396
// Prevent default behavior
429397
event.preventDefault();
430398
event.stopPropagation();
@@ -450,17 +418,20 @@ define(function (require, exports, module) {
450418
}
451419
});
452420

453-
// Add contextmenu (right-click) handler
421+
// Add the contextmenu (right-click) handler
454422
$(document).on("contextmenu", ".tab", function (event) {
455423
event.preventDefault();
456424
event.stopPropagation();
457425

458-
// Determine which pane the tab belongs to
426+
// get the file path from the data-path attribute
427+
const filePath = $(this).attr("data-path");
428+
429+
// determine which pane the tab belongs to
459430
const isSecondPane = $(this).closest("#phoenix-tab-bar-2").length > 0;
460431
const paneId = isSecondPane ? "second-pane" : "first-pane";
461432

462-
// Show context menu at mouse position
463-
MoreOptions.showMoreOptionsContextMenu(paneId, event.pageX, event.pageY);
433+
// show the context menu at mouse position
434+
MoreOptions.showMoreOptionsContextMenu(paneId, event.pageX, event.pageY, filePath);
464435
});
465436
}
466437

src/extensionsIntegrated/TabBar/more-options.js

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,83 @@
11
/*
22
* This file manages the more options context menu.
3-
* The more option button is present at the right side of the tab bar.
4-
* When clicked, it will show the more options context menu.
5-
* which will have various options related to the tab bar
3+
* The more options context menu is shown when a tab is right-clicked
64
*/
75
define(function (require, exports, module) {
86
const DropdownButton = require("widgets/DropdownButton");
97
const Strings = require("strings");
10-
const MainViewManager = require("view/MainViewManager");
118
const CommandManager = require("command/CommandManager");
129
const Commands = require("command/Commands");
10+
const FileSystem = require("filesystem/FileSystem");
1311

14-
const Global = require("./global");
15-
const Helper = require("./helper");
1612

1713
// List of items to show in the context menu
1814
// Strings defined in `src/nls/root/strings.js`
1915
const items = [
16+
Strings.CLOSE_TAB,
17+
Strings.CLOSE_ACTIVE_TAB,
2018
Strings.CLOSE_ALL_TABS,
2119
Strings.CLOSE_UNMODIFIED_TABS,
20+
"---",
2221
Strings.REOPEN_CLOSED_FILE
2322
];
2423

2524

2625
/**
27-
* This function is called when the close all tabs option is selected from the context menu
26+
* "CLOSE TAB"
27+
* this function handles the closing of the tab that was right-clicked
28+
*
29+
* @param {String} filePath - path of the file to close
30+
* @param {String} paneId - the id of the pane in which the file is present
31+
*/
32+
function handleCloseTab(filePath, paneId) {
33+
if (filePath) {
34+
// Get the file object using FileSystem
35+
const fileObj = FileSystem.getFileForPath(filePath);
36+
37+
// Execute close command with file object and pane ID
38+
CommandManager.execute(
39+
Commands.FILE_CLOSE,
40+
{ file: fileObj, paneId: paneId }
41+
);
42+
}
43+
}
44+
45+
46+
/**
47+
* "CLOSE ACTIVE TAB"
48+
* this closes the currently active tab
49+
* doesn't matter if the context menu is opened from this tab or some other tab
50+
*/
51+
function handleCloseActiveTab() {
52+
// This simply executes the FILE_CLOSE command without parameters
53+
// which will close the currently active file
54+
CommandManager.execute(Commands.FILE_CLOSE);
55+
}
56+
57+
58+
/**
59+
* "CLOSE ALL TABS"
2860
* This will close all tabs no matter whether they are in first pane or second pane
2961
*/
3062
function handleCloseAllTabs() {
3163
CommandManager.execute(Commands.FILE_CLOSE_ALL);
3264
}
3365

66+
3467
/**
35-
* Called when the close unmodified tabs option is selected from the context menu
68+
* "CLOSE UNMODIFIED TABS"
3669
* This will close all tabs that are not modified
3770
* TODO: implement the functionality
3871
*/
3972
function handleCloseUnmodifiedTabs() {
40-
4173
// pass
4274
}
4375

76+
4477
/**
45-
* Called when the reopen closed file option is selected from the context menu
78+
* "REOPEN CLOSED FILE"
4679
* This just calls the reopen closed file command. everthing else is handled there
80+
* TODO: disable the command if there are no closed files, look into the file menu
4781
*/
4882
function reopenClosedFile() {
4983
CommandManager.execute(Commands.FILE_REOPEN_CLOSED);
@@ -57,8 +91,9 @@ define(function (require, exports, module) {
5791
* @param {String} paneId - the id of the pane ["first-pane", "second-pane"]
5892
* @param {Number} x - the x coordinate for positioning the menu
5993
* @param {Number} y - the y coordinate for positioning the menu
94+
* @param {String} filePath - [optional] the path of the file that was right-clicked
6095
*/
61-
function showMoreOptionsContextMenu(paneId, x, y) {
96+
function showMoreOptionsContextMenu(paneId, x, y, filePath) {
6297
const dropdown = new DropdownButton.DropdownButton("", items);
6398

6499
// Append to document body for absolute positioning
@@ -76,13 +111,7 @@ define(function (require, exports, module) {
76111

77112
// handle the option selection
78113
dropdown.on("select", function (e, item, index) {
79-
if (index === 0) {
80-
handleCloseAllTabs();
81-
} else if (index === 1) {
82-
handleCloseUnmodifiedTabs();
83-
} else if (index === 2) {
84-
reopenClosedFile();
85-
}
114+
_handleSelection(index, filePath, paneId);
86115
});
87116

88117
// Remove the button after the dropdown is hidden
@@ -91,6 +120,38 @@ define(function (require, exports, module) {
91120
});
92121
}
93122

123+
/**
124+
* Handles the selection of an option in the more options context menu
125+
*
126+
* @param {Number} index - the index of the selected option
127+
* @param {String} filePath - the path of the file that was right-clicked
128+
* @param {String} paneId - the id of the pane ["first-pane", "second-pane"]
129+
*/
130+
function _handleSelection(index, filePath, paneId) {
131+
switch (index) {
132+
case 0:
133+
// Close tab (the one that was right-clicked)
134+
handleCloseTab(filePath, paneId);
135+
break;
136+
case 1:
137+
// Close active tab
138+
handleCloseActiveTab();
139+
break;
140+
case 2:
141+
// Close all tabs
142+
handleCloseAllTabs();
143+
break;
144+
case 3:
145+
// Close unmodified tabs
146+
handleCloseUnmodifiedTabs();
147+
break;
148+
case 5:
149+
// Reopen closed file
150+
reopenClosedFile();
151+
break;
152+
}
153+
}
154+
94155
module.exports = {
95156
showMoreOptionsContextMenu
96157
};

src/nls/root/strings.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,8 @@ define({
427427
"STATUSBAR_TASKS_RESTART": "Restart",
428428

429429
// Tab bar Strings
430+
"CLOSE_TAB": "Close Tab",
431+
"CLOSE_ACTIVE_TAB": "Close Active Tab",
430432
"CLOSE_ALL_TABS": "Close All Tabs",
431433
"CLOSE_UNMODIFIED_TABS": "Close Unmodified Tabs",
432434
"REOPEN_CLOSED_FILE": "Reopen Closed File",

0 commit comments

Comments
 (0)