diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index c88206bb4ddd115aadf5033c04562e036c889894..0d8811435883e5d8627dc3867541651e90adca42 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -780,7 +780,26 @@ const editorConfiguration: IConfigurationNode = { 'description': nls.localize('emptySelectionClipboard', "Controls whether copying without a selection copies the current line.") }, 'editor.wordBasedSuggestions': { - 'type': 'boolean', + 'anyOf': [ + 'boolean', + { + type: 'object', + properties: { + strings: { + type: 'boolean', + description: nls.localize('wordBasedSuggestions.strings', "Enable word based suggestions inside strings.") + }, + comments: { + type: 'boolean', + description: nls.localize('wordBasedSuggestions.comments', "Enable word based suggestions inside comments.") + }, + default: { + type: 'boolean', + description: nls.localize('wordBasedSuggestions.default', "Enable word based suggestions outside of strings and comments.") + }, + } + } + ], 'default': DefaultConfig.editor.wordBasedSuggestions, 'description': nls.localize('wordBasedSuggestions', "Enable word based suggestions.") }, diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 7c0c73ca0c452fcf5f8b5f92c37fbdbe46d04c9f..da83d7574fc3719fb7a256f36ec0bcbd80651b74 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -7,6 +7,7 @@ import { BulkListenerCallback } from 'vs/base/common/eventEmitter'; import { MarkedString } from 'vs/base/common/htmlContent'; import * as types from 'vs/base/common/types'; +import * as objects from 'vs/base/common/objects'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { ServicesAccessor, IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation'; @@ -481,7 +482,7 @@ export interface IEditorOptions { /** * Enable word based suggestions. Defaults to 'true' */ - wordBasedSuggestions?: boolean; + wordBasedSuggestions?: boolean | { strings?: boolean, comments?: boolean, default?: boolean }; /** * The font size for the suggest widget. * Defaults to the editor font size. @@ -1015,7 +1016,7 @@ export class EditorContribOptions { readonly acceptSuggestionOnCommitCharacter: boolean; readonly snippetSuggestions: 'top' | 'bottom' | 'inline' | 'none'; readonly emptySelectionClipboard: boolean; - readonly wordBasedSuggestions: boolean; + readonly wordBasedSuggestions: boolean | { strings?: boolean, comments?: boolean, default?: boolean }; readonly suggestFontSize: number; readonly suggestLineHeight: number; readonly selectionHighlight: boolean; @@ -1042,7 +1043,7 @@ export class EditorContribOptions { acceptSuggestionOnCommitCharacter: boolean; snippetSuggestions: 'top' | 'bottom' | 'inline' | 'none'; emptySelectionClipboard: boolean; - wordBasedSuggestions: boolean; + wordBasedSuggestions: boolean | { strings?: boolean, comments?: boolean, default?: boolean }; suggestFontSize: number; suggestLineHeight: number; selectionHighlight: boolean; @@ -1094,7 +1095,7 @@ export class EditorContribOptions { && this.acceptSuggestionOnCommitCharacter === other.acceptSuggestionOnCommitCharacter && this.snippetSuggestions === other.snippetSuggestions && this.emptySelectionClipboard === other.emptySelectionClipboard - && this.wordBasedSuggestions === other.wordBasedSuggestions + && objects.equals(this.wordBasedSuggestions, other.wordBasedSuggestions) && this.suggestFontSize === other.suggestFontSize && this.suggestLineHeight === other.suggestLineHeight && this.selectionHighlight === other.selectionHighlight diff --git a/src/vs/editor/common/services/editorWorkerServiceImpl.ts b/src/vs/editor/common/services/editorWorkerServiceImpl.ts index e6ab63a9375e8fa25c9797dfdb473907dca43e89..08f740fbc40965632db65183457a06f018a10cc4 100644 --- a/src/vs/editor/common/services/editorWorkerServiceImpl.ts +++ b/src/vs/editor/common/services/editorWorkerServiceImpl.ts @@ -77,27 +77,6 @@ export class EditorWorkerServiceImpl implements IEditorWorkerService { } } -class WordBasedCompletionConfig { - - static fromOldConfig(value: boolean): WordBasedCompletionConfig { - return new WordBasedCompletionConfig(value, value, value); - } - - constructor( - readonly suggestInStrings: boolean, - readonly suggestInComments: boolean, - readonly suggestInCode: boolean - ) { - - } - - accept(tokenType: modes.StandardTokenType): boolean { - return (tokenType === modes.StandardTokenType.String && this.suggestInStrings) - || (tokenType === modes.StandardTokenType.Comment && this.suggestInComments) - || (tokenType === modes.StandardTokenType.Other && this.suggestInCode); - } -} - class WordBasedCompletionItemProvider implements modes.ISuggestSupport { private readonly _workerManager: WorkerManager; @@ -110,16 +89,29 @@ class WordBasedCompletionItemProvider implements modes.ISuggestSupport { provideCompletionItems(model: editorCommon.IModel, position: Position): TPromise { - // TODO(joh) should we force tokenization? - // model.forceTokenization(position.lineNumber); - const config = WordBasedCompletionConfig.fromOldConfig(this._configurationService.lookup('editor.wordBasedSuggestions').value); - const tokens = model.getLineTokens(position.lineNumber); - const { tokenType } = tokens.findTokenAtOffset(position.column - 1); + const { wordBasedSuggestions } = this._configurationService.getConfiguration('editor'); + + if (wordBasedSuggestions === false) { + // simple -> disabled everywhere + return undefined; - if (config.accept(tokenType)) { + } else if (wordBasedSuggestions === true) { + // simple -> enabled for all tokens return this._workerManager.withWorker().then(client => client.textualSuggest(model.uri, position)); + } else { - return undefined; + // check with token type and config + const tokens = model.getLineTokens(position.lineNumber); + const { tokenType } = tokens.findTokenAtOffset(position.column - 1); + const shoudSuggestHere = (tokenType === modes.StandardTokenType.Comment && wordBasedSuggestions.comments) + || (tokenType === modes.StandardTokenType.String && wordBasedSuggestions.strings) + || (tokenType === modes.StandardTokenType.Other && wordBasedSuggestions.default); + + if (shoudSuggestHere) { + return this._workerManager.withWorker().then(client => client.textualSuggest(model.uri, position)); + } else { + return undefined; + } } } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e1424651bb5fa299e517d521a5daa86fd46e7d0c..772fa0233e229e5583a34c2ecbe97c142f26c9ab 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1397,7 +1397,11 @@ declare module monaco.editor { /** * Enable word based suggestions. Defaults to 'true' */ - wordBasedSuggestions?: boolean; + wordBasedSuggestions?: boolean | { + strings?: boolean; + comments?: boolean; + default?: boolean; + }; /** * The font size for the suggest widget. * Defaults to the editor font size. @@ -1619,7 +1623,11 @@ declare module monaco.editor { readonly acceptSuggestionOnCommitCharacter: boolean; readonly snippetSuggestions: 'top' | 'bottom' | 'inline' | 'none'; readonly emptySelectionClipboard: boolean; - readonly wordBasedSuggestions: boolean; + readonly wordBasedSuggestions: boolean | { + strings?: boolean; + comments?: boolean; + default?: boolean; + }; readonly suggestFontSize: number; readonly suggestLineHeight: number; readonly selectionHighlight: boolean;