Skip to content

Instantly share code, notes, and snippets.

@savetheclocktower
Created February 28, 2022 18:00
Show Gist options
  • Save savetheclocktower/110173b70269bf476d512567d460c27b to your computer and use it in GitHub Desktop.
Save savetheclocktower/110173b70269bf476d512567d460c27b to your computer and use it in GitHub Desktop.
Automatically close empty “Staged/Unchaged Changes” tabs in Atom
// Close "Staged/Unstaged Changes" tabs when they become empty.
const EmptyMonitor = {
metaForElement: new Map(),
observerOptions: {
childList: false,
attributes: true,
subtree: false,
attributeFilter: ['class']
},
checkAll (panes) {
for (let pane of panes) {
let items = pane.getItems();
for (let item of items) {
if (!this.isFilePatchView(item)) { continue; }
let element = this.getElementForItem(item);
if (!element) { return; }
if (!this.isEmpty(item)) { return; }
this.forget(item, element);
pane.destroyItem(item);
}
}
},
getElementForItem (item) {
let element;
try {
element = item.getElement().querySelector('.github-FilePatchView');
} catch (err) {
console.error(err);
return null;
}
return element || null;
},
isFilePatchView (item) {
if (!('getURI' in item)) { return false; }
let uri = item.getURI();
if (!uri || typeof uri !== 'string') { return false; }
return uri.startsWith('atom-github://file-patch/');
},
isEmpty (item, element = null) {
if (!element) { element = this.getElementForItem(item); }
return element.classList.contains('github-FilePatchView--blank');
},
remember (item, pane, element = null) {
if (!element) { element = this.getElementForItem(item); }
if (!element) { return; }
return this.metaForElement.set(element, { item, pane });
},
forget (item, element = null) {
if (!element) { element = this.getElementForItem(item); }
if (!element) { return; }
return this.metaForElement.delete(element);
},
checkForEmpty (item, element = null) {
if (!element) { element = this.getElementForItem(item); }
if (!this.isEmpty(item, element)) { return; }
if (!this.metaForElement.has(element)) { return; }
let { pane } = this.metaForElement.get(element);
this.forget(item, element);
pane.destroyItem(item);
},
setup () {
this._observer = new MutationObserver(
mutations => {
let panes = new Set();
for (let mutation of mutations) {
let bundle = this.metaForElement.get(mutation.target);
if (!bundle) { continue; }
panes.add(bundle.pane);
}
setTimeout(this.checkAll.bind(this, panes), 50);
}
);
},
closeOnEmpty (item, pane, retry = true) {
if (!this._observer) { this.setup(); }
let element = this.getElementForItem(item);
if (!element && retry) {
setTimeout(() => this.closeOnEmpty(item, pane, false), 100);
return;
}
this.remember(item, pane, element);
this._observer.observe(element, this.observerOptions);
setTimeout(() => this.checkForEmpty(item, element), 50);
},
observeIfFilePatchView (item, pane) {
if (!this.isFilePatchView(item)) { return; }
setTimeout(() => this.closeOnEmpty(item, pane), 100);
}
};
atom.workspace.observePanes(
pane => {
pane.onDidAddItem(({ item }) => {
EmptyMonitor.observeIfFilePatchView(item, pane);
});
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment