diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index cc6f7e769fdd2..607a21568943b 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -301,7 +301,7 @@ class InternalEditorOptionsHelper { selectionClipboard: toBoolean(opts.selectionClipboard), hover: toBoolean(opts.hover), contextmenu: toBoolean(opts.contextmenu), - quickSuggestions: toBoolean(opts.quickSuggestions), + quickSuggestions: typeof opts.quickSuggestions === 'object' ? { other: true, ...opts.quickSuggestions } : toBoolean(opts.quickSuggestions), quickSuggestionsDelay: toInteger(opts.quickSuggestionsDelay), parameterHints: toBoolean(opts.parameterHints), iconsInSuggestions: toBoolean(opts.iconsInSuggestions), @@ -723,9 +723,31 @@ const editorConfiguration: IConfigurationNode = { 'description': nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events") }, 'editor.quickSuggestions': { - 'type': 'boolean', + 'anyOf': [ + 'boolean', + { + type: 'object', + properties: { + strings: { + type: 'boolean', + default: false, + description: nls.localize('quickSuggestions.strings', "Enable quick suggestions inside strings.") + }, + comments: { + type: 'boolean', + default: false, + description: nls.localize('quickSuggestions.comments', "Enable quick suggestions inside comments.") + }, + other: { + type: 'boolean', + default: true, + description: nls.localize('quickSuggestions.other', "Enable quick suggestions outside of strings and comments.") + }, + } + } + ], 'default': DefaultConfig.editor.quickSuggestions, - 'description': nls.localize('quickSuggestions', "Controls if quick suggestions should show up or not while typing") + 'description': nls.localize('quickSuggestions', "Controls if suggestions should automatically show up while typing") }, 'editor.quickSuggestionsDelay': { 'type': 'integer', diff --git a/src/vs/editor/common/config/defaultConfig.ts b/src/vs/editor/common/config/defaultConfig.ts index e8faee7136ea2..8c178305c52e1 100644 --- a/src/vs/editor/common/config/defaultConfig.ts +++ b/src/vs/editor/common/config/defaultConfig.ts @@ -86,7 +86,7 @@ class ConfigClass implements IConfiguration { hover: true, contextmenu: true, mouseWheelScrollSensitivity: 1, - quickSuggestions: true, + quickSuggestions: { other: true, comments: false, strings: false }, quickSuggestionsDelay: 10, parameterHints: true, iconsInSuggestions: true, diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 3c742c911b2d0..3390af3d04a54 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -421,7 +421,7 @@ export interface IEditorOptions { * Enable quick suggestions (shadow suggestions) * Defaults to true. */ - quickSuggestions?: boolean; + quickSuggestions?: boolean | { other: boolean, comments: boolean, strings: boolean }; /** * Quick suggestions show delay (in ms) * Defaults to 500 (ms) @@ -1005,7 +1005,7 @@ export class EditorContribOptions { readonly selectionClipboard: boolean; readonly hover: boolean; readonly contextmenu: boolean; - readonly quickSuggestions: boolean; + readonly quickSuggestions: boolean | { other: boolean, comments: boolean, strings: boolean }; readonly quickSuggestionsDelay: number; readonly parameterHints: boolean; readonly iconsInSuggestions: boolean; @@ -1032,7 +1032,7 @@ export class EditorContribOptions { selectionClipboard: boolean; hover: boolean; contextmenu: boolean; - quickSuggestions: boolean; + quickSuggestions: boolean | { other: boolean, comments: boolean, strings: boolean }; quickSuggestionsDelay: number; parameterHints: boolean; iconsInSuggestions: boolean; @@ -1055,7 +1055,7 @@ export class EditorContribOptions { this.selectionClipboard = Boolean(source.selectionClipboard); this.hover = Boolean(source.hover); this.contextmenu = Boolean(source.contextmenu); - this.quickSuggestions = Boolean(source.quickSuggestions); + this.quickSuggestions = source.quickSuggestions; this.quickSuggestionsDelay = source.quickSuggestionsDelay || 0; this.parameterHints = Boolean(source.parameterHints); this.iconsInSuggestions = Boolean(source.iconsInSuggestions); @@ -1084,7 +1084,7 @@ export class EditorContribOptions { this.selectionClipboard === other.selectionClipboard && this.hover === other.hover && this.contextmenu === other.contextmenu - && this.quickSuggestions === other.quickSuggestions + && objects.equals(this.quickSuggestions, other.quickSuggestions) && this.quickSuggestionsDelay === other.quickSuggestionsDelay && this.parameterHints === other.parameterHints && this.iconsInSuggestions === other.iconsInSuggestions diff --git a/src/vs/editor/contrib/suggest/common/suggestModel.ts b/src/vs/editor/contrib/suggest/common/suggestModel.ts index a002e184f2086..5ac02485b3434 100644 --- a/src/vs/editor/contrib/suggest/common/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/common/suggestModel.ts @@ -11,7 +11,7 @@ import Event, { Emitter } from 'vs/base/common/event'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; import { ICommonCodeEditor, ICursorSelectionChangedEvent, CursorChangeReason, IModel, IPosition, IWordAtPosition } from 'vs/editor/common/editorCommon'; -import { ISuggestSupport, SuggestRegistry } from 'vs/editor/common/modes'; +import { ISuggestSupport, SuggestRegistry, StandardTokenType } from 'vs/editor/common/modes'; import { Position } from 'vs/editor/common/core/position'; import { provideSuggestionItems, getSuggestionComparator, ISuggestionItem } from './suggest'; import { CompletionModel } from './completionModel'; @@ -260,14 +260,42 @@ export class SuggestModel implements IDisposable { // trigger 24x7 IntelliSense when idle, enabled, when cursor // moved RIGHT, and when at a good position - if (this.editor.getConfiguration().contribInfo.quickSuggestions - && prevPosition.isBefore(this.currentPosition)) { + if (this.editor.getConfiguration().contribInfo.quickSuggestions !== false + && prevPosition.isBefore(this.currentPosition) + ) { this.cancel(); if (LineContext.shouldAutoTrigger(this.editor)) { this.triggerAutoSuggestPromise = TPromise.timeout(this.quickSuggestDelay); this.triggerAutoSuggestPromise.then(() => { + const model = this.editor.getModel(); + const pos = this.editor.getPosition(); + + if (!model) { + return; + } + // validate enabled now + const { quickSuggestions } = this.editor.getConfiguration().contribInfo; + if (quickSuggestions === false) { + return; + } else if (quickSuggestions === true) { + // all good + } else { + model.forceTokenization(pos.lineNumber); + const { tokenType } = model + .getLineTokens(pos.lineNumber) + .findTokenAtOffset(pos.column - 1); + + const inValidScope = quickSuggestions.other && tokenType === StandardTokenType.Other + || quickSuggestions.comments && tokenType === StandardTokenType.Comment + || quickSuggestions.strings && tokenType === StandardTokenType.String; + + if (!inValidScope) { + return; + } + } + this.triggerAutoSuggestPromise = null; this.trigger(true); }); @@ -390,6 +418,11 @@ export class SuggestModel implements IDisposable { // freeze when IntelliSense was manually requested this.completionModel.lineContext = oldLineContext; isFrozen = this.completionModel.items.length > 0; + + } else { + // nothing left + this.cancel(); + return; } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e1424651bb5fa..faf8b9aebe187 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1336,7 +1336,11 @@ declare module monaco.editor { * Enable quick suggestions (shadow suggestions) * Defaults to true. */ - quickSuggestions?: boolean; + quickSuggestions?: boolean | { + other: boolean; + comments: boolean; + strings: boolean; + }; /** * Quick suggestions show delay (in ms) * Defaults to 500 (ms) @@ -1608,7 +1612,11 @@ declare module monaco.editor { readonly selectionClipboard: boolean; readonly hover: boolean; readonly contextmenu: boolean; - readonly quickSuggestions: boolean; + readonly quickSuggestions: boolean | { + other: boolean; + comments: boolean; + strings: boolean; + }; readonly quickSuggestionsDelay: number; readonly parameterHints: boolean; readonly iconsInSuggestions: boolean;