mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Refresh master with initial release/0.24 snapshot (#332)
* Initial port of release/0.24 source code * Fix additional headers * Fix a typo in launch.json
This commit is contained in:
173
extensions/git/src/decorationProvider.ts
Normal file
173
extensions/git/src/decorationProvider.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
|
||||
import { Repository, GitResourceGroup } from './repository';
|
||||
import { Model } from './model';
|
||||
import { debounce } from './decorators';
|
||||
import { filterEvent } from './util';
|
||||
|
||||
class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
|
||||
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
|
||||
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
|
||||
|
||||
private checkIgnoreQueue = new Map<string, { resolve: (status: boolean) => void, reject: (err: any) => void }>();
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(private repository: Repository) {
|
||||
this.disposables.push(
|
||||
window.registerDecorationProvider(this),
|
||||
filterEvent(workspace.onDidSaveTextDocument, e => e.fileName.endsWith('.gitignore'))(_ => this._onDidChangeDecorations.fire())
|
||||
//todo@joh -> events when the ignore status actually changes, not only when the file changes
|
||||
);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
this.checkIgnoreQueue.clear();
|
||||
}
|
||||
|
||||
provideDecoration(uri: Uri): Promise<DecorationData | undefined> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
this.checkIgnoreQueue.set(uri.fsPath, { resolve, reject });
|
||||
this.checkIgnoreSoon();
|
||||
}).then(ignored => {
|
||||
if (ignored) {
|
||||
return <DecorationData>{
|
||||
priority: 3,
|
||||
color: new ThemeColor('gitDecoration.ignoredResourceForeground')
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@debounce(500)
|
||||
private checkIgnoreSoon(): void {
|
||||
const queue = new Map(this.checkIgnoreQueue.entries());
|
||||
this.checkIgnoreQueue.clear();
|
||||
this.repository.checkIgnore([...queue.keys()]).then(ignoreSet => {
|
||||
for (const [key, value] of queue.entries()) {
|
||||
value.resolve(ignoreSet.has(key));
|
||||
}
|
||||
}, err => {
|
||||
console.error(err);
|
||||
for (const [, value] of queue.entries()) {
|
||||
value.reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class GitDecorationProvider implements DecorationProvider {
|
||||
|
||||
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
|
||||
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
private decorations = new Map<string, DecorationData>();
|
||||
|
||||
constructor(private repository: Repository) {
|
||||
this.disposables.push(
|
||||
window.registerDecorationProvider(this),
|
||||
repository.onDidRunOperation(this.onDidRunOperation, this)
|
||||
);
|
||||
}
|
||||
|
||||
private onDidRunOperation(): void {
|
||||
let newDecorations = new Map<string, DecorationData>();
|
||||
this.collectDecorationData(this.repository.indexGroup, newDecorations);
|
||||
this.collectDecorationData(this.repository.workingTreeGroup, newDecorations);
|
||||
this.collectDecorationData(this.repository.mergeGroup, newDecorations);
|
||||
|
||||
let uris: Uri[] = [];
|
||||
newDecorations.forEach((value, uriString) => {
|
||||
if (this.decorations.has(uriString)) {
|
||||
this.decorations.delete(uriString);
|
||||
} else {
|
||||
uris.push(Uri.parse(uriString));
|
||||
}
|
||||
});
|
||||
this.decorations.forEach((value, uriString) => {
|
||||
uris.push(Uri.parse(uriString));
|
||||
});
|
||||
this.decorations = newDecorations;
|
||||
this._onDidChangeDecorations.fire(uris);
|
||||
}
|
||||
|
||||
private collectDecorationData(group: GitResourceGroup, bucket: Map<string, DecorationData>): void {
|
||||
group.resourceStates.forEach(r => {
|
||||
if (r.resourceDecoration) {
|
||||
bucket.set(r.original.toString(), r.resourceDecoration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
provideDecoration(uri: Uri): DecorationData | undefined {
|
||||
return this.decorations.get(uri.toString());
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class GitDecorations {
|
||||
|
||||
private configListener: Disposable;
|
||||
private modelListener: Disposable[] = [];
|
||||
private providers = new Map<Repository, Disposable>();
|
||||
|
||||
constructor(private model: Model) {
|
||||
this.configListener = workspace.onDidChangeConfiguration(e => e.affectsConfiguration('git.decorations.enabled') && this.update());
|
||||
this.update();
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
const enabled = workspace.getConfiguration('git').get('decorations.enabled');
|
||||
if (enabled) {
|
||||
this.enable();
|
||||
} else {
|
||||
this.disable();
|
||||
}
|
||||
}
|
||||
|
||||
private enable(): void {
|
||||
this.modelListener = [];
|
||||
this.model.onDidOpenRepository(this.onDidOpenRepository, this, this.modelListener);
|
||||
this.model.onDidCloseRepository(this.onDidCloseRepository, this, this.modelListener);
|
||||
this.model.repositories.forEach(this.onDidOpenRepository, this);
|
||||
}
|
||||
|
||||
private disable(): void {
|
||||
this.modelListener.forEach(d => d.dispose());
|
||||
this.providers.forEach(value => value.dispose());
|
||||
this.providers.clear();
|
||||
}
|
||||
|
||||
private onDidOpenRepository(repository: Repository): void {
|
||||
const provider = new GitDecorationProvider(repository);
|
||||
const ignoreProvider = new GitIgnoreDecorationProvider(repository);
|
||||
this.providers.set(repository, Disposable.from(provider, ignoreProvider));
|
||||
}
|
||||
|
||||
private onDidCloseRepository(repository: Repository): void {
|
||||
const provider = this.providers.get(repository);
|
||||
if (provider) {
|
||||
provider.dispose();
|
||||
this.providers.delete(repository);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.configListener.dispose();
|
||||
this.modelListener.forEach(d => d.dispose());
|
||||
this.providers.forEach(value => value.dispose);
|
||||
this.providers.clear();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user