Skip to content

Commit

Permalink
Show expansion of @source globs on hover
Browse files Browse the repository at this point in the history
  • Loading branch information
thecrypticace committed Nov 12, 2024
1 parent 78dd585 commit f432e12
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 15 deletions.
54 changes: 42 additions & 12 deletions packages/tailwindcss-language-server/tests/hover/hover.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,25 +157,28 @@ withFixture('basic', (c) => {
})

withFixture('v4/basic', (c) => {
async function testHover(name, { text, lang, position, expected, expectedRange, settings }) {
async function testHover(
name,
{ text, exact = false, lang, position, expected, expectedRange, settings },
) {
test.concurrent(name, async ({ expect }) => {
let textDocument = await c.openDocument({ text, lang, settings })
let res = await c.sendRequest('textDocument/hover', {
textDocument,
position,
})

expect(res).toEqual(
expected
? {
contents: {
language: 'css',
value: expected,
},
range: expectedRange,
}
: expected,
)
if (!exact && expected) {
expected = {
contents: {
language: 'css',
value: expected,
},
range: expectedRange,
}
}

expect(res).toEqual(expected)
})
}

Expand Down Expand Up @@ -242,6 +245,33 @@ withFixture('v4/basic', (c) => {
end: { line: 2, character: 18 },
},
})

testHover('css @source glob expansion', {
exact: true,
lang: 'css',
text: `@source "../{app,components}/**/*.jsx"`,
position: { line: 0, character: 23 },
expected: {
contents: {
kind: 'markdown',
value: [
'**Expansion**',
'```plaintext',
'- ../app/**/*.jsx',
'- ../components/**/*.jsx',
'```',
].join('\n'),
},
range: {
start: { line: 0, character: 8 },
end: { line: 0, character: 38 },
},
},
expectedRange: {
start: { line: 2, character: 9 },
end: { line: 2, character: 18 },
},
})
})

withFixture('v4/css-loading-js', (c) => {
Expand Down
1 change: 1 addition & 0 deletions packages/tailwindcss-language-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@types/culori": "^2.1.0",
"@types/moo": "0.5.3",
"@types/semver": "7.3.10",
"braces": "3.0.3",
"color-name": "1.1.4",
"css.escape": "1.5.1",
"culori": "^4.0.1",
Expand Down
76 changes: 73 additions & 3 deletions packages/tailwindcss-language-service/src/hoverProvider.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import type { State } from './util/state'
import type { Hover, Position } from 'vscode-languageserver'
import type { Hover, MarkupContent, Position, Range } from 'vscode-languageserver'
import { stringifyCss, stringifyConfigValue } from './util/stringify'
import dlv from 'dlv'
import { isCssContext } from './util/css'
import { findClassNameAtPosition, findHelperFunctionsInRange } from './util/find'
import {
findAll,
findClassNameAtPosition,
findHelperFunctionsInRange,
indexToPosition,
} from './util/find'
import { validateApply } from './util/validateApply'
import { getClassNameParts } from './util/getClassNameAtPosition'
import * as jit from './util/jit'
import { validateConfigPath } from './diagnostics/getInvalidConfigPathDiagnostics'
import { isWithinRange } from './util/isWithinRange'
import type { TextDocument } from 'vscode-languageserver-textdocument'
import { addPixelEquivalentsToValue } from './util/pixelEquivalents'
import { getTextWithoutComments } from './util/doc'
import braces from 'braces'
import { absoluteRange } from './util/absoluteRange'

export async function doHover(
state: State,
Expand All @@ -19,7 +27,8 @@ export async function doHover(
): Promise<Hover> {
return (
(await provideClassNameHover(state, document, position)) ||
(await provideCssHelperHover(state, document, position))
(await provideCssHelperHover(state, document, position)) ||
(await provideSourceGlobHover(state, document, position))
)
}

Expand Down Expand Up @@ -133,3 +142,64 @@ async function provideClassNameHover(
range: className.range,
}
}

function markdown(lines: string[]): MarkupContent {
return {
kind: 'markdown',
value: lines.join('\n'),
}
}

async function provideSourceGlobHover(
state: State,
document: TextDocument,
position: Position,
): Promise<Hover> {
if (!isCssContext(state, document, position)) {
return null
}

let range = {
start: { line: position.line, character: 0 },
end: { line: position.line + 1, character: 0 },
}

let text = getTextWithoutComments(document, 'css', range)

let pattern = /@source\s*(?<path>'[^']+'|"[^"]+")/dg

for (let match of findAll(pattern, text)) {
let path = match.groups.path.slice(1, -1)

// Ignore paths that don't need brace expansion
if (!path.includes('{') || !path.includes('}')) continue

// Ignore paths that don't contain the current position
let slice: Range = absoluteRange(
{
start: indexToPosition(text, match.indices.groups.path[0]),
end: indexToPosition(text, match.indices.groups.path[1]),
},
range,
)

if (!isWithinRange(position, slice)) continue

// Perform brace expansion
let paths = new Set(braces.expand(path))
if (paths.size < 2) continue

return {
range: slice,
contents: markdown([
//
'**Expansion**',
'```plaintext',
...Array.from(paths, (path) => `- ${path}`),
'```',
]),
}
}

return null
}

0 comments on commit f432e12

Please sign in to comment.