提交 d5880b1a 编写于 作者: J Johannes Rieken

deco - decorate ignored files

上级 68797abd
......@@ -8,6 +8,57 @@
import { window, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider } from 'vscode';
import { Repository, GitResourceGroup } from './repository';
import { Model } from './model';
import { debounce } from './decorators';
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, '.gitignore')
//todo@joh -> events when the ignore status actually changes, not 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,
opacity: 0.75
};
}
});
}
@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 => {
for (const [, value] of queue.entries()) {
value.reject(err);
}
});
}
}
class GitDecorationProvider implements DecorationProvider {
......@@ -65,7 +116,7 @@ class GitDecorationProvider implements DecorationProvider {
export class GitDecorations {
private disposables: Disposable[] = [];
private providers = new Map<Repository, GitDecorationProvider>();
private providers = new Map<Repository, Disposable>();
constructor(private model: Model) {
this.disposables.push(
......@@ -77,7 +128,8 @@ export class GitDecorations {
private onDidOpenRepository(repository: Repository): void {
const provider = new GitDecorationProvider(repository);
this.providers.set(repository, provider);
const ignoreProvider = new GitIgnoreDecorationProvider(repository);
this.providers.set(repository, Disposable.from(provider, ignoreProvider));
}
private onDidCloseRepository(repository: Repository): void {
......
......@@ -646,6 +646,42 @@ export class Repository implements Disposable {
});
}
checkIgnore(filePaths: string[]): Promise<Set<string>> {
return this.run(Operation.Ignore, () => {
return new Promise<Set<string>>((resolve, reject) => {
const child = this.repository.stream(['check-ignore', ...filePaths]);
const onExit = exitCode => {
if (exitCode === 1) {
// nothing ignored
resolve(new Set<string>());
} else if (exitCode === 0) {
// each line is something ignored
resolve(new Set<string>(data.split('\n')));
} else {
reject();
}
};
let data = '';
const onStdoutData = (raw: string) => {
data += raw;
};
child.stdout.setEncoding('utf8');
child.stdout.on('data', onStdoutData);
// const stderrData: string[] = [];
// child.stderr.setEncoding('utf8');
// child.stderr.on('data', raw => stderrData.push(raw as string));
child.on('error', reject);
child.on('exit', onExit);
});
});
}
private async run<T>(operation: Operation, runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> {
if (this.state !== RepositoryState.Idle) {
throw new Error('Repository not initialized');
......
......@@ -249,15 +249,16 @@ class DecorationProviderWrapper {
return;
}
if (item === undefined && !includeChildren) {
// unknown, a leaf node -> trigger request
if (item === undefined) {
// unknown -> trigger request
item = this._fetchData(uri);
}
if (item) {
// leaf node
// found something
callback(item, false);
}
if (includeChildren) {
// (resolved) children
const childTree = this.data.findSuperstr(key);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册