提交 70a9b8b2 编写于 作者: J Jackson Kearl

Add experimental setting to reuse prior search config. Ref #89353.

上级 945ee295
...@@ -14,17 +14,21 @@ import { DefaultEndOfLine, ITextModel, TrackedRangeStickiness } from 'vs/editor/ ...@@ -14,17 +14,21 @@ import { DefaultEndOfLine, ITextModel, TrackedRangeStickiness } from 'vs/editor/
import { IModelService } from 'vs/editor/common/services/modelService'; import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService'; import { IModeService } from 'vs/editor/common/services/modeService';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { EditorInput, GroupIdentifier, IEditorInput, IMoveResult, IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor'; import { EditorInput, GroupIdentifier, IEditorInput, IMoveResult, IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor';
import { Memento } from 'vs/workbench/common/memento';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { SearchEditorFindMatchClass, SearchEditorScheme } from 'vs/workbench/contrib/searchEditor/browser/constants'; import { SearchEditorFindMatchClass, SearchEditorScheme } from 'vs/workbench/contrib/searchEditor/browser/constants';
import { extractSearchQueryFromModel, parseSavedSearchEditor, serializeSearchConfiguration } from 'vs/workbench/contrib/searchEditor/browser/searchEditorSerialization'; import { defaultSearchConfig, extractSearchQueryFromModel, parseSavedSearchEditor, serializeSearchConfiguration } from 'vs/workbench/contrib/searchEditor/browser/searchEditorSerialization';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService'; import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService';
import { ISearchConfigurationProperties } from 'vs/workbench/services/search/common/search';
import { ITextFileSaveOptions, ITextFileService, snapshotToString, stringToSnapshot } from 'vs/workbench/services/textfile/common/textfiles'; import { ITextFileSaveOptions, ITextFileService, snapshotToString, stringToSnapshot } from 'vs/workbench/services/textfile/common/textfiles';
import { IWorkingCopy, IWorkingCopyBackup, IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IWorkingCopy, IWorkingCopyBackup, IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService';
...@@ -46,6 +50,8 @@ const SEARCH_EDITOR_EXT = '.code-search'; ...@@ -46,6 +50,8 @@ const SEARCH_EDITOR_EXT = '.code-search';
export class SearchEditorInput extends EditorInput { export class SearchEditorInput extends EditorInput {
static readonly ID: string = 'workbench.editorinputs.searchEditorInput'; static readonly ID: string = 'workbench.editorinputs.searchEditorInput';
private memento: Memento;
private dirty: boolean = false; private dirty: boolean = false;
private model: Promise<ITextModel>; private model: Promise<ITextModel>;
private _cachedModel: ITextModel | undefined; private _cachedModel: ITextModel | undefined;
...@@ -57,7 +63,11 @@ export class SearchEditorInput extends EditorInput { ...@@ -57,7 +63,11 @@ export class SearchEditorInput extends EditorInput {
private _config: Readonly<SearchConfiguration>; private _config: Readonly<SearchConfiguration>;
public get config(): Readonly<SearchConfiguration> { return this._config; } public get config(): Readonly<SearchConfiguration> { return this._config; }
public set config(value: Readonly<SearchConfiguration>) { this._config = value; this._onDidChangeLabel.fire(); } public set config(value: Readonly<SearchConfiguration>) {
this._config = value;
this.memento.getMemento(StorageScope.WORKSPACE).searchConfig = value;
this._onDidChangeLabel.fire();
}
get resource() { get resource() {
return this.backingUri || this.modelUri; return this.backingUri || this.modelUri;
...@@ -76,7 +86,8 @@ export class SearchEditorInput extends EditorInput { ...@@ -76,7 +86,8 @@ export class SearchEditorInput extends EditorInput {
@IWorkingCopyService private readonly workingCopyService: IWorkingCopyService, @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService,
@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService, @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService,
@ITelemetryService private readonly telemetryService: ITelemetryService, @ITelemetryService private readonly telemetryService: ITelemetryService,
@IRemotePathService private readonly remotePathService: IRemotePathService @IRemotePathService private readonly remotePathService: IRemotePathService,
@IStorageService storageService: IStorageService,
) { ) {
super(); super();
...@@ -93,6 +104,9 @@ export class SearchEditorInput extends EditorInput { ...@@ -93,6 +104,9 @@ export class SearchEditorInput extends EditorInput {
throw Error('SearchEditorInput must be invoked with a SearchEditorScheme uri'); throw Error('SearchEditorInput must be invoked with a SearchEditorScheme uri');
} }
this.memento = new Memento(SearchEditorInput.ID, storageService);
storageService.onWillSaveState(() => this.memento.saveMemento());
const input = this; const input = this;
const workingCopyAdapter = new class implements IWorkingCopy { const workingCopyAdapter = new class implements IWorkingCopy {
readonly resource = input.modelUri; readonly resource = input.modelUri;
...@@ -283,15 +297,20 @@ export const getOrMakeSearchEditorInput = ( ...@@ -283,15 +297,20 @@ export const getOrMakeSearchEditorInput = (
{ backingUri: URI, text?: never, modelUri?: never })) { backingUri: URI, text?: never, modelUri?: never }))
): SearchEditorInput => { ): SearchEditorInput => {
const defaultConfig: SearchConfiguration = { caseSensitive: false, contextLines: 0, excludes: '', includes: '', query: '', regexp: false, showIncludesExcludes: false, useIgnores: true, wholeWord: false };
let config = { ...defaultConfig, ...existingData.config };
const modelUri = existingData.modelUri ?? URI.from({ scheme: SearchEditorScheme, fragment: `${Math.random()}` });
const instantiationService = accessor.get(IInstantiationService); const instantiationService = accessor.get(IInstantiationService);
const modelService = accessor.get(IModelService); const modelService = accessor.get(IModelService);
const backupService = accessor.get(IBackupFileService); const backupService = accessor.get(IBackupFileService);
const modeService = accessor.get(IModeService); const modeService = accessor.get(IModeService);
const storageService = accessor.get(IStorageService);
const configurationService = accessor.get(IConfigurationService);
const reuseOldSettings = configurationService.getValue<ISearchConfigurationProperties>('search').searchEditor?.experimental?.reusePriorSearchConfiguration;
const priorConfig: SearchConfiguration = reuseOldSettings ? new Memento(SearchEditorInput.ID, storageService).getMemento(StorageScope.WORKSPACE).searchConfig : {};
const defaultConfig = defaultSearchConfig();
let config = { ...defaultConfig, ...priorConfig, ...existingData.config };
const modelUri = existingData.modelUri ?? URI.from({ scheme: SearchEditorScheme, fragment: `${Math.random()}` });
const existing = inputs.get(modelUri.toString() + existingData.backingUri?.toString()); const existing = inputs.get(modelUri.toString() + existingData.backingUri?.toString());
if (existing) { if (existing) {
......
...@@ -106,15 +106,15 @@ function fileMatchToSearchResultFormat(fileMatch: FileMatch, labelFormatter: (x: ...@@ -106,15 +106,15 @@ function fileMatchToSearchResultFormat(fileMatch: FileMatch, labelFormatter: (x:
return { text, matchRanges }; return { text, matchRanges };
} }
const contentPatternToSearchConfiguration = (pattern: ITextQuery | null, includes: string, excludes: string, contextLines: number): Partial<SearchConfiguration> => { const contentPatternToSearchConfiguration = (pattern: ITextQuery, includes: string, excludes: string, contextLines: number): SearchConfiguration => {
return { return {
query: pattern?.contentPattern.pattern, query: pattern.contentPattern.pattern,
regexp: pattern?.contentPattern.isRegExp, regexp: !!pattern.contentPattern.isRegExp,
caseSensitive: pattern?.contentPattern.isCaseSensitive, caseSensitive: !!pattern.contentPattern.isCaseSensitive,
wholeWord: pattern?.contentPattern.isWordMatch, wholeWord: !!pattern.contentPattern.isWordMatch,
excludes, includes, excludes, includes,
showIncludesExcludes: !!(includes || excludes || pattern?.userDisabledExcludesAndIgnoreFiles), showIncludesExcludes: !!(includes || excludes || pattern?.userDisabledExcludesAndIgnoreFiles),
useIgnores: pattern?.userDisabledExcludesAndIgnoreFiles === undefined ? undefined : !pattern.userDisabledExcludesAndIgnoreFiles, useIgnores: !!(pattern?.userDisabledExcludesAndIgnoreFiles === undefined ? undefined : !pattern.userDisabledExcludesAndIgnoreFiles),
contextLines, contextLines,
}; };
}; };
...@@ -144,19 +144,21 @@ export const serializeSearchConfiguration = (config: Partial<SearchConfiguration ...@@ -144,19 +144,21 @@ export const serializeSearchConfiguration = (config: Partial<SearchConfiguration
export const extractSearchQueryFromModel = (model: ITextModel): SearchConfiguration => export const extractSearchQueryFromModel = (model: ITextModel): SearchConfiguration =>
extractSearchQueryFromLines(model.getValueInRange(new Range(1, 1, 6, 1)).split(lineDelimiter)); extractSearchQueryFromLines(model.getValueInRange(new Range(1, 1, 6, 1)).split(lineDelimiter));
export const defaultSearchConfig = (): SearchConfiguration => ({
query: '',
includes: '',
excludes: '',
regexp: false,
caseSensitive: false,
useIgnores: true,
wholeWord: false,
contextLines: 0,
showIncludesExcludes: false,
});
export const extractSearchQueryFromLines = (lines: string[]): SearchConfiguration => { export const extractSearchQueryFromLines = (lines: string[]): SearchConfiguration => {
const query: SearchConfiguration = { const query = defaultSearchConfig();
query: '',
includes: '',
excludes: '',
regexp: false,
caseSensitive: false,
useIgnores: true,
wholeWord: false,
contextLines: 0,
showIncludesExcludes: false,
};
const unescapeNewlines = (str: string) => { const unescapeNewlines = (str: string) => {
let out = ''; let out = '';
...@@ -207,6 +209,7 @@ export const extractSearchQueryFromLines = (lines: string[]): SearchConfiguratio ...@@ -207,6 +209,7 @@ export const extractSearchQueryFromLines = (lines: string[]): SearchConfiguratio
export const serializeSearchResultForEditor = export const serializeSearchResultForEditor =
(searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string, contextLines: number, labelFormatter: (x: URI) => string): { matchRanges: Range[], text: string, config: Partial<SearchConfiguration> } => { (searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string, contextLines: number, labelFormatter: (x: URI) => string): { matchRanges: Range[], text: string, config: Partial<SearchConfiguration> } => {
if (!searchResult.query) { throw Error('Internal Error: Expected query, got null'); }
const config = contentPatternToSearchConfiguration(searchResult.query, rawIncludePattern, rawExcludePattern, contextLines); const config = contentPatternToSearchConfiguration(searchResult.query, rawIncludePattern, rawExcludePattern, contextLines);
const filecount = searchResult.fileCount() > 1 ? localize('numFiles', "{0} files", searchResult.fileCount()) : localize('oneFile', "1 file"); const filecount = searchResult.fileCount() > 1 ? localize('numFiles', "{0} files", searchResult.fileCount()) : localize('oneFile', "1 file");
......
...@@ -345,7 +345,10 @@ export interface ISearchConfigurationProperties { ...@@ -345,7 +345,10 @@ export interface ISearchConfigurationProperties {
collapseResults: 'auto' | 'alwaysCollapse' | 'alwaysExpand'; collapseResults: 'auto' | 'alwaysCollapse' | 'alwaysExpand';
searchOnType: boolean; searchOnType: boolean;
searchOnTypeDebouncePeriod: number; searchOnTypeDebouncePeriod: number;
searchEditor: { doubleClickBehaviour: 'selectWord' | 'goToLocation' | 'openLocationToSide' }; searchEditor: {
doubleClickBehaviour: 'selectWord' | 'goToLocation' | 'openLocationToSide',
experimental: { reusePriorSearchConfiguration: boolean }
};
sortOrder: SearchSortOrder; sortOrder: SearchSortOrder;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册