UNPKG

@shopify/theme-language-server-common

Version:

<h1 align="center" style="position: relative;" > <br> <img src="https://github.com/Shopify/theme-check-vscode/blob/main/images/shopify_glyph.png?raw=true" alt="logo" width="141" height="160"> <br> Theme Language Server </h1>

82 lines (69 loc) 3.02 kB
import { createCorrector, Fix, FixDescription, flattenFixes } from '@shopify/theme-check-common'; import { ApplyWorkspaceEditRequest, Command, TextDocumentEdit, TextEdit, } from 'vscode-languageserver'; import { TextDocument } from 'vscode-languageserver-textdocument'; import { BaseExecuteCommandProvider } from '../BaseExecuteCommandProvider'; /** * The ApplyFixesProvider is responsible for handling the `themeCheck/applyFixes` command. * * To create a command, use the `applyFixCommand` function. * The provider will execute the command with the given arguments. * * ApplyFixesProvider collects the text edits represented by the targeted offenses' `.fix` property, * applies them, and forwards the result to the client using the 'workspace/applyEdit' request. */ export class ApplyFixesProvider extends BaseExecuteCommandProvider { static command = 'themeCheck/applyFixes' as const; async execute(uri: string, version: number | undefined, ids: number[]) { if (!this.clientCapabilities.hasApplyEditSupport) return; const diagnostics = this.diagnosticsManager.get(uri); const document = this.documentManager.get(uri); if (!document || !diagnostics) return; if (document.version !== version || diagnostics.version !== version) return; const anomalies = ids .map((id) => diagnostics.anomalies[id]) .filter((anomaly) => !!anomaly.offense.fix); const fixes = anomalies.map((anomaly) => anomaly.offense.fix!); const corrector = createCorrector(document.type, document.source); for (const collectFixes of fixes) { collectFixes(corrector as any); } const { textDocument } = document; const textDocumentEdit = TextDocumentEdit.create( { uri: textDocument.uri, version: textDocument.version }, toTextEdits(document.textDocument, corrector.fix), ); await this.connection.sendRequest(ApplyWorkspaceEditRequest.type, { edit: { documentChanges: [textDocumentEdit], }, }); // Clean up state diagnostics when we're done const offenses = diagnostics.anomalies.map((a) => a.offense); const fixedOffenses = anomalies.map((a) => a.offense); const remainingOffenses = offenses.filter((offense) => !fixedOffenses.includes(offense)); this.diagnosticsManager.set(uri, diagnostics.version, remainingOffenses); } } /** * applyFixCommand creates an LSP Command that the client can call */ export function applyFixCommand(uri: string, version: number | undefined, ids: number[]): Command { return Command.create('applyFixes', ApplyFixesProvider.command, uri, version, ids); } function toTextEdit(document: TextDocument, fixDesc: FixDescription): TextEdit { return { newText: fixDesc.insert, range: { start: document.positionAt(fixDesc.startIndex), end: document.positionAt(fixDesc.endIndex), }, }; } function toTextEdits(document: TextDocument, fix: Fix): TextEdit[] { return flattenFixes(fix).map((fixDesc) => toTextEdit(document, fixDesc)); }