mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
[Search Editor] Add option for context lines
This commit is contained in:
parent
529351318e
commit
eae6eca8cf
|
@ -28,6 +28,15 @@
|
|||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "searchResult.rerunSearchWithContext",
|
||||
"title": "%searchResult.rerunSearchWithContext.title%",
|
||||
"category": "Search Result",
|
||||
"icon": {
|
||||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
|
@ -35,6 +44,7 @@
|
|||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"when": "editorLangId == search-result",
|
||||
"alt": "searchResult.rerunSearchWithContext",
|
||||
"group": "navigation"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"displayName": "Search Result",
|
||||
"description": "Provides syntax highlighting and language features for tabbed search results.",
|
||||
"searchResult.rerunSearch.title": "Search Again"
|
||||
"searchResult.rerunSearch.title": "Search Again",
|
||||
"searchResult.rerunSearchWithContext.title": "Search Again (Wth Context)"
|
||||
}
|
||||
|
|
|
@ -7,14 +7,17 @@ import * as vscode from 'vscode';
|
|||
import * as pathUtils from 'path';
|
||||
|
||||
const FILE_LINE_REGEX = /^(\S.*):$/;
|
||||
const RESULT_LINE_REGEX = /^(\s+)(\d+):(\s+)(.*)$/;
|
||||
const RESULT_LINE_REGEX = /^(\s+)(\d+)(?::| )(\s+)(.*)$/;
|
||||
const SEARCH_RESULT_SELECTOR = { language: 'search-result' };
|
||||
const DIRECTIVES = ['# Query:', '# Flags:', '# Including:', '# Excluding:', '# ContextLines:'];
|
||||
const FLAGS = ['RegExp', 'CaseSensitive', 'IgnoreExcludeSettings', 'WordMatch'];
|
||||
|
||||
let cachedLastParse: { version: number, parse: ParsedSearchResults } | undefined;
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('searchResult.rerunSearch', () => vscode.commands.executeCommand('search.action.rerunEditorSearch')),
|
||||
vscode.commands.registerCommand('searchResult.rerunSearchWithContext', () => vscode.commands.executeCommand('search.action.rerunEditorSearchWithContext')),
|
||||
|
||||
vscode.languages.registerDocumentSymbolProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.DocumentSymbol[] {
|
||||
|
@ -38,16 +41,16 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
const line = document.lineAt(position.line);
|
||||
if (position.line > 3) { return []; }
|
||||
if (position.character === 0 || (position.character === 1 && line.text === '#')) {
|
||||
const header = Array.from({ length: 4 }).map((_, i) => document.lineAt(i).text);
|
||||
const header = Array.from({ length: DIRECTIVES.length }).map((_, i) => document.lineAt(i).text);
|
||||
|
||||
return ['# Query:', '# Flags:', '# Including:', '# Excluding:']
|
||||
return DIRECTIVES
|
||||
.filter(suggestion => header.every(line => line.indexOf(suggestion) === -1))
|
||||
.map(flag => ({ label: flag, insertText: (flag.slice(position.character)) + ' ' }));
|
||||
}
|
||||
|
||||
if (line.text.indexOf('# Flags:') === -1) { return []; }
|
||||
|
||||
return ['RegExp', 'CaseSensitive', 'IgnoreExcludeSettings', 'WordMatch']
|
||||
return FLAGS
|
||||
.filter(flag => line.text.indexOf(flag) === -1)
|
||||
.map(flag => ({ label: flag, insertText: flag + ' ' }));
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"scopeName": "text.searchResult",
|
||||
"patterns": [
|
||||
{
|
||||
"match": "^# (Query|Flags|Including|Excluding): .*$",
|
||||
"match": "^# (Query|Flags|Including|Excluding|ContextLines): .*$",
|
||||
"name": "comment"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -41,7 +41,7 @@ import { ExplorerFolderContext, ExplorerRootContext, FilesExplorerFocusCondition
|
|||
import { OpenAnythingHandler } from 'vs/workbench/contrib/search/browser/openAnythingHandler';
|
||||
import { OpenSymbolHandler } from 'vs/workbench/contrib/search/browser/openSymbolHandler';
|
||||
import { registerContributions as replaceContributions } from 'vs/workbench/contrib/search/browser/replaceContributions';
|
||||
import { clearHistoryCommand, ClearSearchResultsAction, CloseReplaceAction, CollapseDeepestExpandedLevelAction, copyAllCommand, copyMatchCommand, copyPathCommand, FocusNextInputAction, FocusNextSearchResultAction, FocusPreviousInputAction, FocusPreviousSearchResultAction, focusSearchListCommand, getSearchView, openSearchView, OpenSearchViewletAction, RefreshAction, RemoveAction, ReplaceAction, ReplaceAllAction, ReplaceAllInFolderAction, ReplaceInFilesAction, toggleCaseSensitiveCommand, toggleRegexCommand, toggleWholeWordCommand, FindInFilesCommand, ToggleSearchOnTypeAction, OpenResultsInEditorAction, RerunEditorSearchAction } from 'vs/workbench/contrib/search/browser/searchActions';
|
||||
import { clearHistoryCommand, ClearSearchResultsAction, CloseReplaceAction, CollapseDeepestExpandedLevelAction, copyAllCommand, copyMatchCommand, copyPathCommand, FocusNextInputAction, FocusNextSearchResultAction, FocusPreviousInputAction, FocusPreviousSearchResultAction, focusSearchListCommand, getSearchView, openSearchView, OpenSearchViewletAction, RefreshAction, RemoveAction, ReplaceAction, ReplaceAllAction, ReplaceAllInFolderAction, ReplaceInFilesAction, toggleCaseSensitiveCommand, toggleRegexCommand, toggleWholeWordCommand, FindInFilesCommand, ToggleSearchOnTypeAction, OpenResultsInEditorAction, RerunEditorSearchAction, RerunEditorSearchWithContextAction } from 'vs/workbench/contrib/search/browser/searchActions';
|
||||
import { SearchPanel } from 'vs/workbench/contrib/search/browser/searchPanel';
|
||||
import { SearchView, SearchViewPosition } from 'vs/workbench/contrib/search/browser/searchView';
|
||||
import { SearchViewlet } from 'vs/workbench/contrib/search/browser/searchViewlet';
|
||||
|
@ -651,6 +651,11 @@ registry.registerWorkbenchAction(
|
|||
'Search Editor: Search Again', category,
|
||||
ContextKeyExpr.and(EditorContextKeys.languageId.isEqualTo('search-result')));
|
||||
|
||||
registry.registerWorkbenchAction(
|
||||
SyncActionDescriptor.create(RerunEditorSearchWithContextAction, RerunEditorSearchWithContextAction.ID, RerunEditorSearchWithContextAction.LABEL),
|
||||
'Search Editor: Search Again (With Context)', category,
|
||||
ContextKeyExpr.and(EditorContextKeys.languageId.isEqualTo('search-result')));
|
||||
|
||||
|
||||
// Register Quick Open Handler
|
||||
Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen).registerDefaultQuickOpenHandler(
|
||||
|
|
|
@ -32,6 +32,7 @@ import { ITreeNavigator } from 'vs/base/browser/ui/tree/tree';
|
|||
import { createEditorFromSearchResult, refreshActiveEditorSearch } from 'vs/workbench/contrib/search/browser/searchEditor';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
|
||||
export function isSearchViewFocused(viewletService: IViewletService, panelService: IPanelService): boolean {
|
||||
const searchView = getSearchView(viewletService, panelService);
|
||||
|
@ -472,7 +473,38 @@ export class RerunEditorSearchAction extends Action {
|
|||
async run() {
|
||||
if (this.configurationService.getValue<ISearchConfigurationProperties>('search').enableSearchEditorPreview) {
|
||||
await this.progressService.withProgress({ location: ProgressLocation.Window },
|
||||
() => refreshActiveEditorSearch(this.editorService, this.instantiationService, this.contextService, this.labelService, this.configurationService));
|
||||
() => refreshActiveEditorSearch(undefined, this.editorService, this.instantiationService, this.contextService, this.labelService, this.configurationService));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class RerunEditorSearchWithContextAction extends Action {
|
||||
|
||||
static readonly ID: string = Constants.RerunEditorSearchWithContextCommandId;
|
||||
static readonly LABEL = nls.localize('search.rerunEditorSearchContext', "Search Again (With Context)");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@ILabelService private labelService: ILabelService,
|
||||
@IProgressService private progressService: IProgressService,
|
||||
@IQuickInputService private quickPickService: IQuickInputService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
async run() {
|
||||
const lines = await this.quickPickService.input({
|
||||
prompt: nls.localize('lines', "Lines of Context"),
|
||||
value: '2',
|
||||
validateInput: async (value) => isNaN(parseInt(value)) ? nls.localize('mustBeInteger', "Must enter an integer") : undefined
|
||||
});
|
||||
if (lines === undefined) { return; }
|
||||
if (this.configurationService.getValue<ISearchConfigurationProperties>('search').enableSearchEditorPreview) {
|
||||
await this.progressService.withProgress({ location: ProgressLocation.Window },
|
||||
() => refreshActiveEditorSearch(+lines, this.editorService, this.instantiationService, this.contextService, this.labelService, this.configurationService));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ const matchToSearchResultFormat = (match: Match): { line: string, ranges: Range[
|
|||
};
|
||||
|
||||
type SearchResultSerialization = { text: string[], matchRanges: Range[] };
|
||||
|
||||
function fileMatchToSearchResultFormat(fileMatch: FileMatch, labelFormatter: (x: URI) => string): SearchResultSerialization {
|
||||
const serializedMatches = flatten(fileMatch.matches()
|
||||
.sort(searchMatchComparer)
|
||||
|
@ -76,17 +77,37 @@ function fileMatchToSearchResultFormat(fileMatch: FileMatch, labelFormatter: (x:
|
|||
|
||||
const targetLineNumberToOffset: Record<string, number> = {};
|
||||
|
||||
const context: { line: string, lineNumber: number }[] = [];
|
||||
fileMatch.context.forEach((line, lineNumber) => context.push({ line, lineNumber }));
|
||||
context.sort((a, b) => a.lineNumber - b.lineNumber);
|
||||
|
||||
let lastLine: number | undefined = undefined;
|
||||
|
||||
const seenLines = new Set<string>();
|
||||
serializedMatches.forEach(match => {
|
||||
if (!seenLines.has(match.line)) {
|
||||
while (context.length && context[0].lineNumber < +match.lineNumber) {
|
||||
const { line, lineNumber } = context.shift()!;
|
||||
if (lastLine !== undefined && lineNumber !== lastLine + 1) {
|
||||
text.push('');
|
||||
}
|
||||
text.push(` ${lineNumber} ${line}`);
|
||||
lastLine = lineNumber;
|
||||
}
|
||||
|
||||
targetLineNumberToOffset[match.lineNumber] = text.length;
|
||||
seenLines.add(match.line);
|
||||
text.push(match.line);
|
||||
lastLine = +match.lineNumber;
|
||||
}
|
||||
|
||||
matchRanges.push(...match.ranges.map(translateRangeLines(targetLineNumberToOffset[match.lineNumber])));
|
||||
});
|
||||
|
||||
while (context.length) {
|
||||
const { line, lineNumber } = context.shift()!;
|
||||
text.push(` ${lineNumber} ${line}`);
|
||||
}
|
||||
|
||||
return { text, matchRanges };
|
||||
}
|
||||
|
@ -104,7 +125,7 @@ const flattenSearchResultSerializations = (serializations: SearchResultSerializa
|
|||
return { text, matchRanges };
|
||||
};
|
||||
|
||||
const contentPatternToSearchResultHeader = (pattern: ITextQuery | null, includes: string, excludes: string): string[] => {
|
||||
const contentPatternToSearchResultHeader = (pattern: ITextQuery | null, includes: string, excludes: string, contextLines: number): string[] => {
|
||||
if (!pattern) { return []; }
|
||||
|
||||
const removeNullFalseAndUndefined = <T>(a: (T | null | false | undefined)[]) => a.filter(a => a !== false && a !== null && a !== undefined) as T[];
|
||||
|
@ -123,16 +144,32 @@ const contentPatternToSearchResultHeader = (pattern: ITextQuery | null, includes
|
|||
]).join(' ')}`,
|
||||
includes ? `# Including: ${includes}` : undefined,
|
||||
excludes ? `# Excluding: ${excludes}` : undefined,
|
||||
contextLines ? `# ContextLines: ${contextLines}` : undefined,
|
||||
''
|
||||
]);
|
||||
};
|
||||
|
||||
const searchHeaderToContentPattern = (header: string[]): { pattern: string, flags: { regex: boolean, wholeWord: boolean, caseSensitive: boolean, ignoreExcludes: boolean }, includes: string, excludes: string } => {
|
||||
const query = {
|
||||
|
||||
type SearchHeader = {
|
||||
pattern: string;
|
||||
flags: {
|
||||
regex: boolean;
|
||||
wholeWord: boolean;
|
||||
caseSensitive: boolean;
|
||||
ignoreExcludes: boolean;
|
||||
};
|
||||
includes: string;
|
||||
excludes: string;
|
||||
context: number | undefined;
|
||||
};
|
||||
|
||||
const searchHeaderToContentPattern = (header: string[]): SearchHeader => {
|
||||
const query: SearchHeader = {
|
||||
pattern: '',
|
||||
flags: { regex: false, caseSensitive: false, ignoreExcludes: false, wholeWord: false },
|
||||
includes: '',
|
||||
excludes: ''
|
||||
excludes: '',
|
||||
context: undefined
|
||||
};
|
||||
|
||||
const unescapeNewlines = (str: string) => str.replace(/\\\\/g, '\\').replace(/\\n/g, '\n');
|
||||
|
@ -145,6 +182,7 @@ const searchHeaderToContentPattern = (header: string[]): { pattern: string, flag
|
|||
case 'Query': query.pattern = unescapeNewlines(value); break;
|
||||
case 'Including': query.includes = value; break;
|
||||
case 'Excluding': query.excludes = value; break;
|
||||
case 'ContextLines': query.context = +value; break;
|
||||
case 'Flags': {
|
||||
query.flags = {
|
||||
regex: value.indexOf('RegExp') !== -1,
|
||||
|
@ -159,19 +197,20 @@ const searchHeaderToContentPattern = (header: string[]): { pattern: string, flag
|
|||
return query;
|
||||
};
|
||||
|
||||
const serializeSearchResultForEditor = (searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string, labelFormatter: (x: URI) => string): SearchResultSerialization => {
|
||||
const header = contentPatternToSearchResultHeader(searchResult.query, rawIncludePattern, rawExcludePattern);
|
||||
const serializeSearchResultForEditor = (searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string, contextLines: number, labelFormatter: (x: URI) => string): SearchResultSerialization => {
|
||||
const header = contentPatternToSearchResultHeader(searchResult.query, rawIncludePattern, rawExcludePattern, contextLines);
|
||||
const allResults =
|
||||
flattenSearchResultSerializations(
|
||||
flatten(searchResult.folderMatches().sort(searchMatchComparer)
|
||||
.map(folderMatch => folderMatch.matches().sort(searchMatchComparer)
|
||||
.map(fileMatch => fileMatchToSearchResultFormat(fileMatch, labelFormatter)))));
|
||||
flatten(
|
||||
searchResult.folderMatches().sort(searchMatchComparer)
|
||||
.map(folderMatch => folderMatch.matches().sort(searchMatchComparer)
|
||||
.map(fileMatch => fileMatchToSearchResultFormat(fileMatch, labelFormatter)))));
|
||||
|
||||
return { matchRanges: allResults.matchRanges.map(translateRangeLines(header.length)), text: header.concat(allResults.text) };
|
||||
};
|
||||
|
||||
export const refreshActiveEditorSearch =
|
||||
async (editorService: IEditorService, instantiationService: IInstantiationService, contextService: IWorkspaceContextService, labelService: ILabelService, configurationService: IConfigurationService) => {
|
||||
async (contextLines: number | undefined, editorService: IEditorService, instantiationService: IInstantiationService, contextService: IWorkspaceContextService, labelService: ILabelService, configurationService: IConfigurationService) => {
|
||||
const model = editorService.activeTextEditorWidget?.getModel();
|
||||
if (!model) { return; }
|
||||
|
||||
|
@ -190,6 +229,8 @@ export const refreshActiveEditorSearch =
|
|||
isWordMatch: contentPattern.flags.wholeWord
|
||||
};
|
||||
|
||||
contextLines = contextLines ?? contentPattern.context ?? 0;
|
||||
|
||||
const options: ITextQueryBuilderOptions = {
|
||||
_reason: 'searchEditor',
|
||||
extraFileResources: instantiationService.invokeFunction(getOutOfWorkspaceEditorResources),
|
||||
|
@ -202,6 +243,8 @@ export const refreshActiveEditorSearch =
|
|||
matchLines: 1,
|
||||
charsPerLine: 1000
|
||||
},
|
||||
afterContext: contextLines,
|
||||
beforeContext: contextLines,
|
||||
isSmartCase: configurationService.getValue<ISearchConfigurationProperties>('search').smartCase,
|
||||
expandPatterns: true
|
||||
};
|
||||
|
@ -220,7 +263,7 @@ export const refreshActiveEditorSearch =
|
|||
await searchModel.search(query);
|
||||
|
||||
const labelFormatter = (uri: URI): string => labelService.getUriLabel(uri, { relative: true });
|
||||
const results = serializeSearchResultForEditor(searchModel.searchResult, '', '', labelFormatter);
|
||||
const results = serializeSearchResultForEditor(searchModel.searchResult, contentPattern.includes, contentPattern.excludes, contextLines, labelFormatter);
|
||||
|
||||
textModel.setValue(results.text.join(lineDelimiter));
|
||||
textModel.deltaDecorations([], results.matchRanges.map(range => ({ range, options: { className: 'searchEditorFindMatch', stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges } })));
|
||||
|
@ -233,7 +276,7 @@ export const createEditorFromSearchResult =
|
|||
|
||||
const labelFormatter = (uri: URI): string => labelService.getUriLabel(uri, { relative: true });
|
||||
|
||||
const results = serializeSearchResultForEditor(searchResult, rawIncludePattern, rawExcludePattern, labelFormatter);
|
||||
const results = serializeSearchResultForEditor(searchResult, rawIncludePattern, rawExcludePattern, 0, labelFormatter);
|
||||
|
||||
let possible = {
|
||||
contents: results.text.join(lineDelimiter),
|
||||
|
@ -255,7 +298,6 @@ export const createEditorFromSearchResult =
|
|||
model.deltaDecorations([], results.matchRanges.map(range => ({ range, options: { className: 'searchEditorFindMatch', stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges } })));
|
||||
};
|
||||
|
||||
// theming
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
collector.addRule(`.monaco-editor .searchEditorFindMatch { background-color: ${theme.getColor(searchEditorFindMatch)}; }`);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ export const CopyMatchCommandId = 'search.action.copyMatch';
|
|||
export const CopyAllCommandId = 'search.action.copyAll';
|
||||
export const OpenInEditorCommandId = 'search.action.openInEditor';
|
||||
export const RerunEditorSearchCommandId = 'search.action.rerunEditorSearch';
|
||||
export const RerunEditorSearchWithContextCommandId = 'search.action.rerunEditorSearchWithContext';
|
||||
export const ClearSearchHistoryCommandId = 'search.action.clearHistory';
|
||||
export const FocusSearchListCommandID = 'search.action.focusSearchList';
|
||||
export const ReplaceActionId = 'search.action.replace';
|
||||
|
|
|
@ -20,7 +20,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
|
|||
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
|
||||
import { ReplacePattern } from 'vs/workbench/services/search/common/replace';
|
||||
import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchConfigurationProperties, ISearchService, ITextQuery, ITextSearchPreviewOptions, ITextSearchMatch, ITextSearchStats, resultIsMatch, ISearchRange, OneLineRange } from 'vs/workbench/services/search/common/search';
|
||||
import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchConfigurationProperties, ISearchService, ITextQuery, ITextSearchPreviewOptions, ITextSearchMatch, ITextSearchStats, resultIsMatch, ISearchRange, OneLineRange, ITextSearchContext, ITextSearchResult } from 'vs/workbench/services/search/common/search';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { overviewRulerFindMatchForeground, minimapFindMatch } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
|
||||
|
@ -197,6 +197,11 @@ export class FileMatch extends Disposable implements IFileMatch {
|
|||
private _updateScheduler: RunOnceScheduler;
|
||||
private _modelDecorations: string[] = [];
|
||||
|
||||
private _context: Map<number, string> = new Map();
|
||||
public get context(): Map<number, string> {
|
||||
return new Map(this._context);
|
||||
}
|
||||
|
||||
constructor(private _query: IPatternInfo, private _previewOptions: ITextSearchPreviewOptions | undefined, private _maxResults: number | undefined, private _parent: FolderMatch, private rawMatch: IFileMatch,
|
||||
@IModelService private readonly modelService: IModelService, @IReplaceService private readonly replaceService: IReplaceService
|
||||
) {
|
||||
|
@ -221,6 +226,8 @@ export class FileMatch extends Disposable implements IFileMatch {
|
|||
textSearchResultToMatches(rawMatch, this)
|
||||
.forEach(m => this.add(m));
|
||||
});
|
||||
|
||||
this.addContext(this.rawMatch.results);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,6 +382,14 @@ export class FileMatch extends Disposable implements IFileMatch {
|
|||
return getBaseLabel(this.resource);
|
||||
}
|
||||
|
||||
addContext(results: ITextSearchResult[] | undefined) {
|
||||
if (!results) { return; }
|
||||
|
||||
results
|
||||
.filter((result => !resultIsMatch(result)) as ((a: any) => a is ITextSearchContext))
|
||||
.forEach(context => this._context.set(context.lineNumber, context.text));
|
||||
}
|
||||
|
||||
add(match: Match, trigger?: boolean) {
|
||||
this._matches.set(match.id(), match);
|
||||
if (trigger) {
|
||||
|
@ -479,6 +494,8 @@ export class FolderMatch extends Disposable {
|
|||
.forEach(m => existingFileMatch.add(m));
|
||||
});
|
||||
updated.push(existingFileMatch);
|
||||
|
||||
existingFileMatch.addContext(rawFileMatch.results);
|
||||
} else {
|
||||
const fileMatch = this.instantiationService.createInstance(FileMatch, this._query.contentPattern, this._query.previewOptions, this._query.maxResults, this, rawFileMatch);
|
||||
this.doAdd(fileMatch);
|
||||
|
|
Loading…
Reference in a new issue