diff --git a/src/lsp/providers/codeActionProvider/index.ts b/src/lsp/providers/codeActionProvider/index.ts index 62bdb128c3e49cf2cd5895a14dff8cfa7064aef1..6ae4bf984ee3310f28f8a627347c6b54b8ad140c 100644 --- a/src/lsp/providers/codeActionProvider/index.ts +++ b/src/lsp/providers/codeActionProvider/index.ts @@ -6,6 +6,7 @@ Range, TextEdit, } from 'vscode-languageserver' import { State } from '../../util/state' +import { findLast } from '../../util/find' import { isWithinRange } from '../../util/isWithinRange' import { getClassNameParts } from '../../util/getClassNameAtPosition' const dlv = require('dlv') @@ -30,9 +31,6 @@ isInvalidVariantDiagnostic, } from '../diagnostics/types' import { flatten, dedupeBy } from '../../../util/array' import { joinWithAnd } from '../../util/joinWithAnd' -import { getLanguageBoundaries } from '../../util/getLanguageBoundaries' -import { isCssDoc } from '../../util/css' -import { absoluteRange } from '../../util/absoluteRange' async function getDiagnosticsFromCodeActionParams( state: State, @@ -212,8 +210,6 @@ diagnostic: InvalidApplyDiagnostic ): Promise { let document = state.editor.documents.get(params.textDocument.uri) let documentText = document.getText() - let cssRange: Range - let cssText = documentText const { postcss } = state.modules let change: TextEdit @@ -221,67 +217,54 @@ let totalClassNamesInClassList = diagnostic.className.classList.classList.split( /\s+/ ).length - if (!isCssDoc(state, document)) { - let languageBoundaries = getLanguageBoundaries(state, document) - if (!languageBoundaries) return [] - cssRange = languageBoundaries.css.find((range) => - isWithinRange(diagnostic.range.start, range) - ) - if (!cssRange) return [] - cssText = document.getText(cssRange) - } + await postcss([ + postcss.plugin('', (_options = {}) => { + return (root) => { + root.walkRules((rule) => { + if (change) return false - try { - await postcss([ - postcss.plugin('', (_options = {}) => { - return (root) => { - root.walkRules((rule) => { - if (change) return false - - rule.walkAtRules('apply', (atRule) => { - let { start, end } = atRule.source - let atRuleRange: Range = { - start: { - line: start.line - 1, - character: start.column - 1, - }, - end: { - line: end.line - 1, - character: end.column - 1, - }, - } - if (cssRange) { - atRuleRange = absoluteRange(atRuleRange, cssRange) - } + rule.walkAtRules('apply', (atRule) => { + let { start, end } = atRule.source + let range: Range = { + start: { + line: start.line - 1, + character: start.column - 1, + }, + end: { + line: end.line - 1, + character: end.column - 1, + }, + } - if (!isWithinRange(diagnostic.range.start, atRuleRange)) { - // keep looking - return true - } + if (!isWithinRange(diagnostic.range.start, range)) { + // keep looking + return true + } - let className = diagnostic.className.className - let ast = classNameToAst( - state, - className, - rule.selector, - diagnostic.className.classList.important - ) + let className = document.getText(diagnostic.range) + let ast = classNameToAst( + state, + className, + rule.selector, + diagnostic.className.classList.important + ) - if (!ast) { - return false - } + if (!ast) { + return false + } - rule.after(ast.nodes) - let insertedRule = rule.next() + rule.after(ast.nodes) + let insertedRule = rule.next() - if (totalClassNamesInClassList === 1) { - atRule.remove() - } + if (totalClassNamesInClassList === 1) { + atRule.remove() + } - let outputIndent: string - let documentIndent = detectIndent(documentText) + let outputIndent: string + let documentIndent = detectIndent(documentText) - let ruleRange: Range = { + change = { + range: { start: { line: rule.source.start.line - 1, character: rule.source.start.column - 1, @@ -290,39 +273,30 @@ end: { line: rule.source.end.line - 1, character: rule.source.end.column, }, - } - if (cssRange) { - ruleRange = absoluteRange(ruleRange, cssRange) - } - - change = { - range: ruleRange, - newText: - rule.toString() + - (insertedRule.raws.before || '\n\n') + - insertedRule - .toString() - .replace(/\n\s*\n/g, '\n') - .replace(/(@apply [^;\n]+)$/gm, '$1;') - .replace(/([^\s^]){$/gm, '$1 {') - .replace(/^\s+/gm, (m: string) => { - if (typeof outputIndent === 'undefined') outputIndent = m - return m.replace( - new RegExp(outputIndent, 'g'), - documentIndent.indent - ) - }), - } + }, + newText: + rule.toString() + + (insertedRule.raws.before || '\n\n') + + insertedRule + .toString() + .replace(/\n\s*\n/g, '\n') + .replace(/(@apply [^;\n]+)$/gm, '$1;') + .replace(/([^\s^]){$/gm, '$1 {') + .replace(/^\s+/gm, (m: string) => { + if (typeof outputIndent === 'undefined') outputIndent = m + return m.replace( + new RegExp(outputIndent, 'g'), + documentIndent.indent + ) + }), + } - return false - }) + return false }) - } - }), - ]).process(cssText, { from: undefined }) - } catch (_) { - return [] - } + }) + } + }), + ]).process(documentText, { from: undefined }) if (!change) { return []