Skip to content

Commit f379975

Browse files
committed
feat: add close button in tabs to remove the tab
1 parent 4b31e63 commit f379975

File tree

2 files changed

+86
-6
lines changed

2 files changed

+86
-6
lines changed

src/extensionsIntegrated/TabBar/main.js

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ define(function (require, exports, module) {
101101
// Create the tab element with the structure we need
102102
// tab name is written as a separate div because it may include directory info which we style differently
103103
const $tab = $(
104-
`<div class="tab ${isActive ? 'active' : ''}
105-
${isDirty ? 'dirty' : ''}"
104+
`<div class="tab ${isActive ? 'active' : ''}"
106105
data-path="${entry.path}"
107106
title="${entry.path}">
108107
<div class="tab-icon"></div>
109108
<div class="tab-name"></div>
109+
<div class="tab-close"><i class="fa-solid fa-xmark"></i></div>
110110
</div>`);
111111

112112
// Add the file icon
@@ -211,14 +211,66 @@ define(function (require, exports, module) {
211211

212212

213213
/**
214-
* handle click events on the tabs to open the file
214+
* Handle close button click on tabs
215+
* This function will remove the file from the working set
216+
*
217+
* @param {String} filePath - path of the file to close
218+
*/
219+
function handleTabClose(filePath) {
220+
// Logic: First open the file we want to close, then close it and finally restore focus
221+
// Why? Because FILE_CLOSE removes the currently active file from the working set
222+
223+
// Get the current active editor to restore focus later
224+
const currentActiveEditor = EditorManager.getActiveEditor();
225+
const currentActivePath = currentActiveEditor ? currentActiveEditor.document.file.fullPath : null;
226+
227+
// Only need to open the file first if it's not the currently active one
228+
if (currentActivePath !== filePath) {
229+
// open the file we want to close
230+
CommandManager.execute(Commands.FILE_OPEN, { fullPath: filePath })
231+
.done(function () {
232+
// close it
233+
CommandManager.execute(Commands.FILE_CLOSE)
234+
.done(function () {
235+
// If we had a different file active before, restore focus to it
236+
if (currentActivePath && currentActivePath !== filePath) {
237+
CommandManager.execute(Commands.FILE_OPEN, { fullPath: currentActivePath });
238+
}
239+
})
240+
.fail(function (error) {
241+
console.error("Failed to close file:", filePath, error);
242+
});
243+
})
244+
.fail(function (error) {
245+
console.error("Failed to open file for closing:", filePath, error);
246+
});
247+
} else {
248+
// if it's already the active file, just close it
249+
CommandManager.execute(Commands.FILE_CLOSE)
250+
.fail(function (error) {
251+
console.error("Failed to close file:", filePath, error);
252+
});
253+
}
254+
}
255+
256+
257+
/**
258+
* handle click events on the tabs to open the file or close the tab
215259
*/
216260
function handleTabClick() {
217261

218262
// delegate event handling for both tab bars
219263
$(document).on("click", ".tab", function (event) {
220-
// Skip if this is a click on a close button or other control
221-
if ($(event.target).hasClass('tab-close') || $(event.target).closest('.tab-close').length) {
264+
// check if the clicked element is the close button
265+
if ($(event.target).hasClass('fa-xmark') || $(event.target).closest('.tab-close').length) {
266+
// Get the file path from the data-path attribute of the parent tab
267+
const filePath = $(this).attr("data-path");
268+
if (filePath) {
269+
handleTabClose(filePath);
270+
// Prevent default behavior
271+
event.preventDefault();
272+
event.stopPropagation();
273+
}
222274
return;
223275
}
224276

@@ -297,3 +349,6 @@ define(function (require, exports, module) {
297349
handleTabClick();
298350
});
299351
});
352+
353+
354+
// TODO: Bug (when we have two panes and one pane gets empty by closing all files in it, the other pane tab bar also gets removed)

src/styles/Extn-TabBar.less

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
.tab {
2222
display: inline-flex;
2323
align-items: center;
24-
padding: 0 12px;
24+
padding: 0 8px;
2525
padding-top: 1px;
2626
height: 100%;
2727
background-color: #2D2D2D;
@@ -83,4 +83,29 @@
8383

8484
.tab.dirty .tab-icon {
8585
margin-left: 10px;
86+
}
87+
88+
.tab-close {
89+
font-size: 12px;
90+
font-weight: lighter;
91+
padding: 1px 4px 0.4px 4px;
92+
margin-left: 3px;
93+
color: #808080;
94+
transition: all 0.2s ease;
95+
border-radius: 3px;
96+
visibility: hidden;
97+
opacity: 0;
98+
pointer-events: none;
99+
}
100+
101+
.tab:hover .tab-close,
102+
.tab.active .tab-close {
103+
visibility: visible;
104+
opacity: 1;
105+
pointer-events: auto;
106+
}
107+
108+
.tab-close:hover {
109+
color: #CCCCCC;
110+
background-color: rgba(255, 255, 255, 0.1);
86111
}

0 commit comments

Comments
 (0)