diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 845fbfa3c9cb3a792eb9750a6ad15d33cd8321ac..5a9ae68a30688318d312366efd98374bd5507d41 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -357,6 +357,19 @@ export let completionKindFromLegacyString = (function () { }; })(); +export enum CompletionItemInsertTextRule { + /** + * `insertText` is a snippet. + */ + InsertAsSnippet = 0b01, + + /** + * Adjust whitespace/indentation of multiline insert texts to + * match the current line indentation. + */ + AdjustWhitespace = 0b10 +} + /** * A completion item represents a text snippet that is * proposed to complete text that is being typed. @@ -407,9 +420,10 @@ export interface CompletionItem { */ insertText: string; /** - * The insert test is a snippet + * Addition rules (as bitmask) that should be applied when inserting + * this completion. */ - insertTextIsSnippet?: boolean; + insertTextRules?: CompletionItemInsertTextRule; /** * A range of text that should be replaced by this completion item. * @@ -436,8 +450,6 @@ export interface CompletionItem { * A command that should be run upon acceptance of this item. */ command?: Command; - /**@internal*/ - noWhitespaceAdjust?: boolean; /**@internal*/ _labelLow?: string; diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index b3d928950ba05004ae9c872d95f66ae915a647ec..93d3ed4d9acd47fba7da2da56d8b426139333c2d 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -14,7 +14,7 @@ import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Range } from 'vs/editor/common/core/range'; import { IEditorContribution, ScrollType, Handler } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { CompletionItem, CompletionItemProvider } from 'vs/editor/common/modes'; +import { CompletionItem, 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'; @@ -180,7 +180,7 @@ export class SuggestController implements IEditorContribution { && this._model.state === State.Auto && !item.suggestion.command && !item.suggestion.additionalTextEdits - && !item.suggestion.insertTextIsSnippet + && !(item.suggestion.insertTextRules & CompletionItemInsertTextRule.InsertAsSnippet) && endColumn - startColumn === item.suggestion.insertText.length ) { const oldText = this._editor.getModel().getValueInRange({ @@ -239,7 +239,7 @@ export class SuggestController implements IEditorContribution { this._memory.getValue().memorize(this._editor.getModel(), this._editor.getPosition(), event.item); let { insertText } = suggestion; - if (!suggestion.insertTextIsSnippet) { + if (!(suggestion.insertTextRules & CompletionItemInsertTextRule.InsertAsSnippet)) { insertText = SnippetParser.escape(insertText); } @@ -251,7 +251,7 @@ export class SuggestController implements IEditorContribution { overwriteBefore + columnDelta, overwriteAfter, false, false, - !suggestion.noWhitespaceAdjust + Boolean(suggestion.insertTextRules & CompletionItemInsertTextRule.AdjustWhitespace) ); if (undoStops) { @@ -315,7 +315,7 @@ export class SuggestController implements IEditorContribution { }; const makesTextEdit = (item: ISuggestionItem): boolean => { - if (item.suggestion.insertTextIsSnippet || item.suggestion.additionalTextEdits) { + if (item.suggestion.insertTextRules & CompletionItemInsertTextRule.InsertAsSnippet || item.suggestion.additionalTextEdits) { // snippet, other editor -> makes edit return true; } diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 6ebc4005be5c9f8e753286d5c89a512ce9002eac..fdb6caba717bca18ae64f00f6a26c217e63f5c93 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -534,6 +534,7 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { // enums DocumentHighlightKind: modes.DocumentHighlightKind, CompletionItemKind: modes.CompletionItemKind, + CompletionItemInsertTextRule: modes.CompletionItemInsertTextRule, SymbolKind: modes.SymbolKind, IndentAction: IndentAction, CompletionTriggerKind: modes.CompletionTriggerKind, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 5b1ea704fe23f20a71a6ab5910ef8277da48accf..85917e2abd7877c7fd8aad961dabf2b737131ef7 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4700,6 +4700,18 @@ declare namespace monaco.languages { Snippet = 25 } + export enum CompletionItemInsertTextRule { + /** + * `insertText` is a snippet. + */ + InsertAsSnippet = 1, + /** + * Adjust whitespace/indentation of multiline insert texts to + * match the current line indentation. + */ + AdjustWhitespace = 2 + } + /** * A completion item represents a text snippet that is * proposed to complete text that is being typed. @@ -4750,9 +4762,10 @@ declare namespace monaco.languages { */ insertText: string; /** - * The insert test is a snippet + * Addition rules (as bitmask) that should be applied when inserting + * this completion. */ - insertTextIsSnippet?: boolean; + insertTextRules?: CompletionItemInsertTextRule; /** * A range of text that should be replaced by this completion item. * diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 681279a3b36fece2a446da4b4487fe10a0babb6f..0fb99a4970572fdd91a981896f30adc6aa4de894 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -683,19 +683,19 @@ class SuggestAdapter { // 'insertText'-logic if (item.textEdit) { result.insertText = item.textEdit.newText; - result.insertTextIsSnippet = false; + result.insertTextRules = modes.CompletionItemInsertTextRule.AdjustWhitespace; } else if (typeof item.insertText === 'string') { result.insertText = item.insertText; - result.insertTextIsSnippet = false; + result.insertTextRules = modes.CompletionItemInsertTextRule.AdjustWhitespace; } else if (item.insertText instanceof SnippetString) { result.insertText = item.insertText.value; - result.insertTextIsSnippet = true; + result.insertTextRules = modes.CompletionItemInsertTextRule.AdjustWhitespace | modes.CompletionItemInsertTextRule.InsertAsSnippet; } else { result.insertText = item.label; - result.insertTextIsSnippet = false; + result.insertTextRules = modes.CompletionItemInsertTextRule.AdjustWhitespace; } // 'overwrite[Before|After]'-logic diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index 33578815ac51972d693080c6b56aac2aab4c03f0..2d09b275fe9589bdc57440333c2f825a579897ca 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -556,7 +556,7 @@ export namespace Suggest { result.range = Range.to(suggestion.range); // 'inserText'-logic - if (suggestion.insertTextIsSnippet) { + if (suggestion.insertTextRules & modes.CompletionItemInsertTextRule.InsertAsSnippet) { result.insertText = new types.SnippetString(suggestion.insertText); } else { result.insertText = suggestion.insertText; diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts index faa2d3f857a7f3b5fb2e967f53df175940bcd25c..94bf1fac7ac4ff559fc9f4ab2f9ff7c1d5e0e848 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts @@ -10,7 +10,7 @@ import { compare } from 'vs/base/common/strings'; import { Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ITextModel } from 'vs/editor/common/model'; -import { CompletionItem, CompletionItemKind, CompletionItemProvider, CompletionList, LanguageId } from 'vs/editor/common/modes'; +import { CompletionItem, CompletionItemKind, CompletionItemProvider, CompletionList, LanguageId, CompletionItemInsertTextRule } from 'vs/editor/common/modes'; import { IModeService } from 'vs/editor/common/services/modeService'; import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; import { localize } from 'vs/nls'; @@ -26,7 +26,7 @@ export class SnippetCompletion implements CompletionItem { range: IRange; sortText: string; kind: CompletionItemKind; - insertTextIsSnippet: true; + insertTextRules: CompletionItemInsertTextRule; constructor( readonly snippet: Snippet, @@ -38,7 +38,7 @@ export class SnippetCompletion implements CompletionItem { this.range = range; this.sortText = `${snippet.snippetSource === SnippetSource.Extension ? 'z' : 'a'}-${snippet.prefix}`; this.kind = CompletionItemKind.Snippet; - this.insertTextIsSnippet = true; + this.insertTextRules = CompletionItemInsertTextRule.InsertAsSnippet | CompletionItemInsertTextRule.AdjustWhitespace; } resolve(): this {