Skip to content

Commit

Permalink
Switches close unchanged file to use TabGroup apis
Browse files Browse the repository at this point in the history
Avoids the silly looping that we used to need to do before the new apis
  • Loading branch information
eamodio committed Jul 18, 2022
1 parent dab32b5 commit d65cb16
Showing 1 changed file with 27 additions and 106 deletions.
133 changes: 27 additions & 106 deletions src/commands/closeUnchangedFiles.ts
@@ -1,12 +1,19 @@
import { TextEditor, Uri, window } from 'vscode';
import { TextEditorComparer, UriComparer } from '../comparers';
import { Commands, CoreCommands } from '../constants';
import {
TabInputCustom,
TabInputNotebook,
TabInputNotebookDiff,
TabInputText,
TabInputTextDiff,
Uri,
window,
} from 'vscode';
import { UriComparer } from '../comparers';
import { Commands } from '../constants';
import type { Container } from '../container';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { RepositoryPicker } from '../quickpicks/repositoryPicker';
import { command, executeCoreCommand } from '../system/command';
import { debounce } from '../system/function';
import { command } from '../system/command';
import { Command } from './base';

export interface CloseUnchangedFilesCommandArgs {
Expand All @@ -15,8 +22,6 @@ export interface CloseUnchangedFilesCommandArgs {

@command()
export class CloseUnchangedFilesCommand extends Command {
private _onEditorChangedFn: ((editor: TextEditor | undefined) => void) | undefined;

constructor(private readonly container: Container) {
super(Commands.CloseUnchangedFiles);
}
Expand All @@ -39,114 +44,30 @@ export class CloseUnchangedFilesCommand extends Command {
args.uris = status.files.map(f => f.uri);
}

if (args.uris.length === 0) {
void executeCoreCommand(CoreCommands.CloseAllEditors);

return;
}

const disposable = window.onDidChangeActiveTextEditor(
debounce((e: TextEditor | undefined) => this._onEditorChangedFn?.(e), 50),
);

let editor = window.activeTextEditor;
const hasNoChangedFiles = args.uris.length === 0;

let count = 0;
let loopCount = 0;
const editors: TextEditor[] = [];

// Find out how many editors there are
while (true) {
if (editor != null) {
let found = false;
for (const e of editors) {
if (TextEditorComparer.equals(e, editor, { usePosition: true })) {
found = true;
break;
}
}
if (found) break;

// Start counting at the first real editor
count++;
editors.push(editor);
} else if (count !== 0) {
count++;
}

editor = await this.nextEditor();

loopCount++;
// Break out if we've looped 4 times and haven't found any editors
if (loopCount >= 4 && editors.length === 0) break;
}

if (editors.length) {
editor = window.activeTextEditor;

for (let i = 0; i <= count; i++) {
for (const group of window.tabGroups.all) {
for (const tab of group.tabs) {
if (
editor == null ||
editor.document.isDirty ||
// eslint-disable-next-line no-loop-func
args.uris.some(uri => UriComparer.equals(uri, editor?.document.uri))
tab.input instanceof TabInputText ||
tab.input instanceof TabInputCustom ||
tab.input instanceof TabInputNotebook
) {
editor = await this.nextEditor();
} else {
editor = await this.closeEditor();
const inputUri = tab.input.uri;
if (hasNoChangedFiles || !args.uris.some(uri => UriComparer.equals(uri, inputUri))) {
void window.tabGroups.close(tab, true);
}
} else if (tab.input instanceof TabInputTextDiff || tab.input instanceof TabInputNotebookDiff) {
const inputUri = tab.input.modified;
if (hasNoChangedFiles || !args.uris.some(uri => UriComparer.equals(uri, inputUri))) {
void window.tabGroups.close(tab, true);
}
}
}
}

disposable.dispose();
} catch (ex) {
Logger.error(ex, 'CloseUnchangedFilesCommand');
void Messages.showGenericErrorMessage('Unable to close all unchanged files');
}
}

private async closeEditor(timeout: number = 500): Promise<TextEditor | undefined> {
const editor = window.activeTextEditor;

void (await executeCoreCommand(CoreCommands.CloseActiveEditor));

if (editor !== window.activeTextEditor) {
return window.activeTextEditor;
}

return this.waitForEditorChange(timeout);
}

private async nextEditor(timeout: number = 500): Promise<TextEditor | undefined> {
const editor = window.activeTextEditor;

void (await executeCoreCommand(CoreCommands.NextEditor));

if (editor !== window.activeTextEditor) {
return window.activeTextEditor;
}

return this.waitForEditorChange(timeout);
}

private waitForEditorChange(timeout: number = 500): Promise<TextEditor | undefined> {
return new Promise<TextEditor | undefined>(resolve => {
let timer: ReturnType<typeof setTimeout> | undefined;

this._onEditorChangedFn = (editor: TextEditor | undefined) => {
if (timer != null) {
clearTimeout(timer);
timer = undefined;

resolve(editor);
}
};

timer = setTimeout(() => {
timer = undefined;

resolve(window.activeTextEditor);
}, timeout);
});
}
}

0 comments on commit d65cb16

Please sign in to comment.