提交 479d60b6 编写于 作者: J Johannes Rieken

make suggest memories a singleton service, listen to storage change events

上级 6ea1f725
......@@ -198,7 +198,7 @@ export interface ISuggestOptions {
/**
* Enable using global storage for remembering suggestions.
*/
useGlobalStorageForSuggestions?: boolean;
shareSuggestSelections?: boolean;
}
/**
......@@ -1884,7 +1884,7 @@ export class EditorOptionsValidator {
snippets: _stringSet<'top' | 'bottom' | 'inline' | 'none'>(opts.snippetSuggestions, defaults.snippets, ['top', 'bottom', 'inline', 'none']),
snippetsPreventQuickSuggestions: _boolean(suggestOpts.snippetsPreventQuickSuggestions, defaults.filterGraceful),
localityBonus: _boolean(suggestOpts.localityBonus, defaults.localityBonus),
shareSuggestSelections: _boolean(suggestOpts.useGlobalStorageForSuggestions, defaults.shareSuggestSelections)
shareSuggestSelections: _boolean(suggestOpts.shareSuggestSelections, defaults.shareSuggestSelections)
};
}
......
......@@ -17,7 +17,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { CompletionItemProvider, CompletionItemInsertTextRule } from 'vs/editor/common/modes';
import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2';
import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser';
import { SuggestMemories } from 'vs/editor/contrib/suggest/suggestMemory';
import { ISuggestMemories } from 'vs/editor/contrib/suggest/suggestMemory';
import * as nls from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
......@@ -89,7 +89,6 @@ export class SuggestController implements IEditorContribution {
private _model: SuggestModel;
private _widget: SuggestWidget;
private readonly _memory: IdleValue<SuggestMemories>;
private readonly _alternatives: IdleValue<SuggestAlternatives>;
private _toDispose: IDisposable[] = [];
......@@ -98,16 +97,12 @@ export class SuggestController implements IEditorContribution {
constructor(
private _editor: ICodeEditor,
@IEditorWorkerService editorWorker: IEditorWorkerService,
@ISuggestMemories private readonly _memory: ISuggestMemories,
@ICommandService private readonly _commandService: ICommandService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
) {
this._model = new SuggestModel(this._editor, editorWorker);
this._memory = new IdleValue(() => {
let res = _instantiationService.createInstance(SuggestMemories, this._editor);
this._toDispose.push(res);
return res;
});
this._alternatives = new IdleValue(() => {
let res = new SuggestAlternatives(this._editor, this._contextKeyService);
......@@ -125,7 +120,7 @@ export class SuggestController implements IEditorContribution {
}));
this._toDispose.push(this._model.onDidSuggest(e => {
if (!e.shy) {
let index = this._memory.getValue().select(this._editor.getModel(), this._editor.getPosition(), e.completionModel.items);
let index = this._memory.select(this._editor.getModel(), this._editor.getPosition(), e.completionModel.items);
this._widget.showSuggestions(e.completionModel, index, e.isFrozen, e.auto);
}
}));
......@@ -236,7 +231,7 @@ export class SuggestController implements IEditorContribution {
}
// keep item in memory
this._memory.getValue().memorize(model, this._editor.getPosition(), event.item);
this._memory.memorize(model, this._editor.getPosition(), event.item);
let { insertText } = suggestion;
if (!(suggestion.insertTextRules & CompletionItemInsertTextRule.InsertAsSnippet)) {
......@@ -349,7 +344,7 @@ export class SuggestController implements IEditorContribution {
fallback();
return;
}
const index = this._memory.getValue().select(this._editor.getModel(), this._editor.getPosition(), completionModel.items);
const index = this._memory.select(this._editor.getModel(), this._editor.getPosition(), completionModel.items);
const item = completionModel.items[index];
if (!makesTextEdit(item)) {
fallback();
......
......@@ -9,9 +9,11 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
import { ITextModel } from 'vs/editor/common/model';
import { IPosition } from 'vs/editor/common/core/position';
import { CompletionItemKind, completionKindFromLegacyString } from 'vs/editor/common/modes';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { Disposable } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export abstract class Memory {
......@@ -194,35 +196,56 @@ export class PrefixMemory extends Memory {
export type MemMode = 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix';
export class SuggestMemories extends Disposable {
class SuggestMemories extends Disposable implements ISuggestMemories {
readonly _serviceBrand: any;
private readonly _storagePrefix = 'suggest/memories';
private readonly _persistSoon: RunOnceScheduler;
private _mode: MemMode;
private _shareMem: boolean;
private _strategy: Memory;
private readonly _persistSoon: RunOnceScheduler;
constructor(
editor: ICodeEditor,
@IStorageService private readonly _storageService: IStorageService,
@IConfigurationService private readonly _configService: IConfigurationService,
) {
super();
this._persistSoon = this._register(new RunOnceScheduler(() => this._saveState(editor.getConfiguration().contribInfo.suggest.shareSuggestSelections), 3000));
this._setMode(editor.getConfiguration().contribInfo.suggestSelection, editor.getConfiguration().contribInfo.suggest.shareSuggestSelections);
this._register(editor.onDidChangeConfiguration(e => e.contribInfo && this._setMode(editor.getConfiguration().contribInfo.suggestSelection, editor.getConfiguration().contribInfo.suggest.shareSuggestSelections)));
this._register(_storageService.onWillSaveState(() => this._saveState(editor.getConfiguration().contribInfo.suggest.shareSuggestSelections)));
const update = () => {
const mode = this._configService.getValue<MemMode>('editor.suggestSelection');
const share = this._configService.getValue<boolean>('editor.suggest.shareSuggestSelections');
this._update(mode, share);
};
this._persistSoon = this._register(new RunOnceScheduler(() => this._saveState(), 3000));
this._register(_storageService.onWillSaveState(() => this._saveState()));
this._register(this._configService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('editor.suggestSelection') || e.affectsConfiguration('editor.suggest.shareSuggestSelections')) {
update();
}
}));
this._register(this._storageService.onDidChangeStorage(e => {
if (e.scope === StorageScope.GLOBAL && e.key.indexOf(this._storagePrefix) === 0) {
update();
}
}));
update();
}
private _setMode(mode: MemMode, useGlobalStorageForSuggestions: boolean): void {
if (this._mode === mode) {
private _update(mode: MemMode, shareMem: boolean): void {
if (this._mode === mode && this._shareMem === shareMem) {
return;
}
this._shareMem = shareMem;
this._mode = mode;
this._strategy = mode === 'recentlyUsedByPrefix' ? new PrefixMemory() : mode === 'recentlyUsed' ? new LRUMemory() : new NoMemory();
try {
const raw = useGlobalStorageForSuggestions ? this._storageService.get(`${this._storagePrefix}/${this._mode}`, StorageScope.GLOBAL) : this._storageService.get(`${this._storagePrefix}/${this._mode}`, StorageScope.WORKSPACE);
const scope = shareMem ? StorageScope.GLOBAL : StorageScope.WORKSPACE;
const raw = this._storageService.get(`${this._storagePrefix}/${this._mode}`, scope);
if (raw) {
this._strategy.fromJSON(JSON.parse(raw));
}
......@@ -240,8 +263,20 @@ export class SuggestMemories extends Disposable {
return this._strategy.select(model, pos, items);
}
private _saveState(useGlobalStorageForSuggestions: boolean) {
private _saveState() {
const raw = JSON.stringify(this._strategy);
this._storageService.store(`${this._storagePrefix}/${this._mode}`, raw, useGlobalStorageForSuggestions ? StorageScope.GLOBAL : StorageScope.WORKSPACE);
const scope = this._shareMem ? StorageScope.GLOBAL : StorageScope.WORKSPACE;
this._storageService.store(`${this._storagePrefix}/${this._mode}`, raw, scope);
}
}
export const ISuggestMemories = createDecorator<ISuggestMemories>('ISuggestMemories');
export interface ISuggestMemories {
_serviceBrand: any;
memorize(model: ITextModel, pos: IPosition, item: ICompletionItem): void;
select(model: ITextModel, pos: IPosition, items: ICompletionItem[]): number;
}
registerSingleton(ISuggestMemories, SuggestMemories, true);
......@@ -2561,7 +2561,7 @@ declare namespace monaco.editor {
/**
* Enable using global storage for remembering suggestions.
*/
useGlobalStorageForSuggestions?: boolean;
shareSuggestSelections?: boolean;
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册