Skip to content

Commit f35f4ac

Browse files
committed
Hide completions from CSS language server inside @import "…" source(…)
1 parent 20e1448 commit f35f4ac

File tree

1 file changed

+47
-2
lines changed
  • packages/tailwindcss-language-server/src/language

1 file changed

+47
-2
lines changed

packages/tailwindcss-language-server/src/language/cssServer.ts

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
ConfigurationRequest,
1515
CompletionItemKind,
1616
} from 'vscode-languageserver/node'
17-
import { TextDocument } from 'vscode-languageserver-textdocument'
17+
import { Position, TextDocument } from 'vscode-languageserver-textdocument'
1818
import { Utils, URI } from 'vscode-uri'
1919
import { getLanguageModelCache } from './languageModelCache'
2020
import { Stylesheet } from 'vscode-css-languageservice'
@@ -117,6 +117,7 @@ function getDocumentContext(
117117
async function withDocumentAndSettings<T>(
118118
uri: string,
119119
callback: (result: {
120+
original: TextDocument
120121
document: TextDocument
121122
settings: LanguageSettings | undefined
122123
}) => T | Promise<T>,
@@ -126,13 +127,57 @@ async function withDocumentAndSettings<T>(
126127
return null
127128
}
128129
return await callback({
130+
original: document,
129131
document: createVirtualCssDocument(document),
130132
settings: await getDocumentSettings(document),
131133
})
132134
}
133135

136+
function isInImportDirective(doc: TextDocument, pos: Position) {
137+
let text = doc.getText({
138+
start: { line: pos.line, character: 0 },
139+
end: pos,
140+
})
141+
142+
// Scan backwards to see if we're inside an `@import` directive
143+
let foundImport = false
144+
let foundDirective = false
145+
146+
for (let i = text.length - 1; i >= 0; i--) {
147+
let char = text[i]
148+
if (char === '\n') break
149+
150+
if (char === '(' && !foundDirective) {
151+
if (text.startsWith(' source(', i - 7)) {
152+
foundDirective = true
153+
} else if (text.startsWith(' prefix(', i - 7)) {
154+
foundDirective = true
155+
} else if (text.startsWith(' theme(', i - 6)) {
156+
foundDirective = true
157+
}
158+
}
159+
160+
if (char === '@' && !foundImport) {
161+
if (text.startsWith('@import ', i)) {
162+
foundImport = true
163+
}
164+
}
165+
}
166+
167+
return foundImport && foundDirective
168+
}
169+
134170
connection.onCompletion(async ({ textDocument, position }, _token) =>
135-
withDocumentAndSettings(textDocument.uri, async ({ document, settings }) => {
171+
withDocumentAndSettings(textDocument.uri, async ({ original, document, settings }) => {
172+
// If we're inside source(…), prefix(…), or theme(…), don't show
173+
// completions from the CSS language server
174+
if (isInImportDirective(original, position)) {
175+
return {
176+
isIncomplete: false,
177+
items: [],
178+
}
179+
}
180+
136181
let result = await cssLanguageService.doComplete2(
137182
document,
138183
position,

0 commit comments

Comments
 (0)