From 44627aff43bd53c927fb212b810ff0b0a005cb3e Mon Sep 17 00:00:00 2001 From: William Killerud Date: Sun, 4 Aug 2024 08:37:31 +0200 Subject: [PATCH] fix: suggest variables and functions as mixin parameters --- .../do-complete-interpolation.test.ts | 30 +++++++++++++++++++ .../features/__tests__/do-complete.test.ts | 26 ++++++++++++++++ .../src/features/do-complete.ts | 6 ++++ 3 files changed, 62 insertions(+) diff --git a/packages/language-services/src/features/__tests__/do-complete-interpolation.test.ts b/packages/language-services/src/features/__tests__/do-complete-interpolation.test.ts index 62eb60d5..7404eef5 100644 --- a/packages/language-services/src/features/__tests__/do-complete-interpolation.test.ts +++ b/packages/language-services/src/features/__tests__/do-complete-interpolation.test.ts @@ -37,6 +37,36 @@ test("should not suggest mixin or placeholder in string interpolation", async () assert.isUndefined(items.find((item) => item.label === "%placeholder")); }); +test("should not suggest module mixin in string interpolation", async () => { + ls.configure({ + completionSettings: { + suggestFromUseOnly: true, + }, + }); + + const one = fileSystemProvider.createDocument( + ["$primary: limegreen;", "@mixin mixin($a: 1, $b) {}"], + { + uri: "one.scss", + }, + ); + const two = fileSystemProvider.createDocument( + ['@use "./one";', '.a { background: url("/#{one.'], + { + uri: "two.scss", + }, + ); + + // emulate scanner of language service which adds workspace documents to the cache + ls.parseStylesheet(one); + ls.parseStylesheet(two); + + const { items } = await ls.doComplete(two, Position.create(1, 29)); + assert.equal(items.length, 1); + assert.ok(items.find((annotation) => annotation.label === "$primary")); + assert.isUndefined(items.find((item) => item.label === "mixin")); +}); + test("should suggest symbol from a different document via @use when in string interpolation", async () => { ls.configure({ completionSettings: { diff --git a/packages/language-services/src/features/__tests__/do-complete.test.ts b/packages/language-services/src/features/__tests__/do-complete.test.ts index b6fce9ce..d0131d46 100644 --- a/packages/language-services/src/features/__tests__/do-complete.test.ts +++ b/packages/language-services/src/features/__tests__/do-complete.test.ts @@ -524,3 +524,29 @@ test("should suggest function in @for $i from 1 through ", async () => { assert.isUndefined(items.find((item) => item.label === "mixin")); assert.isUndefined(items.find((item) => item.label === "%placeholder")); }); + +test("should suggest variable and function as parameter to mixin, not mixin or placeholder", async () => { + ls.configure({ + completionSettings: { + suggestAllFromOpenDocument: true, + suggestFromUseOnly: false, + }, + }); + + const one = fileSystemProvider.createDocument([ + '$name: "value";', + "@mixin mixin($a: 1, $b) {}", + "@function compare($a: 1, $b) {}", + "%placeholder { color: blue; }", + ".a { @include mixin(", + ]); + + ls.parseStylesheet(one); + + const { items } = await ls.doComplete(one, Position.create(4, 20)); + + assert.ok(items.find((item) => item.label === "$name")); + assert.ok(items.find((item) => item.label === "compare")); + assert.isUndefined(items.find((item) => item.label === "mixin")); + assert.isUndefined(items.find((item) => item.label === "%placeholder")); +}); diff --git a/packages/language-services/src/features/do-complete.ts b/packages/language-services/src/features/do-complete.ts index 0e6e2c1d..aca429fd 100644 --- a/packages/language-services/src/features/do-complete.ts +++ b/packages/language-services/src/features/do-complete.ts @@ -55,6 +55,7 @@ const rePropertyValue = /.*:\s*/; const reEmptyPropertyValue = /.*:\s*$/; const reQuotedValueInString = /["'](?:[^"'\\]|\\.)*["']/g; const reMixinReference = /.*@include\s+(.*)/; +const reCompletedMixinWithParametersReference = /.*@include\s+(.*)\(/; const reComment = /^(.*\/\/|.*\/\*|\s*\*)/; const reSassDoc = /^[\\s]*\/{3}.*$/; const reQuotes = /["']/; @@ -480,6 +481,11 @@ export class DoComplete extends LanguageFeature { if (!isPropertyValue && reMixinReference.test(lineBeforePosition)) { context.isMixinContext = true; + if (reCompletedMixinWithParametersReference.test(lineBeforePosition)) { + context.isMixinContext = false; + context.isVariableContext = true; + context.isFunctionContext = true; + } } return context;