Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
wip
  • Loading branch information
bradlc committed Oct 21, 2022
commit df3e3250c91579a62ce530719a6ff5568de6ad51
51 changes: 39 additions & 12 deletions packages/tailwindcss-language-server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ async function createProjectService(
state.enabled = false
refreshDiagnostics()
updateCapabilities()
connection.sendNotification('@/tailwindCSS/projectReset')
}

async function tryInit() {
Expand All @@ -520,6 +521,7 @@ async function createProjectService(
}
try {
await init()
connection.sendNotification('@/tailwindCSS/projectInitialized')
} catch (error) {
resetState()
showError(connection, error)
Expand Down Expand Up @@ -1212,6 +1214,10 @@ async function createProjectService(
].map((value) => ({ label: `${prefix}-[${value}]` }))
},
sortClassLists(classLists: string[]): string[] {
if (!state.jit) {
return classLists
}

return classLists.map((classList) => {
let result = ''
let parts = classList.split(/(\s+)/)
Expand Down Expand Up @@ -2121,19 +2127,39 @@ class TW {
this.connection.onColorPresentation(this.onColorPresentation.bind(this))
this.connection.onCodeAction(this.onCodeAction.bind(this))
this.connection.onDocumentLinks(this.onDocumentLinks.bind(this))
this.connection.onRequest((method, params: { uri: string; classLists: string[] }) => {
if (method === '@/tailwindCSS/sortSelection') {
let project = this.getProject({ uri: params.uri })
if (!project) {
return { error: 'no-project' }
}
try {
return { classLists: project.sortClassLists(params.classLists) }
} catch {
return { error: 'unknown' }
}
this.connection.onRequest(this.onRequest.bind(this))
}

private onRequest(
method: '@/tailwindCSS/sortSelection',
params: { uri: string; classLists: string[] }
): { error: string } | { classLists: string[] }
private onRequest(
method: '@/tailwindCSS/getProject',
params: { uri: string }
): { version: string } | null
private onRequest(method: string, params: any): any {
if (method === '@/tailwindCSS/sortSelection') {
let project = this.getProject({ uri: params.uri })
if (!project) {
return { error: 'no-project' }
}
})
try {
return { classLists: project.sortClassLists(params.classLists) }
} catch {
return { error: 'unknown' }
}
}

if (method === '@/tailwindCSS/getProject') {
let project = this.getProject({ uri: params.uri })
if (!project || !project.enabled() || !project.state?.enabled) {
return null
}
return {
version: project.state.version,
}
}
}

private updateCapabilities() {
Expand Down Expand Up @@ -2243,6 +2269,7 @@ class TW {
}

dispose(): void {
connection.sendNotification('@/tailwindCSS/projectsDestroyed')
for (let [, project] of this.projects) {
project.dispose()
}
Expand Down
10 changes: 10 additions & 0 deletions packages/vscode-tailwindcss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ By default VS Code will not trigger completions when editing "string" content, f
}
```

## Extension Commands

### `Tailwind CSS: Show Output`

Reveal the language server log panel. This command is only available when there is an active language server instance.

### `Tailwind CSS: Sort Classes in Selection`

Treat the current selection(s) as a list of classes and sort them based on [our recommended class order](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted). This command is only available when the current document belongs to an active Tailwind project and the `tailwindcss` version is `3.0.0` or greater.

## Extension Settings

### `tailwindCSS.includeLanguages`
Expand Down
4 changes: 2 additions & 2 deletions packages/vscode-tailwindcss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
},
{
"command": "tailwindCSS.sortSelection",
"title": "Tailwind CSS: Sort Selection",
"enablement": "editorHasSelection && resourceScheme == file"
"title": "Tailwind CSS: Sort Classes in Selection",
"enablement": "editorHasSelection && resourceScheme == file && tailwindCSS.activeTextEditorSupportsClassSorting"
}
],
"grammars": [
Expand Down
64 changes: 64 additions & 0 deletions packages/vscode-tailwindcss/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
Disposable,
} from 'vscode-languageclient/node'
import { languages as defaultLanguages } from 'tailwindcss-language-service/src/util/languages'
import * as semver from 'tailwindcss-language-service/src/util/semver'
import isObject from 'tailwindcss-language-service/src/util/isObject'
import { dedupe, equal } from 'tailwindcss-language-service/src/util/array'
import namedColors from 'color-name'
Expand Down Expand Up @@ -137,6 +138,53 @@ function selectionsAreEqual(
return true
}

async function getActiveTextEditorProject(): Promise<{ version: string } | null> {
if (clients.size === 0) {
return null
}
let editor = Window.activeTextEditor
if (!editor) {
return null
}
let uri = editor.document.uri
let folder = Workspace.getWorkspaceFolder(uri)
if (!folder) {
return null
}
let client = clients.get(folder.uri.toString())
if (!client) {
return null
}
try {
let project = await client.sendRequest<{ version: string } | null>('@/tailwindCSS/getProject', {
uri: uri.toString(),
})
return project
} catch {
return null
}
}

async function activeTextEditorSupportsClassSorting(): Promise<boolean> {
let project = await getActiveTextEditorProject()
if (!project) {
return false
}
return semver.gte(project.version, '3.0.0')
}

async function updateActiveTextEditorContext(): Promise<void> {
commands.executeCommand(
'setContext',
'tailwindCSS.activeTextEditorSupportsClassSorting',
await activeTextEditorSupportsClassSorting()
)
}

function resetActiveTextEditorContext(): void {
commands.executeCommand('setContext', 'tailwindCSS.activeTextEditorSupportsClassSorting', false)
}

export async function activate(context: ExtensionContext) {
let module = context.asAbsolutePath(path.join('dist', 'server.js'))
let prod = path.join('dist', 'tailwindServer.js')
Expand Down Expand Up @@ -216,6 +264,12 @@ export async function activate(context: ExtensionContext) {
})
)

context.subscriptions.push(
Window.onDidChangeActiveTextEditor(async () => {
await updateActiveTextEditorContext()
})
)

// context.subscriptions.push(
// commands.registerCommand(
// 'tailwindCSS.onInsertArbitraryVariantSnippet',
Expand Down Expand Up @@ -694,6 +748,16 @@ export async function activate(context: ExtensionContext) {

client.onNotification('@/tailwindCSS/clearColors', () => clearColors())

client.onNotification('@/tailwindCSS/projectInitialized', async () => {
await updateActiveTextEditorContext()
})
client.onNotification('@/tailwindCSS/projectReset', async () => {
await updateActiveTextEditorContext()
})
client.onNotification('@/tailwindCSS/projectsDestroyed', () => {
resetActiveTextEditorContext()
})

client.onRequest('@/tailwindCSS/getDocumentSymbols', async ({ uri }) => {
return commands.executeCommand<SymbolInformation[]>(
'vscode.executeDocumentSymbolProvider',
Expand Down