提交 73ee03ed 编写于 作者: J Johannes Rieken

remote - sketch up find in files logic

上级 44d1ccf8
......@@ -83,6 +83,12 @@ declare module 'vscode' {
type: FileType;
}
export interface FindMatch {
uri: Uri;
range: Range;
preview: { leading: string, matching: string, trailing: string };
}
// todo@joh discover files etc
// todo@joh CancellationToken everywhere
export interface FileSystemProvider {
......@@ -131,6 +137,7 @@ declare module 'vscode' {
// find files by names
findFiles?(query: string, progress: Progress<Uri>, token: CancellationToken): Thenable<void>;
findInFiles?(query: string, isRegex: boolean, progress: Progress<FindMatch>, token: CancellationToken): Thenable<void>;
}
export namespace workspace {
......
......@@ -12,9 +12,10 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
import { IProgress } from 'vs/platform/progress/common/progress';
import { ISearchResultProvider, ISearchQuery, ISearchComplete, ISearchProgressItem, QueryType, IFileMatch, ISearchService } from 'vs/platform/search/common/search';
import { ISearchResultProvider, ISearchQuery, ISearchComplete, ISearchProgressItem, QueryType, IFileMatch, ISearchService, ILineMatch } from 'vs/platform/search/common/search';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { onUnexpectedError } from 'vs/base/common/errors';
import { values } from 'vs/base/common/map';
@extHostNamedCustomer(MainContext.MainThreadFileSystem)
export class MainThreadFileSystem implements MainThreadFileSystemShape {
......@@ -59,8 +60,8 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
// --- search
$handleDidFindFile(handle: number, session: number, data: UriComponents): void {
this._provider.get(handle).hanelDidFindFile(session, URI.revive(data));
$handleFindMatch(handle: number, session, data: UriComponents | [UriComponents, ILineMatch]): void {
this._provider.get(handle).handleFindMatch(session, data);
}
}
......@@ -76,11 +77,25 @@ class FileReadOperation {
}
}
class SearchOperation {
private static _idPool = 0;
constructor(
readonly progress: (match: IFileMatch) => any,
readonly id: number = ++SearchOperation._idPool,
readonly matches = new Map<string, IFileMatch>()
) {
//
}
}
class RemoteFileSystemProvider implements IFileSystemProvider, ISearchResultProvider {
private readonly _onDidChange = new Emitter<IFileChange[]>();
private readonly _reads = new Map<number, FileReadOperation>();
private readonly _registrations: IDisposable[];
private readonly _reads = new Map<number, FileReadOperation>();
private readonly _searches = new Map<number, SearchOperation>();
readonly onDidChange: Event<IFileChange[]> = this._onDidChange.event;
......@@ -149,38 +164,44 @@ class RemoteFileSystemProvider implements IFileSystemProvider, ISearchResultProv
// --- search
private _searches = new Map<number, (resource: URI) => void>();
private _searchesIdPool = 0;
search(query: ISearchQuery): PPromise<ISearchComplete, ISearchProgressItem> {
if (query.type === QueryType.Text) {
return PPromise.as<ISearchComplete>({ results: [], stats: undefined });
} else {
return this._findFiles(query);
}
}
private _findFiles(query: ISearchQuery): PPromise<ISearchComplete, ISearchProgressItem> {
const id = ++this._searchesIdPool;
const matches: IFileMatch[] = [];
return new PPromise((resolve, reject, report) => {
this._proxy.$findFiles(this._handle, id, query.filePattern).then(() => {
this._searches.delete(id);
resolve({
results: matches,
stats: undefined
});
}, reject);
this._searches.set(id, resource => {
const match: IFileMatch = { resource };
matches.push(match);
report(match);
const search = new SearchOperation(report);
this._searches.set(search.id, search);
const promise = query.type === QueryType.File
? this._proxy.$findFiles(this._handle, search.id, query.filePattern)
: this._proxy.$findInFiles(this._handle, search.id, query.contentPattern);
promise.then(() => {
this._searches.delete(search.id);
resolve(({ results: values(search.matches), stats: undefined }));
}, err => {
this._searches.delete(search.id);
reject(err);
});
});
}
hanelDidFindFile(session: number, resource: URI): void {
this._searches.get(session)(resource);
handleFindMatch(session: number, dataOrUri: UriComponents | [UriComponents, ILineMatch]): void {
let resource: URI;
let match: ILineMatch;
if (Array.isArray(dataOrUri)) {
resource = URI.revive(dataOrUri[0]);
match = dataOrUri[1];
} else {
resource = URI.revive(dataOrUri);
}
const { matches } = this._searches.get(session);
if (!matches.has(resource.toString())) {
matches.set(resource.toString(), { resource, lineMatches: [] });
}
if (match) {
matches.get(resource.toString()).lineMatches.push(match);
}
}
}
......@@ -53,6 +53,7 @@ import { ConfigurationScope } from 'vs/platform/configuration/common/configurati
import { ParsedArgs } from 'vs/platform/environment/common/environment';
import { CommentRule, CharacterPair, EnterAction } from 'vs/editor/common/modes/languageConfiguration';
import { EndOfLineSequence, ISingleEditOperation } from 'vs/editor/common/model';
import { ILineMatch, IPatternInfo } from 'vs/platform/search/common/search';
export interface IEnvironment {
isExtensionDevelopmentDebug: boolean;
......@@ -373,7 +374,7 @@ export interface MainThreadFileSystemShape extends IDisposable {
$onFileSystemChange(handle: number, resource: IFileChange[]): void;
$reportFileChunk(handle: number, session: number, chunk: number[] | null): void;
$handleDidFindFile(handle: number, session: number, resource: UriComponents): void;
$handleFindMatch(handle: number, session, data: UriComponents | [UriComponents, ILineMatch]): void;
}
export interface MainThreadTaskShape extends IDisposable {
......@@ -543,6 +544,7 @@ export interface ExtHostFileSystemShape {
$readdir(handle: number, resource: UriComponents): TPromise<[UriComponents, IStat][]>;
$rmdir(handle: number, resource: UriComponents): TPromise<void>;
$findFiles(handle: number, session: number, query: string): TPromise<void>;
$findInFiles(handle: number, session: number, pattern: IPatternInfo): TPromise<void>;
}
export interface ExtHostExtensionServiceShape {
......
......@@ -11,6 +11,7 @@ import * as vscode from 'vscode';
import { IStat } from 'vs/platform/files/common/files';
import { IDisposable } from 'vs/base/common/lifecycle';
import { asWinJsPromise } from 'vs/base/common/async';
import { IPatternInfo } from 'vs/platform/search/common/search';
export class ExtHostFileSystem implements ExtHostFileSystemShape {
......@@ -79,7 +80,27 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape {
if (!provider.findFiles) {
return TPromise.as(undefined);
}
const progress = { report: (uri) => this._proxy.$handleDidFindFile(handle, session, uri) };
const progress = {
report: (uri) => {
this._proxy.$handleFindMatch(handle, session, uri);
}
};
return asWinJsPromise(token => provider.findFiles(query, progress, token));
}
$findInFiles(handle: number, session: number, pattern: IPatternInfo): TPromise<void> {
const provider = this._provider.get(handle);
if (!provider.findInFiles) {
return TPromise.as(undefined);
}
const progress = {
report: (data: vscode.FindMatch) => {
this._proxy.$handleFindMatch(handle, session, [data.uri, {
lineNumber: 1 + data.range.start.line,
preview: data.preview.leading + data.preview.matching + data.preview.trailing,
offsetAndLengths: [[data.preview.leading.length, data.preview.matching.length]]
}]);
}
};
return asWinJsPromise(token => provider.findInFiles(pattern.pattern, pattern.isRegExp, progress, token));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册