From b13f5ea60b9def268d93abbbe0d54c4a69d30634 Mon Sep 17 00:00:00 2001 From: William Killerud Date: Sat, 14 Sep 2024 15:58:39 +0200 Subject: [PATCH] fix: hold up, this feature is ancient, clean up the old mess --- .../src/features/do-complete.ts | 635 +++++------------- .../test/e2e/defaults-scss/completion.test.js | 23 +- 2 files changed, 163 insertions(+), 495 deletions(-) diff --git a/packages/language-services/src/features/do-complete.ts b/packages/language-services/src/features/do-complete.ts index 792efd93..f15849e3 100644 --- a/packages/language-services/src/features/do-complete.ts +++ b/packages/language-services/src/features/do-complete.ts @@ -309,7 +309,6 @@ export class DoComplete extends LanguageFeature { if (!context.isVariableContext) break; const items = await this.doVariableCompletion( - document, currentDocument, context, symbol, @@ -324,7 +323,6 @@ export class DoComplete extends LanguageFeature { if (!context.isMixinContext) break; const items = await this.doMixinCompletion( - document, currentDocument, context, symbol, @@ -339,7 +337,6 @@ export class DoComplete extends LanguageFeature { if (!context.isFunctionContext) break; const items = await this.doFunctionCompletion( - document, currentDocument, context, symbol, @@ -588,6 +585,10 @@ export class DoComplete extends LanguageFeature { detail, documentation, filterText, + textEdit: TextEdit.replace( + this.getReplaceRange(context, symbol.name), + symbol.name, + ), kind: CompletionItemKind.Class, insertTextFormat: InsertTextFormat.PlainText, label: symbol.name, @@ -595,21 +596,6 @@ export class DoComplete extends LanguageFeature { ? [CompletionItemTag.Deprecated] : undefined, }; - - if ( - this.clientCapabilities?.textDocument?.completion?.completionItem - ?.insertReplaceSupport - ) { - item.textEdit = TextEdit.replace( - this.getInsertRange(context, symbol.name), - symbol.name, - ); - } else { - // This method is kept for backwards compatibility. - // It might be removed in a major version. - item.insertText = filterText; - } - return item; } @@ -638,26 +624,16 @@ export class DoComplete extends LanguageFeature { const filterText = child.name.substring(1); const item: CompletionItem = { + textEdit: TextEdit.replace( + this.getReplaceRange(context, symbol.name), + symbol.name, + ), filterText, insertTextFormat: InsertTextFormat.PlainText, kind: CompletionItemKind.Class, label: child.name, }; - if ( - this.clientCapabilities.textDocument?.completion?.completionItem - ?.insertReplaceSupport - ) { - item.textEdit = TextEdit.replace( - this.getInsertRange(context, symbol.name), - symbol.name, - ); - } else { - // This method is kept for backwards compatibility. - // It might be removed in a major version. - item.insertText = filterText; - } - items.push(item); } } @@ -766,7 +742,6 @@ export class DoComplete extends LanguageFeature { if (!context.isVariableContext) break; const vars = await this.doVariableCompletion( - document, currentDocument, context, symbol, @@ -782,7 +757,6 @@ export class DoComplete extends LanguageFeature { if (!context.isMixinContext) break; const mixs = await this.doMixinCompletion( - document, currentDocument, context, symbol, @@ -798,7 +772,6 @@ export class DoComplete extends LanguageFeature { if (!context.isFunctionContext) break; const funcs = await this.doFunctionCompletion( - document, currentDocument, context, symbol, @@ -846,18 +819,14 @@ export class DoComplete extends LanguageFeature { } private async doVariableCompletion( - initialDocument: TextDocument, - currentDocument: TextDocument, + document: TextDocument, context: CompletionContext, symbol: SassDocumentSymbol, isPrivate: boolean, prefix = "", ): Promise { - const rawValue = this.getVariableValue(currentDocument, symbol); - let value = await this.findValue( - currentDocument, - symbol.selectionRange.start, - ); + const rawValue = this.getVariableValue(document, symbol); + let value = await this.findValue(document, symbol.selectionRange.start); value = value || rawValue; const color = value ? getColorValue(value) : null; @@ -879,7 +848,7 @@ export class DoComplete extends LanguageFeature { if (sassdoc) { documentation += `\n____\n${sassdoc}`; } - documentation += `\n____\nVariable declared in ${this.getFileName(currentDocument.uri)}`; + documentation += `\n____\nVariable declared in ${this.getFileName(document.uri)}`; const sortText = isPrivate ? label.replace(/^$[_]/, "") : undefined; @@ -898,78 +867,20 @@ export class DoComplete extends LanguageFeature { tags: symbol.sassdoc?.deprecated ? [CompletionItemTag.Deprecated] : [], }; - if ( - this.clientCapabilities?.textDocument?.completion?.completionItem - ?.insertReplaceSupport - ) { - let insertText: string = label; - if (context.namespace && context.namespace !== "*") { - insertText = `${context.namespace}.${label}`; - item.filterText = `${context.namespace}.${label}`; - } - - const range = this.getInsertRange(context, insertText); - item.textEdit = TextEdit.replace(range, insertText); - } else { - // This method is kept for backwards compatibility. - // It might be removed or simplified in a major version, placing - // the responsibility for correctly treating the word boundary - // on the editor. - // If editors are having trouble with the completion items made - // by this code, they should update to support completion items - // with text edits added in 3.16 of the LSP spec. - - const dotExt = initialDocument.uri.slice( - Math.max(0, initialDocument.uri.lastIndexOf(".")), - ); - const isEmbedded = !dotExt.match(reSassDotExt); - let insertText: string | undefined; - - const { namespace, currentWord } = context; - - if (namespace && namespace !== "*") { - const noDot = - isEmbedded || - dotExt === ".sass" || - this.configuration.completionSettings?.afterModule === ""; - - const noDollar = isEmbedded; - - item.insertText = currentWord.endsWith(".") - ? `${noDot ? "" : "."}${label}` - : noDollar - ? asDollarlessVariable(label) - : label; - - if ( - this.configuration.completionSettings?.afterModule && - this.configuration.completionSettings.afterModule.startsWith( - "{module}", - ) - ) { - item.insertText = `${namespace}${insertText}`; - } - - item.filterText = currentWord.endsWith(".") - ? `${namespace}.${label}` - : label; - } else if ( - dotExt === ".vue" || - dotExt === ".astro" || - dotExt === ".sass" || - this.configuration.completionSettings?.beforeVariable === "" - ) { - // In these languages the $ does not get replaced by the suggestion, - // so exclude it from the insertText. - item.insertText = asDollarlessVariable(label); - } + let insertText: string = label; + if (context.namespace && context.namespace !== "*") { + insertText = `${context.namespace}.${label}`; + item.filterText = `${context.namespace}.${label}`; } + const range = this.getReplaceRange(context, insertText); + item.textEdit = TextEdit.replace(range, insertText); + return [item]; } // TODO: make this generate the replace textEdit instead, it's the same pattern everywhere - getInsertRange(context: CompletionContext, insertText: string): Range { + getReplaceRange(context: CompletionContext, insertText: string): Range { const { position, currentWord } = context; const start = Position.create( position.line, @@ -991,8 +902,7 @@ export class DoComplete extends LanguageFeature { } private async doMixinCompletion( - initialDocument: TextDocument, - currentDocument: TextDocument, + document: TextDocument, context: CompletionContext, symbol: SassDocumentSymbol, isPrivate: boolean, @@ -1022,218 +932,99 @@ export class DoComplete extends LanguageFeature { if (sassdoc) { documentation.value += `\n____\n${sassdoc}`; } - documentation.value += `\n____\nMixin declared in ${this.getFileName(currentDocument.uri)}`; - - if ( - this.clientCapabilities.textDocument?.completion?.completionItem - ?.insertReplaceSupport - ) { - const base: CompletionItem = { - label, - documentation, - filterText, - sortText, - kind: CompletionItemKind.Method, - insertTextFormat: snippetSupport - ? InsertTextFormat.Snippet - : InsertTextFormat.PlainText, - tags: symbol.sassdoc?.deprecated ? [CompletionItemTag.Deprecated] : [], - }; - - let detail: string | undefined; - let insert = label; - if (context.namespace && context.namespace !== "*") { - insert = `${context.namespace}.${label}`; - base.filterText = `${context.namespace}.${label}`; - } - - const makeCompletionVariants = () => { - // Not all mixins have @content, but when they do, be smart about adding brackets - // and move the cursor to be ready to add said contents. - // Include as separate suggestion since content may not always be needed or wanted. - if ( - this.configuration.completionSettings?.suggestionStyle !== "bracket" - ) { - items.push({ - ...base, - labelDetails: detail ? { detail: `(${detail})` } : undefined, - textEdit: TextEdit.replace( - this.getInsertRange(context, insert), - insert, - ), - }); - } - - if ( - snippetSupport && - this.configuration.completionSettings?.suggestionStyle !== - "nobracket" && - currentDocument.languageId === "scss" - ) { - // TODO: test if this works correctly with multiline - const insertSnippet = `${insert} {\n\t$0\n}`; - items.push({ - ...base, - labelDetails: { detail: detail ? `(${detail}) { }` : " { }" }, - textEdit: TextEdit.replace( - this.getInsertRange(context, insertSnippet), - insertSnippet, - ), - }); - } - }; + documentation.value += `\n____\nMixin declared in ${this.getFileName(document.uri)}`; - // In the case of no required parameters, skip details. - if (symbol.detail && snippetSupport) { - const parameters = getParametersFromDetail(symbol.detail); - const requiredParameters = parameters.filter((p) => !p.defaultValue); - - // If there are required parameters, add a suggestion with only them. - if (requiredParameters.length > 0) { - const parametersSnippet = requiredParameters - .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) - .join(", "); - insert = label + `(${parametersSnippet})`; - - detail = requiredParameters - .map((p) => mapParameterSignature(p)) - .join(", "); - } + const base: CompletionItem = { + label, + documentation, + filterText, + sortText, + kind: CompletionItemKind.Method, + insertTextFormat: snippetSupport + ? InsertTextFormat.Snippet + : InsertTextFormat.PlainText, + tags: symbol.sassdoc?.deprecated ? [CompletionItemTag.Deprecated] : [], + }; - // If there are optional parameters, add a suggestion with all parameters. - if (requiredParameters.length !== parameters.length) { - const parametersSnippet = parameters - .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) - .join(", "); - insert = label + `(${parametersSnippet})`; - detail = parameters.map((p) => mapParameterSignature(p)).join(", "); + let detail: string | undefined; + let insert = label; + if (context.namespace && context.namespace !== "*") { + insert = `${context.namespace}.${label}`; + base.filterText = `${context.namespace}.${label}`; + } - makeCompletionVariants(); - } - } else { - makeCompletionVariants(); + const makeCompletionVariants = () => { + // Not all mixins have @content, but when they do, be smart about adding brackets + // and move the cursor to be ready to add said contents. + // Include as separate suggestion since content may not always be needed or wanted. + if ( + this.configuration.completionSettings?.suggestionStyle !== "bracket" + ) { + items.push({ + ...base, + labelDetails: detail ? { detail: `(${detail})` } : undefined, + textEdit: TextEdit.replace( + this.getReplaceRange(context, insert), + insert, + ), + }); } - return items; - } else { - // This method is kept for backwards compatibility. - // It might be removed or simplified in a major version, placing - // the responsibility for correctly treating the word boundary - // on the editor. - // If editors are having trouble with the completion items made - // by this code, they should update to support completion items - // with text edits added in 3.16 of the LSP spec. - - const isEmbedded = this.isEmbedded(initialDocument); - const noDot = - namespace === "*" || - isEmbedded || - initialDocument.languageId === "sass" || - this.configuration.completionSettings?.afterModule === ""; - - let insertText = namespace - ? noDot - ? `${prefix}${symbol.name}` - : `.${prefix}${symbol.name}` - : symbol.name; - if ( - namespace && - namespace !== "*" && - this.configuration.completionSettings?.afterModule && - this.configuration.completionSettings.afterModule.startsWith("{module}") + snippetSupport && + this.configuration.completionSettings?.suggestionStyle !== + "nobracket" && + document.languageId === "scss" ) { - insertText = `${namespace}${insertText}`; + // TODO: test if this works correctly with multiline, I think so from the spec text + const insertSnippet = `${insert} {\n\t$0\n}`; + items.push({ + ...base, + labelDetails: { detail: detail ? `(${detail}) { }` : " { }" }, + textEdit: TextEdit.replace( + this.getReplaceRange(context, insertSnippet), + insertSnippet, + ), + }); } + }; - const getCompletionVariants = ( - insertText: string, - detail?: string, - ): CompletionItem[] => { - const variants: CompletionItem[] = []; - const base: CompletionItem = { - documentation, - filterText, - kind: CompletionItemKind.Method, - label, - insertTextFormat: snippetSupport - ? InsertTextFormat.Snippet - : InsertTextFormat.PlainText, - sortText, - tags: symbol.sassdoc?.deprecated - ? [CompletionItemTag.Deprecated] - : [], - }; - - // Not all mixins have @content, but when they do, be smart about adding brackets - // and move the cursor to be ready to add said contents. - // Include as separate suggestion since content may not always be needed or wanted. - if ( - this.configuration.completionSettings?.suggestionStyle !== "bracket" - ) { - variants.push({ - ...base, - labelDetails: detail ? { detail: `(${detail})` } : undefined, - insertText, - }); - } - - if ( - snippetSupport && - this.configuration.completionSettings?.suggestionStyle !== - "nobracket" && - currentDocument.languageId === "scss" - ) { - variants.push({ - ...base, - labelDetails: { detail: detail ? `(${detail}) { }` : " { }" }, - insertText: (insertText += " {\n\t$0\n}"), - }); - } - - return variants; - }; + // In the case of no required parameters, skip details. + if (symbol.detail && snippetSupport) { + const parameters = getParametersFromDetail(symbol.detail); + const requiredParameters = parameters.filter((p) => !p.defaultValue); - // In the case of no required parameters, skip details. // If there are required parameters, add a suggestion with only them. - // If there are optional parameters, add a suggestion with all parameters. - if (symbol.detail && snippetSupport) { - const parameters = getParametersFromDetail(symbol.detail); - const requiredParameters = parameters.filter((p) => !p.defaultValue); - if (requiredParameters.length > 0) { - const parametersSnippet = requiredParameters - .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) - .join(", "); - const insert = insertText + `(${parametersSnippet})`; - - const detail = requiredParameters - .map((p) => mapParameterSignature(p)) - .join(", "); - - items.push(...getCompletionVariants(insert, detail)); - } - if (requiredParameters.length !== parameters.length) { - const parametersSnippet = parameters - .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) - .join(", "); - const insert = insertText + `(${parametersSnippet})`; + if (requiredParameters.length > 0) { + const parametersSnippet = requiredParameters + .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) + .join(", "); + insert = label + `(${parametersSnippet})`; + + detail = requiredParameters + .map((p) => mapParameterSignature(p)) + .join(", "); + } - const detail = parameters - .map((p) => mapParameterSignature(p)) - .join(", "); + // If there are optional parameters, add a suggestion with all parameters. + if (requiredParameters.length !== parameters.length) { + const parametersSnippet = parameters + .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) + .join(", "); + insert = label + `(${parametersSnippet})`; + detail = parameters.map((p) => mapParameterSignature(p)).join(", "); - items.push(...getCompletionVariants(insert, detail)); - } - } else { - items.push(...getCompletionVariants(insertText)); + makeCompletionVariants(); } - return items; + } else { + makeCompletionVariants(); } + + return items; } private async doFunctionCompletion( - initialDocument: TextDocument, - currentDocument: TextDocument, + document: TextDocument, context: CompletionContext, symbol: SassDocumentSymbol, isPrivate: boolean, @@ -1266,7 +1057,7 @@ export class DoComplete extends LanguageFeature { if (sassdoc) { documentation.value += `\n____\n${sassdoc}`; } - documentation.value += `\n____\nFunction declared in ${this.getFileName(currentDocument.uri)}`; + documentation.value += `\n____\nFunction declared in ${this.getFileName(document.uri)}`; // If there are required parameters, add a suggestion with only them. // If there are optional parameters, add a suggestion with all parameters. @@ -1279,142 +1070,63 @@ export class DoComplete extends LanguageFeature { .map((p) => mapParameterSignature(p)) .join(", "); - if ( - this.clientCapabilities.textDocument?.completion?.completionItem - ?.insertReplaceSupport - ) { - const base: CompletionItem = { - documentation, - filterText, - label, - labelDetails: { detail: `(${detail})` }, - sortText, - insertTextFormat: InsertTextFormat.Snippet, - kind: CompletionItemKind.Function, - tags: symbol.sassdoc?.deprecated ? [CompletionItemTag.Deprecated] : [], + const base: CompletionItem = { + documentation, + filterText, + label, + labelDetails: { detail: `(${detail})` }, + sortText, + insertTextFormat: InsertTextFormat.Snippet, + kind: CompletionItemKind.Function, + tags: symbol.sassdoc?.deprecated ? [CompletionItemTag.Deprecated] : [], + }; + + let insert = label; + if (context.namespace && context.namespace !== "*") { + insert = `${context.namespace}.${label}`; + base.filterText = `${context.namespace}.${label}`; + } + + if (!snippetSupport) { + const insertText = `${insert}()`; + const item: CompletionItem = { + ...base, + textEdit: TextEdit.replace( + this.getReplaceRange(context, insertText), + insertText, + ), + insertTextFormat: InsertTextFormat.PlainText, }; + items.push(item); + } else { + const insertText = `${insert}(${parametersSnippet})`; + const item: CompletionItem = { + ...base, + textEdit: TextEdit.replace( + this.getReplaceRange(context, insertText), + insertText, + ), + }; + items.push(item); - let insert = label; - if (context.namespace && context.namespace !== "*") { - insert = `${context.namespace}.${label}`; - base.filterText = `${context.namespace}.${label}`; - } + if (requiredParameters.length !== parameters.length) { + const parametersSnippet = parameters + .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) + .join(", "); + const detail = parameters + .map((p) => mapParameterSignature(p)) + .join(", "); - if (!snippetSupport) { - const insertText = `${insert}()`; - const item: CompletionItem = { - ...base, - textEdit: TextEdit.replace( - this.getInsertRange(context, insertText), - insertText, - ), - insertTextFormat: InsertTextFormat.PlainText, - }; - items.push(item); - } else { const insertText = `${insert}(${parametersSnippet})`; const item: CompletionItem = { ...base, + labelDetails: { detail: `(${detail})` }, textEdit: TextEdit.replace( - this.getInsertRange(context, insertText), + this.getReplaceRange(context, insertText), insertText, ), }; items.push(item); - - if (requiredParameters.length !== parameters.length) { - const parametersSnippet = parameters - .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) - .join(", "); - const detail = parameters - .map((p) => mapParameterSignature(p)) - .join(", "); - - const insertText = `${insert}(${parametersSnippet})`; - const item: CompletionItem = { - ...base, - labelDetails: { detail: `(${detail})` }, - textEdit: TextEdit.replace( - this.getInsertRange(context, insertText), - insertText, - ), - }; - items.push(item); - } - } - } else { - // This method is kept for backwards compatibility. - // It might be removed or simplified in a major version, placing - // the responsibility for correctly treating the word boundary - // on the editor. - // If editors are having trouble with the completion items made - // by this code, they should update to support completion items - // with text edits added in 3.16 of the LSP spec. - - const isEmbedded = this.isEmbedded(initialDocument); - - const noDot = - namespace === "*" || - isEmbedded || - initialDocument.languageId === "sass" || - this.configuration.completionSettings?.afterModule === ""; - - let insertText = namespace - ? noDot - ? `${prefix}${symbol.name}` - : `.${prefix}${symbol.name}` - : symbol.name; - - if ( - namespace && - namespace !== "*" && - this.configuration.completionSettings?.afterModule && - this.configuration.completionSettings.afterModule.startsWith("{module}") - ) { - insertText = `${namespace}${insertText}`; - } - - const base: CompletionItem = { - documentation, - filterText, - label, - labelDetails: { detail: `(${detail})` }, - sortText, - kind: CompletionItemKind.Function, - tags: symbol.sassdoc?.deprecated ? [CompletionItemTag.Deprecated] : [], - }; - - if (!snippetSupport) { - const item: CompletionItem = { - ...base, - insertText: `${insertText}()`, - insertTextFormat: InsertTextFormat.PlainText, - }; - items.push(item); - } else { - const item: CompletionItem = { - ...base, - insertText: `${insertText}(${parametersSnippet})`, - insertTextFormat: InsertTextFormat.Snippet, - }; - items.push(item); - - if (requiredParameters.length !== parameters.length) { - const parametersSnippet = parameters - .map((p, i) => mapParameterSnippet(p, i, symbol.sassdoc)) - .join(", "); - const detail = parameters - .map((p) => mapParameterSignature(p)) - .join(", "); - - const item: CompletionItem = { - ...base, - labelDetails: { detail: `(${detail})` }, - insertText: `${insertText}(${parametersSnippet})`, - insertTextFormat: InsertTextFormat.Snippet, - }; - items.push(item); - } } } @@ -1469,57 +1181,16 @@ export class DoComplete extends LanguageFeature { }, }; - if ( - this.clientCapabilities.textDocument?.completion?.completionItem - ?.insertReplaceSupport - ) { - let insert = `${context.namespace}.${label}`; - items.push({ - ...base, - textEdit: TextEdit.replace( - this.getInsertRange(context, insert), - insert, - ), - }); - } else { - // This method is kept for backwards compatibility. - // It might be removed or simplified in a major version, placing - // the responsibility for correctly treating the word boundary - // on the editor. - // If editors are having trouble with the completion items made - // by this code, they should update to support completion items - // with text edits added in 3.16 of the LSP spec. - - // Inserted text needs to include the `.` which will otherwise - // be replaced (except when we're embedded in Vue, Svelte or Astro). - // Example result: .floor(${1:number}) - const isEmbedded = this.isEmbedded(document); - - const noDot = - isEmbedded || - document.languageId === "sass" || - this.configuration.completionSettings?.afterModule === ""; - - let insertText = context.currentWord.includes(".") - ? `${noDot ? "" : "."}${label}${ - signature ? `(${snippetSupport ? parameterSnippet : ""})` : "" - }` - : label; - - if ( - this.configuration.completionSettings?.afterModule && - this.configuration.completionSettings.afterModule.startsWith( - "{module}", - ) - ) { - insertText = `${context.namespace}${insertText}`; - } - - items.push({ - ...base, - insertText, - }); - } + const insert = `${context.namespace}.${label}${ + signature ? `(${snippetSupport ? parameterSnippet : ""})` : "" + }`; + items.push({ + ...base, + textEdit: TextEdit.replace( + this.getReplaceRange(context, insert), + insert, + ), + }); } return items; diff --git a/vscode-extension/test/e2e/defaults-scss/completion.test.js b/vscode-extension/test/e2e/defaults-scss/completion.test.js index ce1a066f..0b6066cc 100644 --- a/vscode-extension/test/e2e/defaults-scss/completion.test.js +++ b/vscode-extension/test/e2e/defaults-scss/completion.test.js @@ -72,12 +72,11 @@ test("Offers namespaces completions including prefixes", async () => { let expectedCompletions = [ { label: "$var-var-variable", - insertText: '".$var-var-variable"', - filterText: '"ns.$var-var-variable"', + insertText: '"ns.$var-var-variable"', }, { label: "fun-fun-function", - insertText: '".fun-fun-function()"', + insertText: '"ns.fun-fun-function()"', }, ]; @@ -86,7 +85,7 @@ test("Offers namespaces completions including prefixes", async () => { expectedCompletions = [ { label: "mix-mix-mixin", - insertText: '".mix-mix-mixin"', + insertText: '"ns.mix-mix-mixin"', }, ]; @@ -116,12 +115,11 @@ test("Offers namespace completion inside string interpolation", async () => { let expectedCompletions = [ { label: "$var-var-variable", - insertText: '".$var-var-variable"', - filterText: '"ns.$var-var-variable"', + insertText: '"ns.$var-var-variable"', }, { label: "fun-fun-function", - insertText: '".fun-fun-function()"', + insertText: '"ns.fun-fun-function()"', }, ]; @@ -132,7 +130,7 @@ test("Offers completions for Sass built-ins", async () => { let expectedCompletions = [ { label: "floor", - insertText: '".floor(${1:number})"', + insertText: '"math.floor(${1:number})"', filterText: '"math.floor"', }, ]; @@ -144,12 +142,12 @@ test("Offers namespace completion inside string interpolation with preceeding no const expectedCompletions = [ { label: "$var-var-variable", - insertText: '".$var-var-variable"', + insertText: '"ns.$var-var-variable"', filterText: '"ns.$var-var-variable"', }, { label: "fun-fun-function", - insertText: '".fun-fun-function()"', + insertText: '"ns.fun-fun-function()"', }, ]; @@ -160,12 +158,11 @@ test("Offers namespace completion as part of return statement", async () => { const expectedCompletions = [ { label: "$var-var-variable", - insertText: '".$var-var-variable"', - filterText: '"ns.$var-var-variable"', + insertText: '"ns.$var-var-variable"', }, { label: "fun-fun-function", - insertText: '".fun-fun-function()"', + insertText: '"ns.fun-fun-function()"', }, ];