diff --git a/packages/tailwindcss-language-server/tests/env/v4.test.js b/packages/tailwindcss-language-server/tests/env/v4.test.js
index 76de7f15..3a7780af 100644
--- a/packages/tailwindcss-language-server/tests/env/v4.test.js
+++ b/packages/tailwindcss-language-server/tests/env/v4.test.js
@@ -791,3 +791,51 @@ defineTest({
})
},
})
+
+defineTest({
+ options: { only: true },
+ name: 'regex literals do not break language boundaries',
+ fs: {
+ 'app.css': css`
+ @import 'tailwindcss';
+ `,
+ },
+ prepare: async ({ root }) => ({ client: await createClient({ root }) }),
+ handle: async ({ client }) => {
+ let doc = await client.open({
+ lang: 'javascriptreact',
+ text: js`
+ export default function Page() {
+ let styles = "str".match(/
+
+
+ `,
+ })
+
+ let boundaries = getLanguageBoundaries(file.state, file.doc)
+
+ expect(boundaries).toEqual([
+ {
+ type: 'html',
+ range: {
+ start: { line: 0, character: 0 },
+ end: { line: 1, character: 2 },
+ },
+ },
+ {
+ type: 'css',
+ range: {
+ start: { line: 1, character: 2 },
+ end: { line: 5, character: 2 },
+ },
+ },
+ {
+ type: 'html',
+ range: {
+ start: { line: 5, character: 2 },
+ end: { line: 7, character: 6 },
+ },
+ },
+ ])
+})
+
+test('script tags in HTML are treated as a separate boundary', ({ expect }) => {
+ let file = createDocument({
+ name: 'file.html',
+ lang: 'html',
+ content: html`
+
+ `,
+ })
+
+ let boundaries = getLanguageBoundaries(file.state, file.doc)
+
+ expect(boundaries).toEqual([
+ {
+ type: 'html',
+ range: {
+ start: { line: 0, character: 0 },
+ end: { line: 1, character: 2 },
+ },
+ },
+ {
+ type: 'js',
+ range: {
+ start: { line: 1, character: 2 },
+ end: { line: 5, character: 2 },
+ },
+ },
+ {
+ type: 'html',
+ range: {
+ start: { line: 5, character: 2 },
+ end: { line: 7, character: 6 },
+ },
+ },
+ ])
+})
+
+test('Vue files detect ,
+
+
+
+
+
+ Some documentation
+
+ `,
+ })
+
+ let boundaries = getLanguageBoundaries(file.state, file.doc)
+
+ expect(boundaries).toEqual([
+ {
+ type: 'none',
+ range: {
+ start: { line: 0, character: 0 },
+ end: { line: 0, character: 0 },
+ },
+ },
+ {
+ type: 'js',
+ range: {
+ start: { line: 0, character: 0 },
+ end: { line: 2, character: 0 },
+ },
+ },
+ {
+ type: 'none',
+ range: {
+ start: { line: 2, character: 0 },
+ end: { line: 3, character: 0 },
+ },
+ },
+ {
+ type: 'html',
+ range: {
+ start: { line: 3, character: 0 },
+ end: { line: 5, character: 0 },
+ },
+ },
+ {
+ type: 'none',
+ range: {
+ start: { line: 5, character: 0 },
+ end: { line: 6, character: 0 },
+ },
+ },
+ {
+ type: 'css',
+ range: {
+ start: { line: 6, character: 0 },
+ end: { line: 10, character: 0 },
+ },
+ },
+ {
+ type: 'none',
+ range: {
+ start: { line: 10, character: 0 },
+ end: { line: 13, character: 16 },
+ },
+ },
+ ])
+})
diff --git a/packages/tailwindcss-language-service/src/util/test-utils.ts b/packages/tailwindcss-language-service/src/util/test-utils.ts
new file mode 100644
index 00000000..088dade5
--- /dev/null
+++ b/packages/tailwindcss-language-service/src/util/test-utils.ts
@@ -0,0 +1,65 @@
+import { createState, getDefaultTailwindSettings, Settings } from './state'
+import { TextDocument } from 'vscode-languageserver-textdocument'
+import type { DeepPartial } from '../types'
+import dedent from 'dedent'
+
+export const js = dedent
+export const jsx = dedent
+export const ts = dedent
+export const tsx = dedent
+export const css = dedent
+export const html = dedent
+
+export function createDocument({
+ name,
+ lang,
+ content,
+ settings,
+}: {
+ name: string
+ lang: string
+ content: string | string[]
+ settings?: DeepPartial
+}) {
+ let doc = TextDocument.create(
+ `file://${name}`,
+ lang,
+ 1,
+ typeof content === 'string' ? content : content.join('\n'),
+ )
+ let defaults = getDefaultTailwindSettings()
+ settings ??= {}
+ let state = createState({
+ editor: {
+ getConfiguration: async () => ({
+ ...defaults,
+ ...settings,
+ tailwindCSS: {
+ ...defaults.tailwindCSS,
+ ...settings.tailwindCSS,
+ lint: {
+ ...defaults.tailwindCSS.lint,
+ ...(settings.tailwindCSS?.lint ?? {}),
+ },
+ experimental: {
+ ...defaults.tailwindCSS.experimental,
+ ...(settings.tailwindCSS?.experimental ?? {}),
+ },
+ files: {
+ ...defaults.tailwindCSS.files,
+ ...(settings.tailwindCSS?.files ?? {}),
+ },
+ },
+ editor: {
+ ...defaults.editor,
+ ...settings.editor,
+ },
+ }),
+ },
+ })
+
+ return {
+ doc,
+ state,
+ }
+}