mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-02 16:25:00 +01:00
Add re-run search editor search action
This commit is contained in:
@@ -16,6 +16,26 @@
|
||||
"*"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"title": "%searchResult.rerunSearch.title%",
|
||||
"category": "Search Result",
|
||||
"icon": {
|
||||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"editor/title": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"when": "editorLangId == search-result",
|
||||
"group": "navigation"
|
||||
}
|
||||
]
|
||||
},
|
||||
"languages": [
|
||||
{
|
||||
"id": "search-result",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"displayName": "Search Result",
|
||||
"description": "Provides syntax highlighting and language features for tabbed search results."
|
||||
"description": "Provides syntax highlighting and language features for tabbed search results.",
|
||||
"searchResult.rerunSearch.title": "Search Again"
|
||||
}
|
||||
|
||||
@@ -8,12 +8,26 @@ import * as pathUtils from 'path';
|
||||
|
||||
const FILE_LINE_REGEX = /^(\S.*):$/;
|
||||
const RESULT_LINE_REGEX = /^(\s+)(\d+):(\s+)(.*)$/;
|
||||
const LANGUAGE_SELECTOR = { language: 'search-result' };
|
||||
|
||||
let cachedLastParse: { version: number, parse: ParsedSearchResults } | undefined;
|
||||
|
||||
export function activate() {
|
||||
|
||||
vscode.languages.registerDefinitionProvider({ language: 'search-result' }, {
|
||||
vscode.commands.registerCommand('searchResult.rerunSearch', () => vscode.commands.executeCommand('search.action.rerunEditorSearch'));
|
||||
|
||||
vscode.languages.registerCompletionItemProvider(LANGUAGE_SELECTOR, {
|
||||
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||
const line = document.lineAt(position.line);
|
||||
if (line.text.indexOf('# Flags:') === -1) { return []; }
|
||||
|
||||
return ['RegExp', 'CaseSensitive', 'IgnoreExcludeSettings', 'WordMatch']
|
||||
.filter(flag => line.text.indexOf(flag) === -1)
|
||||
.map(flag => ({ label: flag, insertText: flag + ' ' }));
|
||||
}
|
||||
});
|
||||
|
||||
vscode.languages.registerDefinitionProvider(LANGUAGE_SELECTOR, {
|
||||
provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.DefinitionLink[] {
|
||||
const lineResult = parseSearchResults(document, token)[position.line];
|
||||
if (!lineResult) { return []; }
|
||||
@@ -27,7 +41,7 @@ export function activate() {
|
||||
}
|
||||
});
|
||||
|
||||
vscode.languages.registerDocumentLinkProvider({ language: 'search-result' }, {
|
||||
vscode.languages.registerDocumentLinkProvider(LANGUAGE_SELECTOR, {
|
||||
async provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentLink[]> {
|
||||
return parseSearchResults(document, token)
|
||||
.filter(({ type }) => type === 'file')
|
||||
|
||||
4
extensions/search-result/src/media/refresh-dark.svg
Normal file
4
extensions/search-result/src/media/refresh-dark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.56253 2.51577C3.46348 3.4501 2 5.55414 2 7.99999C2 11.3137 4.68629 14 8 14C11.3137 14 14 11.3137 14 7.99999C14 5.32519 12.2497 3.05919 9.83199 2.28482L9.52968 3.23832C11.5429 3.88454 13 5.7721 13 7.99999C13 10.7614 10.7614 13 8 13C5.23858 13 3 10.7614 3 7.99999C3 6.31104 3.83742 4.81767 5.11969 3.91245L5.56253 2.51577Z" fill="#C5C5C5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3H2V2H5.5L6 2.5V6H5V3Z" fill="#C5C5C5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 587 B |
4
extensions/search-result/src/media/refresh-light.svg
Normal file
4
extensions/search-result/src/media/refresh-light.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.56253 2.51577C3.46348 3.4501 2 5.55414 2 7.99999C2 11.3137 4.68629 14 8 14C11.3137 14 14 11.3137 14 7.99999C14 5.32519 12.2497 3.05919 9.83199 2.28482L9.52968 3.23832C11.5429 3.88454 13 5.7721 13 7.99999C13 10.7614 10.7614 13 8 13C5.23858 13 3 10.7614 3 7.99999C3 6.31104 3.83742 4.81767 5.11969 3.91245L5.56253 2.51577Z" fill="#424242"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3H2V2H5.5L6 2.5V6H5V3Z" fill="#424242"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 587 B |
@@ -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 } 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 } 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';
|
||||
@@ -56,6 +56,7 @@ import { ISearchConfiguration, ISearchConfigurationProperties, PANEL_ID, VIEWLET
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { ExplorerViewlet } from 'vs/workbench/contrib/files/browser/explorerViewlet';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
|
||||
registerSingleton(ISearchWorkbenchService, SearchWorkbenchService, true);
|
||||
registerSingleton(ISearchHistoryService, SearchHistoryService, true);
|
||||
@@ -630,6 +631,13 @@ registry.registerWorkbenchAction(
|
||||
'Search: Open Results in Editor', category,
|
||||
ContextKeyExpr.and(Constants.EnableSearchEditorPreview));
|
||||
|
||||
registry.registerWorkbenchAction(
|
||||
SyncActionDescriptor.create(RerunEditorSearchAction, RerunEditorSearchAction.ID, RerunEditorSearchAction.LABEL,
|
||||
{ primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.KEY_R },
|
||||
ContextKeyExpr.and(EditorContextKeys.languageId.isEqualTo('search-result'))),
|
||||
'Search Editor: Search Again', category,
|
||||
ContextKeyExpr.and(EditorContextKeys.languageId.isEqualTo('search-result')));
|
||||
|
||||
|
||||
// Register Quick Open Handler
|
||||
Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen).registerDefaultQuickOpenHandler(
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { ICommandHandler } from 'vs/platform/commands/common/commands';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { getSelectionKeyboardEvent, WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
|
||||
import { SearchView } from 'vs/workbench/contrib/search/browser/searchView';
|
||||
@@ -29,7 +29,9 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { SearchViewlet } from 'vs/workbench/contrib/search/browser/searchViewlet';
|
||||
import { SearchPanel } from 'vs/workbench/contrib/search/browser/searchPanel';
|
||||
import { ITreeNavigator } from 'vs/base/browser/ui/tree/tree';
|
||||
import { createEditorFromSearchResult } from 'vs/workbench/contrib/search/browser/searchEditor';
|
||||
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';
|
||||
|
||||
export function isSearchViewFocused(viewletService: IViewletService, panelService: IPanelService): boolean {
|
||||
const searchView = getSearchView(viewletService, panelService);
|
||||
@@ -451,6 +453,30 @@ export class OpenResultsInEditorAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class RerunEditorSearchAction extends Action {
|
||||
|
||||
static readonly ID: string = Constants.RerunEditorSearchCommandId;
|
||||
static readonly LABEL = nls.localize('search.rerunEditorSearch', "Search Again");
|
||||
|
||||
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
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class FocusNextSearchResultAction extends Action {
|
||||
static readonly ID = 'search.action.focusNextSearchResult';
|
||||
|
||||
@@ -3,25 +3,31 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Match, searchMatchComparer, FileMatch, SearchResult } from 'vs/workbench/contrib/search/common/searchModel';
|
||||
import { Match, searchMatchComparer, FileMatch, SearchResult, SearchModel } from 'vs/workbench/contrib/search/common/searchModel';
|
||||
import { repeat } from 'vs/base/common/strings';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { coalesce, flatten } from 'vs/base/common/arrays';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ITextQuery } from 'vs/workbench/services/search/common/search';
|
||||
import { ITextQuery, IPatternInfo, ISearchConfigurationProperties } from 'vs/workbench/services/search/common/search';
|
||||
import * as network from 'vs/base/common/network';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
|
||||
import { getOutOfWorkspaceEditorResources } from 'vs/workbench/contrib/search/common/search';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
// Using \r\n on Windows inserts an extra newline between results.
|
||||
const lineDelimiter = '\n';
|
||||
|
||||
const translateRangeLines = (n: number) => (range: Range) => new Range(range.startLineNumber + n, range.startColumn, range.endLineNumber + n, range.endColumn);
|
||||
const translateRangeLines =
|
||||
(n: number) =>
|
||||
(range: Range) =>
|
||||
new Range(range.startLineNumber + n, range.startColumn, range.endLineNumber + n, range.endColumn);
|
||||
|
||||
type SearchResultSerialization = { text: string[], matchRanges: Range[] };
|
||||
|
||||
function matchToSearchResultFormat(match: Match): { line: string, ranges: Range[], lineNumber: string }[] {
|
||||
const matchToSearchResultFormat = (match: Match): { line: string, ranges: Range[], lineNumber: string }[] => {
|
||||
const getLinePrefix = (i: number) => `${match.range().startLineNumber + i}`;
|
||||
|
||||
const fullMatchLines = match.fullPreviewLines();
|
||||
@@ -54,8 +60,9 @@ function matchToSearchResultFormat(match: Match): { line: string, ranges: Range[
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
type SearchResultSerialization = { text: string[], matchRanges: Range[] };
|
||||
function fileMatchToSearchResultFormat(fileMatch: FileMatch, labelFormatter: (x: URI) => string): SearchResultSerialization {
|
||||
const serializedMatches = flatten(fileMatch.matches()
|
||||
.sort(searchMatchComparer)
|
||||
@@ -95,7 +102,7 @@ const flattenSearchResultSerializations = (serializations: SearchResultSerializa
|
||||
return { text, matchRanges };
|
||||
};
|
||||
|
||||
function contentPatternToSearchResultHeader(pattern: ITextQuery | null, includes: string, excludes: string): string[] {
|
||||
const contentPatternToSearchResultHeader = (pattern: ITextQuery | null, includes: string, excludes: string): string[] => {
|
||||
if (!pattern) { return []; }
|
||||
|
||||
const removeNullFalseAndUndefined = <T>(a: (T | null | false | undefined)[]) => a.filter(a => a !== false && a !== null && a !== undefined) as T[];
|
||||
@@ -105,29 +112,119 @@ function contentPatternToSearchResultHeader(pattern: ITextQuery | null, includes
|
||||
return removeNullFalseAndUndefined([
|
||||
`# Query: ${escapeNewlines(pattern.contentPattern.pattern)}`,
|
||||
|
||||
(pattern.contentPattern.isCaseSensitive || pattern.contentPattern.isWordMatch || pattern.contentPattern.isRegExp)
|
||||
(pattern.contentPattern.isCaseSensitive || pattern.contentPattern.isWordMatch || pattern.contentPattern.isRegExp || pattern.userDisabledExcludesAndIgnoreFiles)
|
||||
&& `# Flags: ${coalesce([
|
||||
pattern.contentPattern.isCaseSensitive && 'CaseSensitive',
|
||||
pattern.contentPattern.isWordMatch && 'WordMatch',
|
||||
pattern.contentPattern.isRegExp && 'RegExp'
|
||||
pattern.contentPattern.isRegExp && 'RegExp',
|
||||
pattern.userDisabledExcludesAndIgnoreFiles && 'IgnoreExcludeSettings'
|
||||
]).join(' ')}`,
|
||||
includes ? `# Including: ${includes}` : undefined,
|
||||
excludes ? `# Excluding: ${excludes}` : undefined,
|
||||
''
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
const searchHeaderToContentPattern = (header: string[]): { pattern: string, flags: { regex: boolean, wholeWord: boolean, caseSensitive: boolean, ignoreExcludes: boolean }, includes: string, excludes: string } => {
|
||||
const query = {
|
||||
pattern: '',
|
||||
flags: { regex: false, caseSensitive: false, ignoreExcludes: false, wholeWord: false },
|
||||
includes: '',
|
||||
excludes: ''
|
||||
};
|
||||
|
||||
const unescapeNewlines = (str: string) => str.replace(/\\\\/g, '\\').replace(/\\n/g, '\n');
|
||||
const parseYML = /^# ([^:]*): (.*)$/;
|
||||
for (const line of header) {
|
||||
const parsed = parseYML.exec(line);
|
||||
if (!parsed) { continue; }
|
||||
const [, key, value] = parsed;
|
||||
switch (key) {
|
||||
case 'Query': query.pattern = unescapeNewlines(value); break;
|
||||
case 'Including': query.includes = value; break;
|
||||
case 'Excluding': query.excludes = value; break;
|
||||
case 'Flags': {
|
||||
query.flags = {
|
||||
regex: value.indexOf('RegExp') !== -1,
|
||||
caseSensitive: value.indexOf('CaseSensitive') !== -1,
|
||||
ignoreExcludes: value.indexOf('IgnoreExcludeSettings') !== -1,
|
||||
wholeWord: value.indexOf('WordMatch') !== -1
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return query;
|
||||
};
|
||||
|
||||
const serializeSearchResultForEditor = (searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string, labelFormatter: (x: URI) => string): SearchResultSerialization => {
|
||||
const header = contentPatternToSearchResultHeader(searchResult.query, rawIncludePattern, rawExcludePattern);
|
||||
const allResults =
|
||||
flattenSearchResultSerializations(
|
||||
flatten(searchResult.folderMatches()
|
||||
.map(folderMatch => folderMatch.matches()
|
||||
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) => {
|
||||
const model = editorService.activeTextEditorWidget?.getModel();
|
||||
if (!model) { return; }
|
||||
|
||||
const textModel = model as ITextModel;
|
||||
|
||||
const header = textModel.getValueInRange(new Range(1, 1, 5, 1))
|
||||
.split(lineDelimiter)
|
||||
.filter(line => line.indexOf('# ') === 0);
|
||||
|
||||
const contentPattern = searchHeaderToContentPattern(header);
|
||||
|
||||
const content: IPatternInfo = {
|
||||
pattern: contentPattern.pattern,
|
||||
isRegExp: contentPattern.flags.regex,
|
||||
isCaseSensitive: contentPattern.flags.caseSensitive,
|
||||
isWordMatch: contentPattern.flags.wholeWord
|
||||
};
|
||||
|
||||
const options: ITextQueryBuilderOptions = {
|
||||
_reason: 'searchEditor',
|
||||
extraFileResources: instantiationService.invokeFunction(getOutOfWorkspaceEditorResources),
|
||||
maxResults: 10000,
|
||||
disregardIgnoreFiles: contentPattern.flags.ignoreExcludes,
|
||||
disregardExcludeSettings: contentPattern.flags.ignoreExcludes,
|
||||
excludePattern: contentPattern.excludes,
|
||||
includePattern: contentPattern.includes,
|
||||
previewOptions: {
|
||||
matchLines: 1,
|
||||
charsPerLine: 1000
|
||||
},
|
||||
isSmartCase: configurationService.getValue<ISearchConfigurationProperties>('search').smartCase,
|
||||
expandPatterns: true
|
||||
};
|
||||
|
||||
const folderResources = contextService.getWorkspace().folders;
|
||||
|
||||
let query: ITextQuery;
|
||||
try {
|
||||
const queryBuilder = instantiationService.createInstance(QueryBuilder);
|
||||
query = queryBuilder.text(content, folderResources.map(folder => folder.uri), options);
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
const searchModel = instantiationService.createInstance(SearchModel);
|
||||
await searchModel.search(query);
|
||||
|
||||
const labelFormatter = (uri: URI): string => labelService.getUriLabel(uri, { relative: true });
|
||||
const results = serializeSearchResultForEditor(searchModel.searchResult, '', '', labelFormatter);
|
||||
|
||||
textModel.setValue(results.text.join(lineDelimiter));
|
||||
textModel.deltaDecorations([], results.matchRanges.map(range => ({ range, options: { className: 'findMatch', stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges } })));
|
||||
};
|
||||
|
||||
|
||||
export const createEditorFromSearchResult =
|
||||
async (searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string, labelService: ILabelService, editorService: IEditorService) => {
|
||||
const searchTerm = searchResult.query?.contentPattern.pattern.replace(/[^\w-_.]/g, '') || 'Search';
|
||||
@@ -154,5 +251,4 @@ export const createEditorFromSearchResult =
|
||||
const model = control.getModel() as ITextModel;
|
||||
|
||||
model.deltaDecorations([], results.matchRanges.map(range => ({ range, options: { className: 'findMatch', stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges } })));
|
||||
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@ export const CopyPathCommandId = 'search.action.copyPath';
|
||||
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 ClearSearchHistoryCommandId = 'search.action.clearHistory';
|
||||
export const FocusSearchListCommandID = 'search.action.focusSearchList';
|
||||
export const ReplaceActionId = 'search.action.replace';
|
||||
|
||||
Reference in New Issue
Block a user