mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 11:08:31 -05:00
Merge from vscode 2b0b9136329c181a9e381463a1f7dc3a2d105a34 (#4880)
This commit is contained in:
@@ -19,8 +19,7 @@ import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import * as flow from 'vs/base/node/flow';
|
||||
import { readdir } from 'vs/base/node/pfs';
|
||||
import { IFileQuery, IFolderQuery, IProgressMessage, ISearchEngineStats, IRawFileMatch, ISearchEngine, ISearchEngineSuccess } from 'vs/workbench/services/search/common/search';
|
||||
import { spawnRipgrepCmd } from './ripgrepFileSearch';
|
||||
|
||||
@@ -128,7 +127,7 @@ export class FileWalker {
|
||||
this.cmdSW = StopWatch.create(false);
|
||||
|
||||
// For each root folder
|
||||
flow.parallel<IFolderQuery, void>(folderQueries, (folderQuery: IFolderQuery, rootFolderDone: (err: Error | null, result: void) => void) => {
|
||||
this.parallel<IFolderQuery, void>(folderQueries, (folderQuery: IFolderQuery, rootFolderDone: (err: Error | null, result: void) => void) => {
|
||||
this.call(this.cmdTraversal, this, folderQuery, onResult, onMessage, (err?: Error) => {
|
||||
if (err) {
|
||||
const errorMessage = toErrorMessage(err);
|
||||
@@ -146,6 +145,34 @@ export class FileWalker {
|
||||
});
|
||||
}
|
||||
|
||||
private parallel<T, E>(list: T[], fn: (item: T, callback: (err: Error | null, result: E | null) => void) => void, callback: (err: Array<Error | null> | null, result: E[]) => void): void {
|
||||
const results = new Array(list.length);
|
||||
const errors = new Array<Error | null>(list.length);
|
||||
let didErrorOccur = false;
|
||||
let doneCount = 0;
|
||||
|
||||
if (list.length === 0) {
|
||||
return callback(null, []);
|
||||
}
|
||||
|
||||
list.forEach((item, index) => {
|
||||
fn(item, (error, result) => {
|
||||
if (error) {
|
||||
didErrorOccur = true;
|
||||
results[index] = null;
|
||||
errors[index] = error;
|
||||
} else {
|
||||
results[index] = result;
|
||||
errors[index] = null;
|
||||
}
|
||||
|
||||
if (++doneCount === list.length) {
|
||||
return callback(didErrorOccur ? errors : null, results);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private call<F extends Function>(fun: F, that: any, ...args: any[]): void {
|
||||
try {
|
||||
fun.apply(that, args);
|
||||
@@ -440,7 +467,7 @@ export class FileWalker {
|
||||
|
||||
// Execute tasks on each file in parallel to optimize throughput
|
||||
const hasSibling = glob.hasSiblingFn(() => files);
|
||||
flow.parallel(files, (file: string, clb: (error: Error | null, _?: any) => void): void => {
|
||||
this.parallel(files, (file: string, clb: (error: Error | null, _?: any) => void): void => {
|
||||
|
||||
// Check canceled
|
||||
if (this.isCanceled || this.isLimitHit) {
|
||||
@@ -489,12 +516,14 @@ export class FileWalker {
|
||||
this.walkedPaths[realpath] = true; // remember as walked
|
||||
|
||||
// Continue walking
|
||||
return extfs.readdir(currentAbsolutePath, (error: Error, children: string[]): void => {
|
||||
if (error || this.isCanceled || this.isLimitHit) {
|
||||
return readdir(currentAbsolutePath).then(children => {
|
||||
if (this.isCanceled || this.isLimitHit) {
|
||||
return clb(null);
|
||||
}
|
||||
|
||||
this.doWalk(folderQuery, currentRelativePath, children, onResult, err => clb(err || null));
|
||||
}, error => {
|
||||
clb(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as resources from 'vs/base/common/resources';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IFileMatch, IFileSearchProviderStats, IFolderQuery, ISearchCompleteStats, IFileQuery, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search';
|
||||
import * as vscode from 'vscode';
|
||||
import { FileSearchProvider, FileSearchOptions } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
|
||||
export interface IInternalFileMatch {
|
||||
base: URI;
|
||||
@@ -45,7 +45,7 @@ class FileSearchEngine {
|
||||
|
||||
private globalExcludePattern?: glob.ParsedExpression;
|
||||
|
||||
constructor(private config: IFileQuery, private provider: vscode.FileSearchProvider, private sessionToken?: CancellationToken) {
|
||||
constructor(private config: IFileQuery, private provider: FileSearchProvider, private sessionToken?: CancellationToken) {
|
||||
this.filePattern = config.filePattern;
|
||||
this.includePattern = config.includePattern && glob.parse(config.includePattern);
|
||||
this.maxResults = config.maxResults || undefined;
|
||||
@@ -172,7 +172,7 @@ class FileSearchEngine {
|
||||
});
|
||||
}
|
||||
|
||||
private getSearchOptionsForFolder(fq: IFolderQuery<URI>): vscode.FileSearchOptions {
|
||||
private getSearchOptionsForFolder(fq: IFolderQuery<URI>): FileSearchOptions {
|
||||
const includes = resolvePatternsForProvider(this.config.includePattern, fq.includePattern);
|
||||
const excludes = resolvePatternsForProvider(this.config.excludePattern, fq.excludePattern);
|
||||
|
||||
@@ -283,7 +283,7 @@ export class FileSearchManager {
|
||||
|
||||
private readonly sessions = new Map<string, CancellationTokenSource>();
|
||||
|
||||
fileSearch(config: IFileQuery, provider: vscode.FileSearchProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): Promise<ISearchCompleteStats> {
|
||||
fileSearch(config: IFileQuery, provider: FileSearchProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): Promise<ISearchCompleteStats> {
|
||||
const sessionTokenSource = this.getSessionTokenSource(config.cacheKey);
|
||||
const engine = new FileSearchEngine(config, provider, sessionTokenSource && sessionTokenSource.token);
|
||||
|
||||
|
||||
@@ -144,7 +144,8 @@ function globExprsToRgGlobs(patterns: glob.IExpression, folder?: string, exclude
|
||||
}
|
||||
|
||||
globArgs.push(fixDriveC(key));
|
||||
} else if (value && value.when) {
|
||||
// {{SQL CARBON EDIT}} @todo anthonydresser cast value because we aren't using strict null checks
|
||||
} else if (value && (<glob.SiblingClause>value).when) {
|
||||
siblingClauses[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,24 +3,25 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils';
|
||||
import { RipgrepTextSearchEngine } from 'vs/workbench/services/search/node/ripgrepTextSearchEngine';
|
||||
import * as vscode from 'vscode';
|
||||
import { TextSearchProvider, TextSearchComplete, TextSearchResult, TextSearchQuery, TextSearchOptions } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
import { Progress } from 'vs/platform/progress/common/progress';
|
||||
|
||||
export class RipgrepSearchProvider implements vscode.TextSearchProvider {
|
||||
private inProgress: Set<vscode.CancellationTokenSource> = new Set();
|
||||
export class RipgrepSearchProvider implements TextSearchProvider {
|
||||
private inProgress: Set<CancellationTokenSource> = new Set();
|
||||
|
||||
constructor(private outputChannel: OutputChannel) {
|
||||
process.once('exit', () => this.dispose());
|
||||
}
|
||||
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Promise<vscode.TextSearchComplete> {
|
||||
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): Promise<TextSearchComplete> {
|
||||
const engine = new RipgrepTextSearchEngine(this.outputChannel);
|
||||
return this.withToken(token, token => engine.provideTextSearchResults(query, options, progress, token));
|
||||
}
|
||||
|
||||
private async withToken<T>(token: vscode.CancellationToken, fn: (token: vscode.CancellationToken) => Promise<T>): Promise<T> {
|
||||
private async withToken<T>(token: CancellationToken, fn: (token: CancellationToken) => Promise<T>): Promise<T> {
|
||||
const merged = mergedTokenSource(token);
|
||||
this.inProgress.add(merged);
|
||||
const result = await fn(merged.token);
|
||||
@@ -34,7 +35,7 @@ export class RipgrepSearchProvider implements vscode.TextSearchProvider {
|
||||
}
|
||||
}
|
||||
|
||||
function mergedTokenSource(token: vscode.CancellationToken): vscode.CancellationTokenSource {
|
||||
function mergedTokenSource(token: CancellationToken): CancellationTokenSource {
|
||||
const tokenSource = new CancellationTokenSource();
|
||||
token.onCancellationRequested(() => tokenSource.cancel());
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
import { startsWith } from 'vs/base/common/strings';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { SearchRange, TextSearchMatch } from 'vs/workbench/services/search/common/search';
|
||||
import * as vscode from 'vscode';
|
||||
import { mapArrayOrNot } from 'vs/base/common/arrays';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as searchExtTypes from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
|
||||
export type Maybe<T> = T | null | undefined;
|
||||
|
||||
@@ -16,9 +17,9 @@ export function anchorGlob(glob: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a vscode.TextSearchResult by using our internal TextSearchResult type for its previewOptions logic.
|
||||
* Create a vscode.TextSearchMatch by using our internal TextSearchMatch type for its previewOptions logic.
|
||||
*/
|
||||
export function createTextSearchResult(uri: vscode.Uri, text: string, range: Range | Range[], previewOptions?: vscode.TextSearchPreviewOptions): vscode.TextSearchMatch {
|
||||
export function createTextSearchResult(uri: URI, text: string, range: searchExtTypes.Range | searchExtTypes.Range[], previewOptions?: searchExtTypes.TextSearchPreviewOptions): searchExtTypes.TextSearchMatch {
|
||||
const searchRange = mapArrayOrNot(range, rangeToSearchRange);
|
||||
|
||||
const internalResult = new TextSearchMatch(text, searchRange, previewOptions);
|
||||
@@ -33,50 +34,12 @@ export function createTextSearchResult(uri: vscode.Uri, text: string, range: Ran
|
||||
};
|
||||
}
|
||||
|
||||
function rangeToSearchRange(range: Range): SearchRange {
|
||||
function rangeToSearchRange(range: searchExtTypes.Range): SearchRange {
|
||||
return new SearchRange(range.start.line, range.start.character, range.end.line, range.end.character);
|
||||
}
|
||||
|
||||
function searchRangeToRange(range: SearchRange): Range {
|
||||
return new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
||||
}
|
||||
|
||||
export class Position {
|
||||
constructor(readonly line: number, readonly character: number) { }
|
||||
|
||||
isBefore(other: Position): boolean { return false; }
|
||||
isBeforeOrEqual(other: Position): boolean { return false; }
|
||||
isAfter(other: Position): boolean { return false; }
|
||||
isAfterOrEqual(other: Position): boolean { return false; }
|
||||
isEqual(other: Position): boolean { return false; }
|
||||
compareTo(other: Position): number { return 0; }
|
||||
translate(lineDelta?: number, characterDelta?: number): Position;
|
||||
translate(change: { lineDelta?: number; characterDelta?: number; }): Position;
|
||||
translate(_?: any, _2?: any): Position { return new Position(0, 0); }
|
||||
with(line?: number, character?: number): Position;
|
||||
with(change: { line?: number; character?: number; }): Position;
|
||||
with(_: any): Position { return new Position(0, 0); }
|
||||
}
|
||||
|
||||
export class Range {
|
||||
readonly start: Position;
|
||||
readonly end: Position;
|
||||
|
||||
constructor(startLine: number, startCol: number, endLine: number, endCol: number) {
|
||||
this.start = new Position(startLine, startCol);
|
||||
this.end = new Position(endLine, endCol);
|
||||
}
|
||||
|
||||
isEmpty: boolean;
|
||||
isSingleLine: boolean;
|
||||
contains(positionOrRange: Position | Range): boolean { return false; }
|
||||
isEqual(other: Range): boolean { return false; }
|
||||
intersection(range: Range): Range | undefined { return undefined; }
|
||||
union(other: Range): Range { return new Range(0, 0, 0, 0); }
|
||||
|
||||
with(start?: Position, end?: Position): Range;
|
||||
with(change: { start?: Position, end?: Position }): Range;
|
||||
with(_: any): Range { return new Range(0, 0, 0, 0); }
|
||||
function searchRangeToRange(range: SearchRange): searchExtTypes.Range {
|
||||
return new searchExtTypes.Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
||||
}
|
||||
|
||||
export interface IOutputChannel {
|
||||
|
||||
@@ -10,12 +10,14 @@ import { NodeStringDecoder, StringDecoder } from 'string_decoder';
|
||||
import { createRegExp, startsWith, startsWithUTF8BOM, stripUTF8BOM, escapeRegExpCharacters, endsWith } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IExtendedExtensionSearchOptions, SearchError, SearchErrorCode, serializeSearchError } from 'vs/workbench/services/search/common/search';
|
||||
import * as vscode from 'vscode';
|
||||
import { rgPath } from 'vscode-ripgrep';
|
||||
import { anchorGlob, createTextSearchResult, IOutputChannel, Maybe, Range } from './ripgrepSearchUtils';
|
||||
import { anchorGlob, createTextSearchResult, IOutputChannel, Maybe } from './ripgrepSearchUtils';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { splitGlobAware } from 'vs/base/common/glob';
|
||||
import { groupBy } from 'vs/base/common/collections';
|
||||
import { TextSearchQuery, TextSearchOptions, TextSearchResult, TextSearchComplete, TextSearchPreviewOptions, TextSearchContext, TextSearchMatch, Range } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
import { Progress } from 'vs/platform/progress/common/progress';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
// If vscode-ripgrep is in an .asar file, then the binary is unpacked.
|
||||
const rgDiskPath = rgPath.replace(/\bnode_modules\.asar\b/, 'node_modules.asar.unpacked');
|
||||
@@ -24,7 +26,7 @@ export class RipgrepTextSearchEngine {
|
||||
|
||||
constructor(private outputChannel: IOutputChannel) { }
|
||||
|
||||
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, token: vscode.CancellationToken): Promise<vscode.TextSearchComplete> {
|
||||
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): Promise<TextSearchComplete> {
|
||||
this.outputChannel.appendLine(`provideTextSearchResults ${query.pattern}, ${JSON.stringify({
|
||||
...options,
|
||||
...{
|
||||
@@ -53,7 +55,7 @@ export class RipgrepTextSearchEngine {
|
||||
|
||||
let gotResult = false;
|
||||
const ripgrepParser = new RipgrepParser(options.maxResults, cwd, options.previewOptions);
|
||||
ripgrepParser.on('result', (match: vscode.TextSearchResult) => {
|
||||
ripgrepParser.on('result', (match: TextSearchResult) => {
|
||||
gotResult = true;
|
||||
progress.report(match);
|
||||
});
|
||||
@@ -155,7 +157,7 @@ export class RipgrepParser extends EventEmitter {
|
||||
|
||||
private numResults = 0;
|
||||
|
||||
constructor(private maxResults: number, private rootFolder: string, private previewOptions?: vscode.TextSearchPreviewOptions) {
|
||||
constructor(private maxResults: number, private rootFolder: string, private previewOptions?: TextSearchPreviewOptions) {
|
||||
super();
|
||||
this.stringDecoder = new StringDecoder();
|
||||
}
|
||||
@@ -169,7 +171,7 @@ export class RipgrepParser extends EventEmitter {
|
||||
}
|
||||
|
||||
|
||||
on(event: 'result', listener: (result: vscode.TextSearchResult) => void): this;
|
||||
on(event: 'result', listener: (result: TextSearchResult) => void): this;
|
||||
on(event: 'hitLimit', listener: () => void): this;
|
||||
on(event: string, listener: (...args: any[]) => void): this {
|
||||
super.on(event, listener);
|
||||
@@ -240,7 +242,7 @@ export class RipgrepParser extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
private createTextSearchMatch(data: IRgMatch, uri: vscode.Uri): vscode.TextSearchMatch {
|
||||
private createTextSearchMatch(data: IRgMatch, uri: URI): TextSearchMatch {
|
||||
const lineNumber = data.line_number - 1;
|
||||
let isBOMStripped = false;
|
||||
let fullText = bytesOrTextToString(data.lines);
|
||||
@@ -290,7 +292,7 @@ export class RipgrepParser extends EventEmitter {
|
||||
return createTextSearchResult(uri, fullText, <Range[]>ranges, this.previewOptions);
|
||||
}
|
||||
|
||||
private createTextSearchContext(data: IRgMatch, uri: URI): vscode.TextSearchContext[] {
|
||||
private createTextSearchContext(data: IRgMatch, uri: URI): TextSearchContext[] {
|
||||
const text = bytesOrTextToString(data.lines);
|
||||
const startLine = data.line_number;
|
||||
return text
|
||||
@@ -305,7 +307,7 @@ export class RipgrepParser extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
private onResult(match: vscode.TextSearchResult): void {
|
||||
private onResult(match: TextSearchResult): void {
|
||||
this.emit('result', match);
|
||||
}
|
||||
}
|
||||
@@ -333,7 +335,7 @@ function getNumLinesAndLastNewlineLength(text: string): { numLines: number, last
|
||||
return { numLines, lastLineLength };
|
||||
}
|
||||
|
||||
function getRgArgs(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions): string[] {
|
||||
function getRgArgs(query: TextSearchQuery, options: TextSearchOptions): string[] {
|
||||
const args = ['--hidden'];
|
||||
args.push(query.isCaseSensitive ? '--case-sensitive' : '--ignore-case');
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { IFileMatch, IProgressMessage, ITextQuery, ITextSearchStats, ITextSearchMatch, ISerializedFileMatch, ISerializedSearchSuccess } from 'vs/workbench/services/search/common/search';
|
||||
import { RipgrepTextSearchEngine } from 'vs/workbench/services/search/node/ripgrepTextSearchEngine';
|
||||
import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
|
||||
@@ -30,7 +30,7 @@ export class TextSearchEngineAdapter {
|
||||
onMessage({ message: msg });
|
||||
}
|
||||
};
|
||||
const textSearchManager = new TextSearchManager(this.query, new RipgrepTextSearchEngine(pretendOutputChannel), extfs);
|
||||
const textSearchManager = new TextSearchManager(this.query, new RipgrepTextSearchEngine(pretendOutputChannel), pfs);
|
||||
return new Promise((resolve, reject) => {
|
||||
return textSearchManager
|
||||
.search(
|
||||
|
||||
@@ -11,9 +11,9 @@ import * as glob from 'vs/base/common/glob';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { toCanonicalName } from 'vs/base/node/encoding';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search';
|
||||
import * as vscode from 'vscode';
|
||||
import { TextSearchProvider, TextSearchResult, TextSearchMatch, TextSearchComplete, Range, TextSearchOptions, TextSearchQuery } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
|
||||
export class TextSearchManager {
|
||||
|
||||
@@ -22,7 +22,7 @@ export class TextSearchManager {
|
||||
private isLimitHit: boolean;
|
||||
private resultCount = 0;
|
||||
|
||||
constructor(private query: ITextQuery, private provider: vscode.TextSearchProvider, private _extfs: typeof extfs = extfs) {
|
||||
constructor(private query: ITextQuery, private provider: TextSearchProvider, private _pfs: typeof pfs = pfs) {
|
||||
}
|
||||
|
||||
search(onProgress: (matches: IFileMatch[]) => void, token: CancellationToken): Promise<ISearchCompleteStats> {
|
||||
@@ -34,7 +34,7 @@ export class TextSearchManager {
|
||||
this.collector = new TextSearchResultsCollector(onProgress);
|
||||
|
||||
let isCanceled = false;
|
||||
const onResult = (result: vscode.TextSearchResult, folderIdx: number) => {
|
||||
const onResult = (result: TextSearchResult, folderIdx: number) => {
|
||||
if (isCanceled) {
|
||||
return;
|
||||
}
|
||||
@@ -79,14 +79,14 @@ export class TextSearchManager {
|
||||
});
|
||||
}
|
||||
|
||||
private resultSize(result: vscode.TextSearchResult): number {
|
||||
const match = <vscode.TextSearchMatch>result;
|
||||
private resultSize(result: TextSearchResult): number {
|
||||
const match = <TextSearchMatch>result;
|
||||
return Array.isArray(match.ranges) ?
|
||||
match.ranges.length :
|
||||
1;
|
||||
}
|
||||
|
||||
private trimResultToSize(result: vscode.TextSearchMatch, size: number): vscode.TextSearchMatch {
|
||||
private trimResultToSize(result: TextSearchMatch, size: number): TextSearchMatch {
|
||||
const rangesArr = Array.isArray(result.ranges) ? result.ranges : [result.ranges];
|
||||
const matchesArr = Array.isArray(result.preview.matches) ? result.preview.matches : [result.preview.matches];
|
||||
|
||||
@@ -100,11 +100,11 @@ export class TextSearchManager {
|
||||
};
|
||||
}
|
||||
|
||||
private searchInFolder(folderQuery: IFolderQuery<URI>, onResult: (result: vscode.TextSearchResult) => void, token: CancellationToken): Promise<vscode.TextSearchComplete | null | undefined> {
|
||||
private searchInFolder(folderQuery: IFolderQuery<URI>, onResult: (result: TextSearchResult) => void, token: CancellationToken): Promise<TextSearchComplete | null | undefined> {
|
||||
const queryTester = new QueryGlobTester(this.query, folderQuery);
|
||||
const testingPs: Promise<void>[] = [];
|
||||
const progress = {
|
||||
report: (result: vscode.TextSearchResult) => {
|
||||
report: (result: TextSearchResult) => {
|
||||
if (!this.validateProviderResult(result)) {
|
||||
return;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ export class TextSearchManager {
|
||||
});
|
||||
}
|
||||
|
||||
private validateProviderResult(result: vscode.TextSearchResult): boolean {
|
||||
private validateProviderResult(result: TextSearchResult): boolean {
|
||||
if (extensionResultIsMatch(result)) {
|
||||
if (Array.isArray(result.ranges)) {
|
||||
if (!Array.isArray(result.preview.matches)) {
|
||||
@@ -143,7 +143,7 @@ export class TextSearchManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((<vscode.Range[]>result.preview.matches).length !== result.ranges.length) {
|
||||
if ((<Range[]>result.preview.matches).length !== result.ranges.length) {
|
||||
console.warn('INVALID - A text search provider match\'s`ranges` and`matches` properties must have the same length.');
|
||||
return false;
|
||||
}
|
||||
@@ -159,22 +159,14 @@ export class TextSearchManager {
|
||||
}
|
||||
|
||||
private readdir(dirname: string): Promise<string[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._extfs.readdir(dirname, (err, files) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
resolve(files);
|
||||
});
|
||||
});
|
||||
return this._pfs.readdir(dirname);
|
||||
}
|
||||
|
||||
private getSearchOptionsForFolder(fq: IFolderQuery<URI>): vscode.TextSearchOptions {
|
||||
private getSearchOptionsForFolder(fq: IFolderQuery<URI>): TextSearchOptions {
|
||||
const includes = resolvePatternsForProvider(this.query.includePattern, fq.includePattern);
|
||||
const excludes = resolvePatternsForProvider(this.query.excludePattern, fq.excludePattern);
|
||||
|
||||
const options = <vscode.TextSearchOptions>{
|
||||
const options = <TextSearchOptions>{
|
||||
folder: URI.from(fq.folder),
|
||||
excludes,
|
||||
includes,
|
||||
@@ -193,8 +185,8 @@ export class TextSearchManager {
|
||||
}
|
||||
}
|
||||
|
||||
function patternInfoToQuery(patternInfo: IPatternInfo): vscode.TextSearchQuery {
|
||||
return <vscode.TextSearchQuery>{
|
||||
function patternInfoToQuery(patternInfo: IPatternInfo): TextSearchQuery {
|
||||
return <TextSearchQuery>{
|
||||
isCaseSensitive: patternInfo.isCaseSensitive || false,
|
||||
isRegExp: patternInfo.isRegExp || false,
|
||||
isWordMatch: patternInfo.isWordMatch || false,
|
||||
@@ -214,7 +206,7 @@ export class TextSearchResultsCollector {
|
||||
this._batchedCollector = new BatchedCollector<IFileMatch>(512, items => this.sendItems(items));
|
||||
}
|
||||
|
||||
add(data: vscode.TextSearchResult, folderIdx: number): void {
|
||||
add(data: TextSearchResult, folderIdx: number): void {
|
||||
// Collects TextSearchResults into IInternalFileMatches and collates using BatchedCollector.
|
||||
// This is efficient for ripgrep which sends results back one file at a time. It wouldn't be efficient for other search
|
||||
// providers that send results in random order. We could do this step afterwards instead.
|
||||
@@ -251,8 +243,8 @@ export class TextSearchResultsCollector {
|
||||
}
|
||||
}
|
||||
|
||||
function extensionResultToFrontendResult(data: vscode.TextSearchResult): ITextSearchResult {
|
||||
// Warning: result from RipgrepTextSearchEH has fake vscode.Range. Don't depend on any other props beyond these...
|
||||
function extensionResultToFrontendResult(data: TextSearchResult): ITextSearchResult {
|
||||
// Warning: result from RipgrepTextSearchEH has fake Range. Don't depend on any other props beyond these...
|
||||
if (extensionResultIsMatch(data)) {
|
||||
return <ITextSearchMatch>{
|
||||
preview: {
|
||||
@@ -279,8 +271,8 @@ function extensionResultToFrontendResult(data: vscode.TextSearchResult): ITextSe
|
||||
}
|
||||
}
|
||||
|
||||
export function extensionResultIsMatch(data: vscode.TextSearchResult): data is vscode.TextSearchMatch {
|
||||
return !!(<vscode.TextSearchMatch>data).preview;
|
||||
export function extensionResultIsMatch(data: TextSearchResult): data is TextSearchMatch {
|
||||
return !!(<TextSearchMatch>data).preview;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user