Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackson Kearl <jakearl@microsoft.com>2020-05-29 00:59:15 +0300
committerJackson Kearl <jakearl@microsoft.com>2020-05-29 00:59:25 +0300
commit1a547aaaee6103c2550daf3178a79ecf59d3e055 (patch)
tree34427dfdbf455d0a7adea15ad3f913fc1d2ace51
parenteec3db0bf3027c1aeea19ed6083d7cf3fae9d67f (diff)
Fixes #98639 - Search editor: resolves content even if not the active editor
-rw-r--r--src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts56
-rw-r--r--src/vs/workbench/contrib/searchEditor/browser/searchEditorModel.ts65
2 files changed, 80 insertions, 41 deletions
diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts
index 59a80ce0c51..b91adcb6cde 100644
--- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts
+++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts
@@ -10,9 +10,8 @@ import { extname, isEqual, joinPath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import 'vs/css!./media/searchEditor';
import { Range } from 'vs/editor/common/core/range';
-import { DefaultEndOfLine, ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model';
+import { ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model';
import { IModelService } from 'vs/editor/common/services/modelService';
-import { IModeService } from 'vs/editor/common/services/modeService';
import { localize } from 'vs/nls';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
@@ -23,16 +22,15 @@ import { EditorInput, GroupIdentifier, IEditorInput, IMoveResult, IRevertOptions
import { Memento } from 'vs/workbench/common/memento';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { SearchEditorFindMatchClass, SearchEditorScheme } from 'vs/workbench/contrib/searchEditor/browser/constants';
+import { SearchEditorModel } from 'vs/workbench/contrib/searchEditor/browser/searchEditorModel';
import { defaultSearchConfig, extractSearchQueryFromModel, parseSavedSearchEditor, serializeSearchConfiguration } from 'vs/workbench/contrib/searchEditor/browser/searchEditorSerialization';
-import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { ISearchConfigurationProperties } from 'vs/workbench/services/search/common/search';
-import { ITextFileSaveOptions, ITextFileService, snapshotToString, stringToSnapshot } from 'vs/workbench/services/textfile/common/textfiles';
+import { ITextFileSaveOptions, ITextFileService, stringToSnapshot } from 'vs/workbench/services/textfile/common/textfiles';
import { IWorkingCopy, IWorkingCopyBackup, IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService';
-
export type SearchConfiguration = {
query: string,
includes: string,
@@ -53,7 +51,10 @@ export class SearchEditorInput extends EditorInput {
private memento: Memento;
private dirty: boolean = false;
- private model: Promise<ITextModel>;
+ private get model(): Promise<ITextModel> {
+ return this.searchEditorModel.resolve();
+ }
+
private _cachedModel: ITextModel | undefined;
private readonly _onDidChangeContent = this._register(new Emitter<void>());
@@ -76,8 +77,7 @@ export class SearchEditorInput extends EditorInput {
constructor(
public readonly modelUri: URI,
public readonly backingUri: URI | undefined,
- config: Readonly<SearchConfiguration>,
- getModel: () => Promise<ITextModel>,
+ private searchEditorModel: SearchEditorModel,
@IModelService private readonly modelService: IModelService,
@ITextFileService protected readonly textFileService: ITextFileService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@@ -91,13 +91,12 @@ export class SearchEditorInput extends EditorInput {
) {
super();
- this._config = config;
- this.model = getModel()
+ this._config = searchEditorModel.config;
+ searchEditorModel.onModelResolved
.then(model => {
this._register(model.onDidChangeContent(() => this._onDidChangeContent.fire()));
this._register(model);
this._cachedModel = model;
- return model;
});
if (this.modelUri.scheme !== SearchEditorScheme) {
@@ -250,12 +249,11 @@ export class SearchEditorInput extends EditorInput {
}
async setMatchRanges(ranges: Range[]) {
- this.oldDecorationsIDs = (await this.model).deltaDecorations(this.oldDecorationsIDs, ranges.map(range =>
+ this.oldDecorationsIDs = (await this.searchEditorModel.onModelResolved).deltaDecorations(this.oldDecorationsIDs, ranges.map(range =>
({ range, options: { className: SearchEditorFindMatchClass, stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges } })));
}
async revert(group: GroupIdentifier, options?: IRevertOptions) {
- // TODO: this should actually revert the contents. But it needs to set dirty false.
if (this.backingUri) {
const { config, text } = await this.instantiationService.invokeFunction(parseSavedSearchEditor, this.backingUri);
(await this.model).setValue(text);
@@ -298,16 +296,13 @@ export const getOrMakeSearchEditorInput = (
): SearchEditorInput => {
const instantiationService = accessor.get(IInstantiationService);
- const modelService = accessor.get(IModelService);
- const backupService = accessor.get(IBackupFileService);
- const modeService = accessor.get(IModeService);
const storageService = accessor.get(IStorageService);
const configurationService = accessor.get(IConfigurationService);
const searchEditorSettings = configurationService.getValue<ISearchConfigurationProperties>('search').searchEditor;
- const reuseOldSettings = searchEditorSettings?.reusePriorSearchConfiguration;
- const defaultShowContextValue = searchEditorSettings?.defaultShowContextValue;
+ const reuseOldSettings = searchEditorSettings.reusePriorSearchConfiguration;
+ const defaultShowContextValue = searchEditorSettings.defaultShowContextValue;
const priorConfig: SearchConfiguration = reuseOldSettings ? new Memento(SearchEditorInput.ID, storageService).getMemento(StorageScope.WORKSPACE).searchConfig : {};
const defaultConfig = defaultSearchConfig();
@@ -326,29 +321,8 @@ export const getOrMakeSearchEditorInput = (
return existing;
}
- const getModel = async () => {
- let contents: string;
-
- const backup = await backupService.resolve(modelUri);
- if (backup) {
- // this way of stringifying a TextBufferFactory seems needlessly complicated...
- contents = snapshotToString(backup.value.create(DefaultEndOfLine.LF).createSnapshot(true));
- } else if (existingData.text !== undefined) {
- contents = existingData.text;
- } else if (existingData.backingUri !== undefined) {
- const { text } = await instantiationService.invokeFunction(parseSavedSearchEditor, existingData.backingUri);
- contents = text;
- } else if (config !== undefined) {
- contents = '';
- } else {
- throw new Error('no initial contents for search editor');
- }
- backupService.discardBackup(modelUri);
-
- return modelService.getModel(modelUri) ?? modelService.createModel(contents, modeService.create('search-result'), modelUri);
- };
-
- const input = instantiationService.createInstance(SearchEditorInput, modelUri, existingData.backingUri, config, getModel);
+ const model = instantiationService.createInstance(SearchEditorModel, modelUri, config, existingData);
+ const input = instantiationService.createInstance(SearchEditorInput, modelUri, existingData.backingUri, model);
inputs.set(cacheKey, input);
input.onDispose(() => inputs.delete(cacheKey));
diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorModel.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorModel.ts
new file mode 100644
index 00000000000..fd868994e08
--- /dev/null
+++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorModel.ts
@@ -0,0 +1,65 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { URI } from 'vs/base/common/uri';
+import { ITextModel } from 'vs/editor/common/model';
+import { IModelService } from 'vs/editor/common/services/modelService';
+import { IModeService } from 'vs/editor/common/services/modeService';
+import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
+import { parseSavedSearchEditor } from 'vs/workbench/contrib/searchEditor/browser/searchEditorSerialization';
+import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
+import { SearchConfiguration } from './searchEditorInput';
+import { assertIsDefined } from 'vs/base/common/types';
+
+
+export class SearchEditorModel {
+ private cachedContentsModel: ITextModel | undefined = undefined;
+ private resolveContents!: (model: ITextModel) => void;
+ public onModelResolved: Promise<ITextModel>;
+
+ private ongoingResolve = Promise.resolve<any>(undefined);
+
+ constructor(
+ private modelUri: URI,
+ public config: SearchConfiguration,
+ private existingData: ({ config: Partial<SearchConfiguration>; backingUri?: URI; } &
+ ({ modelUri: URI; text?: never; } |
+ { text: string; modelUri?: never; } |
+ { backingUri: URI; text?: never; modelUri?: never; })),
+ @IInstantiationService private readonly instantiationService: IInstantiationService,
+ @IBackupFileService readonly backupService: IBackupFileService,
+ @IModelService private readonly modelService: IModelService,
+ @IModeService private readonly modeService: IModeService) {
+ this.onModelResolved = new Promise<ITextModel>(resolve => this.resolveContents = resolve);
+ this.onModelResolved.then(model => this.cachedContentsModel = model);
+ this.ongoingResolve = backupService.resolve(modelUri)
+ .then(backup => modelService.getModel(modelUri) ?? (backup ? modelService.createModel(backup.value, modeService.create('search-result'), modelUri) : undefined))
+ .then(model => { if (model) { this.resolveContents(model); } });
+ }
+
+ async resolve(): Promise<ITextModel> {
+ await (this.ongoingResolve = this.ongoingResolve.then(() => this.cachedContentsModel || this.createModel()));
+ return assertIsDefined(this.cachedContentsModel);
+ }
+
+ private async createModel() {
+ const getContents = async () => {
+ if (this.existingData.text !== undefined) {
+ return this.existingData.text;
+ }
+ else if (this.existingData.backingUri !== undefined) {
+ return (await this.instantiationService.invokeFunction(parseSavedSearchEditor, this.existingData.backingUri)).text;
+ }
+ else {
+ return '';
+ }
+ };
+
+ const contents = await getContents();
+ const model = this.modelService.getModel(this.modelUri) ?? this.modelService.createModel(contents, this.modeService.create('search-result'), this.modelUri);
+ this.resolveContents(model);
+ return model;
+ }
+}