diff --git a/src/lsp/providers/codeActionProvider.ts b/src/lsp/providers/codeActionProvider.ts new file mode 100644 index 0000000..9900319 --- /dev/null +++ b/src/lsp/providers/codeActionProvider.ts @@ -0,0 +1,45 @@ +import { + CodeAction, + CodeActionParams, + CodeActionKind, +} from 'vscode-languageserver' +import { State } from '../util/state' +import { findLast } from '../util/find' + +export function provideCodeActions( + _state: State, + params: CodeActionParams +): CodeAction[] { + if (params.context.diagnostics.length === 0) { + return null + } + + return params.context.diagnostics + .map((diagnostic) => { + let match = findLast( + / Did you mean (?:something like )?'(?[^']+)'\?$/g, + diagnostic.message + ) + + if (!match) { + return null + } + + return { + title: `Replace with '${match.groups.replacement}'`, + kind: CodeActionKind.QuickFix, + diagnostics: [diagnostic], + edit: { + changes: { + [params.textDocument.uri]: [ + { + range: diagnostic.range, + newText: match.groups.replacement, + }, + ], + }, + }, + } + }) + .filter(Boolean) +} diff --git a/src/lsp/server.ts b/src/lsp/server.ts index 3d37532..dce9672 100644 --- a/src/lsp/server.ts +++ b/src/lsp/server.ts @@ -16,6 +16,8 @@ import { Hover, TextDocumentPositionParams, DidChangeConfigurationNotification, + CodeActionParams, + CodeAction, } from 'vscode-languageserver' import getTailwindState from '../class-names/index' import { State, Settings, EditorState } from './util/state' @@ -32,6 +34,7 @@ import { clearAllDiagnostics, } from './providers/diagnosticsProvider' import { createEmitter } from '../lib/emitter' +import { provideCodeActions } from './providers/codeActionProvider' let connection = createConnection(ProposedFeatures.all) let state: State = { enabled: false, emitter: createEmitter(connection) } @@ -171,6 +174,7 @@ connection.onInitialize( ], }, hoverProvider: true, + codeActionProvider: true, }, } } @@ -226,4 +230,9 @@ connection.onHover( } ) +connection.onCodeAction((params: CodeActionParams): CodeAction[] => { + if (!state.enabled) return null + return provideCodeActions(state, params) +}) + connection.listen()