diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index 608c33074ed..8005cf5badf 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -45,10 +45,6 @@ export class SnippetController2 implements IEditorContribution { return editor.getContribution(SnippetController2.ID); } - static guessNeedsClipboard(template: string): boolean { - return /\${?CLIPBOARD/.test(template); - } - static readonly InSnippetMode = new RawContextKey('inSnippetMode', false); static readonly HasNextTabstop = new RawContextKey('hasNextTabstop', false); static readonly HasPrevTabstop = new RawContextKey('hasPrevTabstop', false); diff --git a/src/vs/editor/contrib/snippet/snippetParser.ts b/src/vs/editor/contrib/snippet/snippetParser.ts index c82aebf6181..b6bd2eb37d3 100644 --- a/src/vs/editor/contrib/snippet/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/snippetParser.ts @@ -586,6 +586,10 @@ export class SnippetParser { return value.replace(/\$|}|\\/g, '\\$&'); } + static guessNeedsClipboard(template: string): boolean { + return /\${?CLIPBOARD/.test(template); + } + private _scanner: Scanner = new Scanner(); private _token: Token = { type: TokenType.EOF, pos: 0, len: 0 }; diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index fd2a141e9b1..6d3cefa27c8 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -14,7 +14,6 @@ import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { IIdentifiedSingleEditOperation, ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { optional } from 'vs/platform/instantiation/common/instantiation'; import { Choice, Placeholder, SnippetParser, Text, TextmateSnippet, Marker } from './snippetParser'; @@ -396,9 +395,7 @@ export class SnippetSession { const workspaceService = editor.invokeWithinContext(accessor => accessor.get(IWorkspaceContextService, optional)); const modelBasedVariableResolver = editor.invokeWithinContext(accessor => new ModelBasedVariableResolver(accessor.get(ILabelService, optional), model)); - - const clipboardService = editor.invokeWithinContext(accessor => accessor.get(IClipboardService, optional)); - const readClipboardText = () => clipboardText || clipboardService && clipboardService.readTextSync(); + const readClipboardText = () => clipboardText; let delta = 0; diff --git a/src/vs/editor/contrib/suggest/completionModel.ts b/src/vs/editor/contrib/suggest/completionModel.ts index cce7e5aaa78..8926c628e43 100644 --- a/src/vs/editor/contrib/suggest/completionModel.ts +++ b/src/vs/editor/contrib/suggest/completionModel.ts @@ -41,6 +41,9 @@ const enum Refilter { Incr = 2 } +/** + * Sorted, filtered completion view model + * */ export class CompletionModel { private readonly _items: CompletionItem[]; @@ -61,7 +64,8 @@ export class CompletionModel { lineContext: LineContext, wordDistance: WordDistance, options: InternalSuggestOptions, - snippetSuggestions: 'top' | 'bottom' | 'inline' | 'none' + snippetSuggestions: 'top' | 'bottom' | 'inline' | 'none', + readonly clipboardText: string | undefined ) { this._items = items; this._column = column; diff --git a/src/vs/editor/contrib/suggest/suggest.ts b/src/vs/editor/contrib/suggest/suggest.ts index 37cf738e967..ff1e75b7d9e 100644 --- a/src/vs/editor/contrib/suggest/suggest.ts +++ b/src/vs/editor/contrib/suggest/suggest.ts @@ -14,8 +14,9 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Range } from 'vs/editor/common/core/range'; import { FuzzyScore } from 'vs/base/common/filters'; -import { isDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { isDisposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { MenuId } from 'vs/platform/actions/common/actions'; +import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; export const Context = { Visible: new RawContextKey('suggestWidgetVisible', false), @@ -163,13 +164,21 @@ export function setSnippetSuggestSupport(support: modes.CompletionItemProvider): return old; } +class CompletionItemModel { + constructor( + readonly items: CompletionItem[], + readonly needsClipboard: boolean, + readonly dispoables: IDisposable, + ) { } +} + export async function provideSuggestionItems( model: ITextModel, position: Position, options: CompletionOptions = CompletionOptions.default, context: modes.CompletionContext = { triggerKind: modes.CompletionTriggerKind.Invoke }, token: CancellationToken = CancellationToken.None -): Promise { +): Promise { // const t1 = Date.now(); position = position.clone(); @@ -180,6 +189,7 @@ export async function provideSuggestionItems( const result: CompletionItem[] = []; const disposables = new DisposableStore(); + let needsClipboard = false; const onCompletionList = (provider: modes.CompletionItemProvider, container: modes.CompletionList | null | undefined) => { if (!container) { @@ -195,6 +205,9 @@ export async function provideSuggestionItems( if (!suggestion.sortText) { suggestion.sortText = typeof suggestion.label === 'string' ? suggestion.label : suggestion.label.name; } + if (!needsClipboard && suggestion.insertTextRules && suggestion.insertTextRules & modes.CompletionItemInsertTextRule.InsertAsSnippet) { + needsClipboard = SnippetParser.guessNeedsClipboard(suggestion.insertText); + } result.push(new CompletionItem(position, suggestion, container, provider)); } } @@ -248,7 +261,11 @@ export async function provideSuggestionItems( return Promise.reject(canceled()); } // console.log(`${result.length} items AFTER ${Date.now() - t1}ms`); - return result.sort(getSuggestionComparator(options.snippetSortOrder)); + return new CompletionItemModel( + result.sort(getSuggestionComparator(options.snippetSortOrder)), + needsClipboard, + disposables + ); } @@ -310,27 +327,23 @@ registerDefaultLanguageCommand('_executeCompletionItemProvider', async (model, p suggestions: [] }; - const disposables = new DisposableStore(); const resolving: Promise[] = []; const maxItemsToResolve = args['maxItemsToResolve'] || 0; - const items = await provideSuggestionItems(model, position); - for (const item of items) { + const completions = await provideSuggestionItems(model, position); + for (const item of completions.items) { if (resolving.length < maxItemsToResolve) { resolving.push(item.resolve(CancellationToken.None)); } result.incomplete = result.incomplete || item.container.incomplete; result.suggestions.push(item.completion); - if (isDisposable(item.container)) { - disposables.add(item.container); - } } try { await Promise.all(resolving); return result; } finally { - setTimeout(() => disposables.dispose(), 100); + setTimeout(() => completions.dispoables.dispose(), 100); } }); diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index b7d7cbce208..60dd04f3d72 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -42,6 +42,7 @@ import { MenuRegistry } from 'vs/platform/actions/common/actions'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { ILogService } from 'vs/platform/log/common/log'; import { StopWatch } from 'vs/base/common/stopwatch'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; // sticky suggest widget which doesn't disappear on focus out and such let _sticky = false; @@ -120,9 +121,10 @@ export class SuggestController implements IEditorContribution { @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @ILogService private readonly _logService: ILogService, + @IClipboardService clipboardService: IClipboardService, ) { this.editor = editor; - this.model = new SuggestModel(this.editor, editorWorker); + this.model = new SuggestModel(this.editor, editorWorker, clipboardService); this.widget = this._toDispose.add(new IdleValue(() => { @@ -358,7 +360,8 @@ export class SuggestController implements IEditorContribution { overwriteAfter: info.overwriteAfter, undoStopBefore: false, undoStopAfter: false, - adjustWhitespace: !(item.completion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace) + adjustWhitespace: !(item.completion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace), + clipboardText: event.model.clipboardText }); if (!(flags & InsertFlags.NoAfterUndoStop)) { diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 42fb74bfa9c..cf65114af70 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -7,7 +7,7 @@ import { isNonEmptyArray } from 'vs/base/common/arrays'; import { TimeoutTimer } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable, dispose, DisposableStore, isDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { CursorChangeReason, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { Position, IPosition } from 'vs/editor/common/core/position'; @@ -22,6 +22,7 @@ import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerServ import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { isLowSurrogate, isHighSurrogate } from 'vs/base/common/strings'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; export interface ICancelEvent { readonly retrigger: boolean; @@ -116,7 +117,8 @@ export class SuggestModel implements IDisposable { constructor( private readonly _editor: ICodeEditor, - private readonly _editorWorker: IEditorWorkerService + private readonly _editorWorkerService: IEditorWorkerService, + private readonly _clipboardService: IClipboardService ) { this._currentSelection = this._editor.getSelection() || new Selection(1, 1, 1, 1); @@ -422,9 +424,9 @@ export class SuggestModel implements IDisposable { } let itemKindFilter = SuggestModel._createItemKindFilter(this._editor); - let wordDistance = WordDistance.create(this._editorWorker, this._editor); + let wordDistance = WordDistance.create(this._editorWorkerService, this._editor); - let items = provideSuggestionItems( + let completions = provideSuggestionItems( model, this._editor.getPosition(), new CompletionOptions(snippetSortOrder, itemKindFilter, onlyFrom), @@ -432,7 +434,7 @@ export class SuggestModel implements IDisposable { this._requestToken.token ); - Promise.all([items, wordDistance]).then(([items, wordDistance]) => { + Promise.all([completions, wordDistance]).then(async ([completions, wordDistance]) => { dispose(this._requestToken); @@ -444,7 +446,13 @@ export class SuggestModel implements IDisposable { return; } + let clipboardText: string | undefined; + if (completions.needsClipboard) { + clipboardText = await this._clipboardService.readText(); + } + const model = this._editor.getModel(); + let items = completions.items; if (isNonEmptyArray(existingItems)) { const cmpFn = getSuggestionComparator(snippetSortOrder); @@ -458,15 +466,12 @@ export class SuggestModel implements IDisposable { }, wordDistance, this._editor.getOption(EditorOption.suggest), - this._editor.getOption(EditorOption.snippetSuggestions) + this._editor.getOption(EditorOption.snippetSuggestions), + clipboardText ); // store containers so that they can be disposed later - for (const item of items) { - if (isDisposable(item.container)) { - this._completionDisposables.add(item.container); - } - } + this._completionDisposables.add(completions.dispoables); this._onNewContext(ctx); diff --git a/src/vs/editor/contrib/suggest/test/completionModel.test.ts b/src/vs/editor/contrib/suggest/test/completionModel.test.ts index 898ba8cd171..fec966a9a3a 100644 --- a/src/vs/editor/contrib/suggest/test/completionModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/completionModel.test.ts @@ -79,7 +79,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: 'foo', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); }); test('filtering - cached', function () { @@ -110,7 +110,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: 'foo', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); assert.equal(incompleteModel.incomplete.size, 1); }); @@ -119,7 +119,7 @@ suite('CompletionModel', function () { const completeItem = createSuggestItem('foobar', 1, undefined, false, { lineNumber: 1, column: 2 }); const incompleteItem = createSuggestItem('foofoo', 1, undefined, true, { lineNumber: 1, column: 2 }); - const model = new CompletionModel([completeItem, incompleteItem], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + const model = new CompletionModel([completeItem, incompleteItem], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); assert.equal(model.incomplete.size, 1); assert.equal(model.items.length, 2); @@ -148,7 +148,7 @@ suite('CompletionModel', function () { completeItem4, completeItem5, incompleteItem1, - ], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue + ], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined ); assert.equal(model.incomplete.size, 1); assert.equal(model.items.length, 6); @@ -172,7 +172,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: ' <', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); assert.equal(model.items.length, 4); @@ -192,7 +192,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: 's', characterCountDelta: 0 - }, WordDistance.None, defaultOptions, 'top'); + }, WordDistance.None, defaultOptions, 'top', undefined); assert.equal(model.items.length, 2); const [a, b] = model.items; @@ -211,7 +211,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: 's', characterCountDelta: 0 - }, WordDistance.None, defaultOptions, 'bottom'); + }, WordDistance.None, defaultOptions, 'bottom', undefined); assert.equal(model.items.length, 2); const [a, b] = model.items; @@ -229,7 +229,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: 's', characterCountDelta: 0 - }, WordDistance.None, defaultOptions, 'inline'); + }, WordDistance.None, defaultOptions, 'inline', undefined); assert.equal(model.items.length, 2); const [a, b] = model.items; @@ -246,7 +246,7 @@ suite('CompletionModel', function () { model = new CompletionModel([item1, item2], 1, { leadingLineContent: 'M', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); assert.equal(model.items.length, 2); @@ -266,7 +266,7 @@ suite('CompletionModel', function () { model = new CompletionModel(items, 3, { leadingLineContent: ' ', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); assert.equal(model.items.length, 2); @@ -285,7 +285,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: '', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); assert.equal(model.items.length, 5); @@ -312,7 +312,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: '', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); // query gets longer, narrow down the narrow-down'ed-set from before model.lineContext = { leadingLineContent: 'rlut', characterCountDelta: 4 }; @@ -334,7 +334,7 @@ suite('CompletionModel', function () { ], 1, { leadingLineContent: '', characterCountDelta: 0 - }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue); + }, WordDistance.None, EditorOptions.suggest.defaultValue, EditorOptions.snippetSuggestions.defaultValue, undefined); model.lineContext = { leadingLineContent: 'form', characterCountDelta: 4 }; assert.equal(model.items.length, 5); diff --git a/src/vs/editor/contrib/suggest/test/suggest.test.ts b/src/vs/editor/contrib/suggest/test/suggest.test.ts index 1e1982b2166..d281a891e06 100644 --- a/src/vs/editor/contrib/suggest/test/suggest.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggest.test.ts @@ -52,7 +52,7 @@ suite('Suggest', function () { }); test('sort - snippet inline', async function () { - const items = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Inline)); + const { items } = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Inline)); assert.equal(items.length, 3); assert.equal(items[0].completion.label, 'aaa'); assert.equal(items[1].completion.label, 'fff'); @@ -60,7 +60,7 @@ suite('Suggest', function () { }); test('sort - snippet top', async function () { - const items = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Top)); + const { items } = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Top)); assert.equal(items.length, 3); assert.equal(items[0].completion.label, 'aaa'); assert.equal(items[1].completion.label, 'zzz'); @@ -68,7 +68,7 @@ suite('Suggest', function () { }); test('sort - snippet bottom', async function () { - const items = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Bottom)); + const { items } = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(SnippetSortOrder.Bottom)); assert.equal(items.length, 3); assert.equal(items[0].completion.label, 'fff'); assert.equal(items[1].completion.label, 'aaa'); @@ -76,7 +76,7 @@ suite('Suggest', function () { }); test('sort - snippet none', async function () { - const items = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(undefined, new Set().add(CompletionItemKind.Snippet))); + const { items } = await provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(undefined, new Set().add(CompletionItemKind.Snippet))); assert.equal(items.length, 1); assert.equal(items[0].completion.label, 'fff'); }); @@ -99,7 +99,7 @@ suite('Suggest', function () { }; const registration = CompletionProviderRegistry.register({ pattern: 'bar/path', scheme: 'foo' }, foo); - provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(undefined, undefined, new Set().add(foo))).then(items => { + provideSuggestionItems(model, new Position(1, 1), new CompletionOptions(undefined, undefined, new Set().add(foo))).then(({ items }) => { registration.dispose(); assert.equal(items.length, 1); @@ -138,7 +138,7 @@ suite('Suggest', function () { }; const registration = CompletionProviderRegistry.register({ pattern: 'bar/path', scheme: 'foo' }, foo); - const items = await provideSuggestionItems(model, new Position(0, 0), new CompletionOptions(undefined, undefined, new Set().add(foo))); + const { items } = await provideSuggestionItems(model, new Position(0, 0), new CompletionOptions(undefined, undefined, new Set().add(foo))); registration.dispose(); assert.equal(items.length, 2); diff --git a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts index f4ebe75cc0c..edf5997475f 100644 --- a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts @@ -33,6 +33,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { MockKeybindingService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { createTextModel } from 'vs/editor/test/common/editorTestUtils'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; export interface Ctor { new(): T; @@ -196,12 +197,19 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { return new Promise((resolve, reject) => { const editor = createMockEditor(model); - const oracle = new SuggestModel(editor, new class extends mock() { - computeWordRanges() { - return Promise.resolve({}); + const oracle = new SuggestModel( + editor, + new class extends mock() { + computeWordRanges() { + return Promise.resolve({}); + } + }, + new class extends mock() { + readText() { + return Promise.resolve('CLIPPY'); + } } - - }); + ); disposables.push(oracle, editor); try { diff --git a/src/vs/workbench/api/browser/mainThreadEditor.ts b/src/vs/workbench/api/browser/mainThreadEditor.ts index f6b8b3ccad0..ba8c05003e2 100644 --- a/src/vs/workbench/api/browser/mainThreadEditor.ts +++ b/src/vs/workbench/api/browser/mainThreadEditor.ts @@ -19,6 +19,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; import { equals } from 'vs/base/common/arrays'; import { CodeEditorStateFlag, EditorState } from 'vs/editor/browser/core/editorState'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; export interface IFocusTracker { onGainedFocus(): void; @@ -467,7 +468,7 @@ export class MainThreadTextEditor { // check if clipboard is required and only iff read it (async) let clipboardText: string | undefined; - const needsTemplate = SnippetController2.guessNeedsClipboard(template); + const needsTemplate = SnippetParser.guessNeedsClipboard(template); if (needsTemplate) { const state = new EditorState(this._codeEditor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position); clipboardText = await this._clipboardService.readText(); diff --git a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts index 2f19bd82b10..30e9538d233 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts @@ -250,7 +250,7 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi } return { - suggestions: suggestions.map(s => { + suggestions: suggestions.items.map(s => { s.completion.range = Range.fromPositions(position.delta(0, -overwriteBefore), position); return s.completion; }) diff --git a/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts b/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts index b94ee44d3a0..25d373fd0b9 100644 --- a/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts +++ b/src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { SnippetFile, Snippet, SnippetSource } from 'vs/workbench/contrib/snippets/browser/snippetsFile'; import { URI } from 'vs/base/common/uri'; -import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; +import { SnippetParser } from 'vs/editor/contrib/snippet/snippetParser'; suite('Snippets', function () { @@ -72,7 +72,7 @@ suite('Snippets', function () { let snippet = new Snippet(['foo'], 'FooSnippet1', 'foo', '', body, 'test', SnippetSource.User); assert.equal(snippet.needsClipboard, expected); - assert.equal(SnippetController2.guessNeedsClipboard(body), expected); + assert.equal(SnippetParser.guessNeedsClipboard(body), expected); } assertNeedsClipboard('foo$CLIPBOARD', true); diff --git a/src/vs/workbench/test/browser/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/browser/api/extHostLanguageFeatures.test.ts index fb797b14dd5..f6860e3f9c6 100644 --- a/src/vs/workbench/test/browser/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/browser/api/extHostLanguageFeatures.test.ts @@ -883,9 +883,9 @@ suite('ExtHostLanguageFeatures', function () { }, [])); await rpcProtocol.sync(); - const value = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); - assert.equal(value.length, 1); - assert.equal(value[0].completion.insertText, 'testing2'); + const { items } = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); + assert.equal(items.length, 1); + assert.equal(items[0].completion.insertText, 'testing2'); }); test('Suggest, order 2/3', async () => { @@ -903,9 +903,9 @@ suite('ExtHostLanguageFeatures', function () { }, [])); await rpcProtocol.sync(); - const value = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); - assert.equal(value.length, 1); - assert.equal(value[0].completion.insertText, 'weak-selector'); + const { items } = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); + assert.equal(items.length, 1); + assert.equal(items[0].completion.insertText, 'weak-selector'); }); test('Suggest, order 2/3', async () => { @@ -923,10 +923,10 @@ suite('ExtHostLanguageFeatures', function () { }, [])); await rpcProtocol.sync(); - const value = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); - assert.equal(value.length, 2); - assert.equal(value[0].completion.insertText, 'strong-1'); // sort by label - assert.equal(value[1].completion.insertText, 'strong-2'); + const { items } = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); + assert.equal(items.length, 2); + assert.equal(items[0].completion.insertText, 'strong-1'); // sort by label + assert.equal(items[1].completion.insertText, 'strong-2'); }); test('Suggest, evil provider', async () => { @@ -945,8 +945,8 @@ suite('ExtHostLanguageFeatures', function () { await rpcProtocol.sync(); - const value = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); - assert.equal(value[0].container.incomplete, false); + const { items } = await provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))); + assert.equal(items[0].container.incomplete, false); }); test('Suggest, CompletionList', async () => { @@ -958,8 +958,8 @@ suite('ExtHostLanguageFeatures', function () { }, [])); await rpcProtocol.sync(); - provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))).then(value => { - assert.equal(value[0].container.incomplete, true); + provideSuggestionItems(model, new EditorPosition(1, 1), new CompletionOptions(undefined, new Set().add(modes.CompletionItemKind.Snippet))).then(model => { + assert.equal(model.items[0].container.incomplete, true); }); });