mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-19 01:35:37 -05:00
Fixes #83 - Close Unchanged Files command can infinitely loop
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
|
||||
'use strict';
|
||||
import { Functions } from './system';
|
||||
import { commands, Disposable, TextEditor, window } from 'vscode';
|
||||
import { BuiltInCommands } from './constants';
|
||||
|
||||
@@ -11,19 +12,20 @@ export class ActiveEditorTracker extends Disposable {
|
||||
constructor() {
|
||||
super(() => this.dispose());
|
||||
|
||||
this._disposable = window.onDidChangeActiveTextEditor(e => this._resolver && this._resolver(e));
|
||||
const fn = Functions.debounce((e: TextEditor) => this._resolver && this._resolver(e), 50);
|
||||
this._disposable = window.onDidChangeActiveTextEditor(fn);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposable && this._disposable.dispose();
|
||||
}
|
||||
|
||||
async awaitClose(timeout: number = 500): Promise<TextEditor> {
|
||||
async awaitClose(timeout: number = 500): Promise<TextEditor | undefined> {
|
||||
this.close();
|
||||
return this.wait(timeout);
|
||||
}
|
||||
|
||||
async awaitNext(timeout: number = 500): Promise<TextEditor> {
|
||||
async awaitNext(timeout: number = 500): Promise<TextEditor | undefined> {
|
||||
this.next();
|
||||
return this.wait(timeout);
|
||||
}
|
||||
@@ -36,15 +38,15 @@ export class ActiveEditorTracker extends Disposable {
|
||||
return commands.executeCommand(BuiltInCommands.NextEditor);
|
||||
}
|
||||
|
||||
async wait(timeout: number = 500): Promise<TextEditor> {
|
||||
async wait(timeout: number = 500): Promise<TextEditor | undefined> {
|
||||
const editor = await new Promise<TextEditor>((resolve, reject) => {
|
||||
let timer: any;
|
||||
|
||||
this._resolver = (editor: TextEditor) => {
|
||||
this._resolver = (e: TextEditor) => {
|
||||
if (timer) {
|
||||
clearTimeout(timer as any);
|
||||
timer = 0;
|
||||
resolve(editor);
|
||||
resolve(e);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,6 +55,7 @@ export class ActiveEditorTracker extends Disposable {
|
||||
timer = 0;
|
||||
}, timeout) as any;
|
||||
});
|
||||
|
||||
this._resolver = undefined;
|
||||
return editor;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
import { TextEditor, Uri, window } from 'vscode';
|
||||
import { commands, TextEditor, Uri, window } from 'vscode';
|
||||
import { ActiveEditorTracker } from '../activeEditorTracker';
|
||||
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
||||
import { TextEditorComparer, UriComparer } from '../comparers';
|
||||
import { BuiltInCommands } from '../constants';
|
||||
import { GitService } from '../gitService';
|
||||
import { Logger } from '../logger';
|
||||
|
||||
@@ -30,34 +31,41 @@ export class CloseUnchangedFilesCommand extends ActiveEditorCommand {
|
||||
args.uris = status.files.map(_ => _.Uri);
|
||||
}
|
||||
|
||||
if (args.uris.length === 0) return commands.executeCommand(BuiltInCommands.CloseAllEditors);
|
||||
|
||||
const editorTracker = new ActiveEditorTracker();
|
||||
|
||||
let active = window.activeTextEditor;
|
||||
let editor = active;
|
||||
do {
|
||||
let count = 0;
|
||||
let previous = undefined;
|
||||
let editor = window.activeTextEditor;
|
||||
while (true) {
|
||||
if (editor !== undefined) {
|
||||
if ((editor.document !== undefined && editor.document.isDirty) ||
|
||||
args.uris.some(_ => UriComparer.equals(_, editor!.document && editor!.document.uri))) {
|
||||
// If we didn't start with a valid editor, set one once we find it
|
||||
if (active === undefined) {
|
||||
active = editor;
|
||||
}
|
||||
editor = await editorTracker.awaitNext(500);
|
||||
if (TextEditorComparer.equals(previous, editor, { useId: true, usePosition: true })) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (active === editor) {
|
||||
active = undefined;
|
||||
}
|
||||
editor = await editorTracker.awaitClose(500);
|
||||
|
||||
if (editor.document !== undefined &&
|
||||
(editor.document.isDirty || args.uris.some(_ => UriComparer.equals(_, editor!.document && editor!.document.uri)))) {
|
||||
previous = editor;
|
||||
editor = await editorTracker.awaitNext(500);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
previous = editor;
|
||||
editor = await editorTracker.awaitClose(500);
|
||||
|
||||
if (previous === undefined && editor === undefined) {
|
||||
count++;
|
||||
// This is such a shitty hack, but I can't figure out any other reliable way to know that we've cycled through all the editors :(
|
||||
if (count >= 4) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (active === editor) {
|
||||
active = undefined;
|
||||
}
|
||||
editor = await editorTracker.awaitClose(500);
|
||||
count = 0;
|
||||
}
|
||||
} while ((active === undefined && editor === undefined) || !TextEditorComparer.equals(active, editor, { useId: true, usePosition: true }));
|
||||
}
|
||||
|
||||
editorTracker.dispose();
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@ export const QualifiedExtensionId = `eamodio.${ExtensionId}`;
|
||||
|
||||
export const ApplicationInsightsKey = 'a9c302f8-6483-4d01-b92c-c159c799c679';
|
||||
|
||||
export type BuiltInCommands = 'cursorMove' | 'editor.action.showReferences' | 'editor.action.toggleRenderWhitespace' | 'editorScroll' | 'revealLine' | 'setContext' | 'vscode.diff' | 'vscode.executeDocumentSymbolProvider' | 'vscode.executeCodeLensProvider' | 'vscode.open' | 'vscode.previewHtml' | 'workbench.action.closeActiveEditor' | 'workbench.action.nextEditor';
|
||||
export type BuiltInCommands = 'cursorMove' | 'editor.action.showReferences' | 'editor.action.toggleRenderWhitespace' | 'editorScroll' | 'revealLine' | 'setContext' | 'vscode.diff' | 'vscode.executeDocumentSymbolProvider' | 'vscode.executeCodeLensProvider' | 'vscode.open' | 'vscode.previewHtml' | 'workbench.action.closeActiveEditor' | 'workbench.action.closeAllEditors' | 'workbench.action.nextEditor';
|
||||
export const BuiltInCommands = {
|
||||
CloseActiveEditor: 'workbench.action.closeActiveEditor' as BuiltInCommands,
|
||||
CloseAllEditors: 'workbench.action.closeAllEditors' as BuiltInCommands,
|
||||
CursorMove: 'cursorMove' as BuiltInCommands,
|
||||
Diff: 'vscode.diff' as BuiltInCommands,
|
||||
EditorScroll: 'editorScroll' as BuiltInCommands,
|
||||
|
||||
Reference in New Issue
Block a user