diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 5a9ae68a306..90d6c2d6bf8 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -358,16 +358,16 @@ 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 + KeepWhitespace = 0b001, + + /** + * `insertText` is a snippet. + */ + InsertAsSnippet = 0b100, } /** diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index 93d3ed4d9ac..2de72fe8c24 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -251,7 +251,7 @@ export class SuggestController implements IEditorContribution { overwriteBefore + columnDelta, overwriteAfter, false, false, - Boolean(suggestion.insertTextRules & CompletionItemInsertTextRule.AdjustWhitespace) + !(suggestion.insertTextRules & CompletionItemInsertTextRule.KeepWhitespace) ); if (undoStops) { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 85917e2abd7..3f8b38bae9d 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4701,15 +4701,14 @@ declare namespace monaco.languages { } export enum CompletionItemInsertTextRule { + /** + * Keep whitespace as-is + */ + KeepWhitespace = 1, /** * `insertText` is a snippet. */ - InsertAsSnippet = 1, - /** - * Adjust whitespace/indentation of multiline insert texts to - * match the current line indentation. - */ - AdjustWhitespace = 2 + InsertAsSnippet = 4 } /** diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index c1efc0b864d..3a11b4d8f70 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -11,6 +11,33 @@ declare module 'vscode' { export function sampleFunction(): Thenable; } + //#region Joh - https://github.com/Microsoft/vscode/issues/57093 + + /** + * An insert text rule defines how the [`insertText`](#CompletionItem.insertText) of a + * completion item should be modified. + */ + export enum CompletionItemInsertTextRule { + + /** + * Keep whitespace as is. By default, the editor adjust leading + * whitespace of new lines in completion items so that they match + * the indentation of the line for the item is accepeted. + */ + KeepWhitespace = 0b01 + } + + export interface CompletionItem { + + /** + * Rules about how/if the `insertText` should be modified by the + * editor. Can be a bit mask of many rules. + */ + insertTextRules?: CompletionItemInsertTextRule; + } + + //#endregion + //#region Joh - clipboard https://github.com/Microsoft/vscode/issues/217 export interface Clipboard { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 4b02688423c..119dfefdd62 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -731,6 +731,7 @@ export function createApiFactory( CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState, CompletionItem: extHostTypes.CompletionItem, CompletionItemKind: extHostTypes.CompletionItemKind, + CompletionItemInsertTextRule: extension.enableProposedApi ? extHostTypes.CompletionItemInsertTextRule : null, CompletionList: extHostTypes.CompletionList, CompletionTriggerKind: extHostTypes.CompletionTriggerKind, ConfigurationTarget: extHostTypes.ConfigurationTarget, diff --git a/src/vs/workbench/api/node/extHostApiCommands.ts b/src/vs/workbench/api/node/extHostApiCommands.ts index 6873d77be72..9a397bc7233 100644 --- a/src/vs/workbench/api/node/extHostApiCommands.ts +++ b/src/vs/workbench/api/node/extHostApiCommands.ts @@ -377,7 +377,7 @@ export class ExtHostApiCommands { }; return this._commands.executeCommand('_executeCompletionItemProvider', args).then(result => { if (result) { - const items = result.suggestions.map(suggestion => typeConverters.Suggest.to(suggestion)); + const items = result.suggestions.map(suggestion => typeConverters.CompletionItem.to(suggestion)); return new types.CompletionList(items, result.incomplete); } return undefined; diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 0fb99a49705..99673b0df8d 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -671,6 +671,7 @@ class SuggestAdapter { // range: undefined, insertText: undefined, + insertTextRules: typeConvert.CompletionItemInsertTextRule.from(item.insertTextRules), additionalTextEdits: item.additionalTextEdits && item.additionalTextEdits.map(typeConvert.TextEdit.from), command: this._commands.toInternal(item.command), commitCharacters: item.commitCharacters, @@ -683,19 +684,16 @@ class SuggestAdapter { // 'insertText'-logic if (item.textEdit) { result.insertText = item.textEdit.newText; - result.insertTextRules = modes.CompletionItemInsertTextRule.AdjustWhitespace; } else if (typeof item.insertText === 'string') { result.insertText = item.insertText; - result.insertTextRules = modes.CompletionItemInsertTextRule.AdjustWhitespace; } else if (item.insertText instanceof SnippetString) { result.insertText = item.insertText.value; - result.insertTextRules = modes.CompletionItemInsertTextRule.AdjustWhitespace | modes.CompletionItemInsertTextRule.InsertAsSnippet; + result.insertTextRules += modes.CompletionItemInsertTextRule.InsertAsSnippet; } else { result.insertText = item.label; - 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 2d09b275fe9..0a690d9bdcd 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -541,7 +541,26 @@ export const CompletionItemKind = { } }; -export namespace Suggest { +export namespace CompletionItemInsertTextRule { + + export function from(rule: types.CompletionItemInsertTextRule): modes.CompletionItemInsertTextRule { + let result = 0; + if ((rule & types.CompletionItemInsertTextRule.KeepWhitespace)) { + result += modes.CompletionItemInsertTextRule.KeepWhitespace; + } + return result; + } + + export function to(rule: modes.CompletionItemInsertTextRule): types.CompletionItemInsertTextRule { + let result = 0; + if ((rule & modes.CompletionItemInsertTextRule.KeepWhitespace)) { + result += types.CompletionItemInsertTextRule.KeepWhitespace; + } + return result; + } +} + +export namespace CompletionItem { export function to(suggestion: modes.CompletionItem): types.CompletionItem { const result = new types.CompletionItem(suggestion.label); @@ -554,7 +573,7 @@ export namespace Suggest { result.preselect = suggestion.preselect; result.commitCharacters = suggestion.commitCharacters; result.range = Range.to(suggestion.range); - + result.insertTextRules = CompletionItemInsertTextRule.to(suggestion.insertTextRules); // 'inserText'-logic if (suggestion.insertTextRules & modes.CompletionItemInsertTextRule.InsertAsSnippet) { result.insertText = new types.SnippetString(suggestion.insertText); @@ -562,7 +581,6 @@ export namespace Suggest { result.insertText = suggestion.insertText; result.textEdit = new types.TextEdit(result.range, result.insertText); } - // TODO additionalEdits, command return result; diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index c1c2383238a..555c76511c7 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -1157,6 +1157,10 @@ export enum CompletionItemKind { TypeParameter = 24 } +export enum CompletionItemInsertTextRule { + KeepWhitespace = 0b1 +} + export class CompletionItem implements vscode.CompletionItem { label: string; @@ -1167,6 +1171,7 @@ export class CompletionItem implements vscode.CompletionItem { filterText: string; preselect: boolean; insertText: string | SnippetString; + insertTextRules: CompletionItemInsertTextRule; range: Range; commitCharacters: string[]; textEdit: TextEdit; diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts index 94bf1fac7ac..fafe8a563e7 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetCompletionProvider.ts @@ -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.insertTextRules = CompletionItemInsertTextRule.InsertAsSnippet | CompletionItemInsertTextRule.AdjustWhitespace; + this.insertTextRules = CompletionItemInsertTextRule.InsertAsSnippet; } resolve(): this {