From e6c695260e08784c90e338a620f68f079e880d63 Mon Sep 17 00:00:00 2001 From: Pluto Date: Wed, 2 Apr 2025 19:05:52 +0530 Subject: [PATCH 1/3] feat: add support for closing tabs to right & left in context menu --- .../TabBar/more-options.js | 86 ++++++++++++++++++- src/nls/root/strings.js | 2 + 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/extensionsIntegrated/TabBar/more-options.js b/src/extensionsIntegrated/TabBar/more-options.js index 27e2ab0982..30bedfbcb2 100644 --- a/src/extensionsIntegrated/TabBar/more-options.js +++ b/src/extensionsIntegrated/TabBar/more-options.js @@ -37,6 +37,8 @@ define(function (require, exports, module) { const items = [ Strings.CLOSE_TAB, Strings.CLOSE_ACTIVE_TAB, + Strings.CLOSE_TABS_TO_THE_LEFT, + Strings.CLOSE_TABS_TO_THE_RIGHT, Strings.CLOSE_ALL_TABS, Strings.CLOSE_UNMODIFIED_TABS, "---", @@ -122,6 +124,78 @@ define(function (require, exports, module) { } } + /** + * "CLOSE TABS TO THE LEFT" + * This function is responsible for closing all tabs to the left of the right-clicked tab + * + * @param {String} filePath - path of the file that was right-clicked + * @param {String} paneId - the id of the pane in which the file is present + */ + function handleCloseTabsToTheLeft(filePath, paneId) { + if (!filePath) { + return; + } + + let workingSet; + workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet; + if (!workingSet) { + return; + } + + // find the index of the current file in the working set + const currentIndex = workingSet.findIndex(entry => entry.path === filePath); + + if (currentIndex > 0) { // we only proceed if there are tabs to the left + // get all files to the left of the current file + const filesToClose = workingSet.slice(0, currentIndex); + + // Close each file, starting from the rightmost [to avoid index shifts] + for (let i = filesToClose.length - 1; i >= 0; i--) { + const fileObj = FileSystem.getFileForPath(filesToClose[i].path); + CommandManager.execute( + Commands.FILE_CLOSE, + { file: fileObj, paneId: paneId } + ); + } + } + } + + + /** + * "CLOSE TABS TO THE RIGHT" + * This function is responsible for closing all tabs to the right of the right-clicked tab + * + * @param {String} filePath - path of the file that was right-clicked + * @param {String} paneId - the id of the pane in which the file is present + */ + function handleCloseTabsToTheRight(filePath, paneId) { + if (!filePath) { + return; + } + + let workingSet; + workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet; + if (!workingSet) { + return; + } + + // get the index of the current file in the working set + const currentIndex = workingSet.findIndex(entry => entry.path === filePath); + // only proceed if there are tabs to the right + if (currentIndex !== -1 && currentIndex < workingSet.length - 1) { + // get all files to the right of the current file + const filesToClose = workingSet.slice(currentIndex + 1); + + for (let i = filesToClose.length - 1; i >= 0; i--) { + const fileObj = FileSystem.getFileForPath(filesToClose[i].path); + CommandManager.execute( + Commands.FILE_CLOSE, + { file: fileObj, paneId: paneId } + ); + } + } + } + /** * "REOPEN CLOSED FILE" @@ -187,14 +261,22 @@ define(function (require, exports, module) { handleCloseActiveTab(); break; case 2: + // Close tabs to the left + handleCloseTabsToTheLeft(filePath, paneId); + break; + case 3: + // Close tabs to the right + handleCloseTabsToTheRight(filePath, paneId); + break; + case 4: // Close all tabs handleCloseAllTabs(); break; - case 3: + case 5: // Close unmodified tabs handleCloseUnmodifiedTabs(); break; - case 5: + case 6: // Reopen closed file reopenClosedFile(); break; diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index cd3f9855ce..d19d139240 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -429,6 +429,8 @@ define({ // Tab bar Strings "CLOSE_TAB": "Close Tab", "CLOSE_ACTIVE_TAB": "Close Active Tab", + "CLOSE_TABS_TO_THE_RIGHT": "Close Tabs to the Right", + "CLOSE_TABS_TO_THE_LEFT": "Close Tabs to the Left", "CLOSE_ALL_TABS": "Close All Tabs", "CLOSE_UNMODIFIED_TABS": "Close Unmodified Tabs", "REOPEN_CLOSED_FILE": "Reopen Closed File", From 23bde667bd5c9846e95925106c09b8f6ccbda623 Mon Sep 17 00:00:00 2001 From: Pluto Date: Wed, 2 Apr 2025 19:25:31 +0530 Subject: [PATCH 2/3] fix: close all tabs and close unmodified tabs now only close for the specified pane --- .../TabBar/more-options.js | 128 ++++++++++-------- 1 file changed, 71 insertions(+), 57 deletions(-) diff --git a/src/extensionsIntegrated/TabBar/more-options.js b/src/extensionsIntegrated/TabBar/more-options.js index 30bedfbcb2..5495c700e9 100644 --- a/src/extensionsIntegrated/TabBar/more-options.js +++ b/src/extensionsIntegrated/TabBar/more-options.js @@ -81,49 +81,63 @@ define(function (require, exports, module) { /** * "CLOSE ALL TABS" - * This will close all tabs no matter whether they are in first pane or second pane + * This will close all tabs in the specified pane + * + * @param {String} paneId - the id of the pane ["first-pane", "second-pane"] */ - function handleCloseAllTabs() { - CommandManager.execute(Commands.FILE_CLOSE_ALL); + function handleCloseAllTabs(paneId) { + if (!paneId) { + return; + } + + let workingSet; + workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet; + if (!workingSet || workingSet.length === 0) { + return; + } + + // close each file in the pane, start from the rightmost [to avoid index shifts] + for (let i = workingSet.length - 1; i >= 0; i--) { + const fileObj = FileSystem.getFileForPath(workingSet[i].path); + CommandManager.execute( + Commands.FILE_CLOSE, + { file: fileObj, paneId: paneId } + ); + } } /** * "CLOSE UNMODIFIED TABS" - * This will close all tabs that are not modified + * This will close all tabs that are not modified in the specified pane + * + * @param {String} paneId - the id of the pane ["first-pane", "second-pane"] */ - function handleCloseUnmodifiedTabs() { - const paneList = MainViewManager.getPaneIdList(); - - // for the first pane - if (paneList.length > 0 && Global.firstPaneWorkingSet.length > 0) { - // get all those entries that are not dirty - const unmodifiedEntries = Global.firstPaneWorkingSet.filter(entry => !entry.isDirty); + function handleCloseUnmodifiedTabs(paneId) { + if (!paneId) { + return; + } - // close each unmodified file in the first pane - unmodifiedEntries.forEach(entry => { - const fileObj = FileSystem.getFileForPath(entry.path); - CommandManager.execute( - Commands.FILE_CLOSE, - { file: fileObj, paneId: "first-pane" } - ); - }); + let workingSet; + workingSet = paneId === "first-pane" ? Global.firstPaneWorkingSet : Global.secondPaneWorkingSet; + if (!workingSet || workingSet.length === 0) { + return; } - // for second pane - if (paneList.length > 1 && Global.secondPaneWorkingSet.length > 0) { - const unmodifiedEntries = Global.secondPaneWorkingSet.filter(entry => !entry.isDirty); + // get all those entries that are not dirty + const unmodifiedEntries = workingSet.filter(entry => !entry.isDirty); - unmodifiedEntries.forEach(entry => { - const fileObj = FileSystem.getFileForPath(entry.path); - CommandManager.execute( - Commands.FILE_CLOSE, - { file: fileObj, paneId: "second-pane" } - ); - }); + // close each unmodified file in the pane + for (let i = unmodifiedEntries.length - 1; i >= 0; i--) { + const fileObj = FileSystem.getFileForPath(unmodifiedEntries[i].path); + CommandManager.execute( + Commands.FILE_CLOSE, + { file: fileObj, paneId: paneId } + ); } } + /** * "CLOSE TABS TO THE LEFT" * This function is responsible for closing all tabs to the left of the right-clicked tab @@ -252,34 +266,34 @@ define(function (require, exports, module) { */ function _handleSelection(index, filePath, paneId) { switch (index) { - case 0: - // Close tab (the one that was right-clicked) - handleCloseTab(filePath, paneId); - break; - case 1: - // Close active tab - handleCloseActiveTab(); - break; - case 2: - // Close tabs to the left - handleCloseTabsToTheLeft(filePath, paneId); - break; - case 3: - // Close tabs to the right - handleCloseTabsToTheRight(filePath, paneId); - break; - case 4: - // Close all tabs - handleCloseAllTabs(); - break; - case 5: - // Close unmodified tabs - handleCloseUnmodifiedTabs(); - break; - case 6: - // Reopen closed file - reopenClosedFile(); - break; + case 0: + // Close tab (the one that was right-clicked) + handleCloseTab(filePath, paneId); + break; + case 1: + // Close active tab + handleCloseActiveTab(); + break; + case 2: + // Close tabs to the left + handleCloseTabsToTheLeft(filePath, paneId); + break; + case 3: + // Close tabs to the right + handleCloseTabsToTheRight(filePath, paneId); + break; + case 4: + // Close all tabs + handleCloseAllTabs(paneId); + break; + case 5: + // Close unmodified tabs + handleCloseUnmodifiedTabs(paneId); + break; + case 6: + // Reopen closed file + reopenClosedFile(); + break; } } From a44274add5424c52c0da75d2e91af96a143f3565 Mon Sep 17 00:00:00 2001 From: Pluto Date: Wed, 2 Apr 2025 19:43:49 +0530 Subject: [PATCH 3/3] fix: scroll to active tab not working for image files --- src/extensionsIntegrated/TabBar/overflow.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/extensionsIntegrated/TabBar/overflow.js b/src/extensionsIntegrated/TabBar/overflow.js index d12fe1a7bf..317989e877 100644 --- a/src/extensionsIntegrated/TabBar/overflow.js +++ b/src/extensionsIntegrated/TabBar/overflow.js @@ -254,13 +254,23 @@ define(function (require, exports, module) { return; } - // make sure there is an active editor + let activePath; + + // get the active file const activeEditor = EditorManager.getActiveEditor(); - if (!activeEditor || !activeEditor.document || !activeEditor.document.file) { - return; + if (activeEditor && activeEditor.document && activeEditor.document.file) { + activePath = activeEditor.document.file.fullPath; + } else { + // If there is no active editor, we need to check if its an image file + const currentFile = MainViewManager.getCurrentlyViewedFile(); + if (currentFile) { + activePath = currentFile.fullPath; + } else { + // if not an image file, not a text file, we don't need to scroll + return; + } } - const activePath = activeEditor.document.file.fullPath; // get the active tab. the active tab is the tab that is currently open const $activeTab = $tabBarElement.find(`.tab[data-path="${activePath}"]`);