UNPKG

codemirror-languageservice

Version:

Integrate a Language Server Protocol compatible language service into CodeMirror

93 lines 2.98 kB
import { language } from '@codemirror/language'; import { Facet, StateField } from '@codemirror/state'; import { TextDocument } from 'vscode-languageserver-textdocument'; let inmemoryDocumentCounter = 0; /** * Get the first value of an array of strings. * * @param values * The input array. * @returns * The first value of the input array. */ function combine(values) { return values.at(-1); } /** * A CodeMirror {@link Facet} used to track the text document URI. */ const uriFacet = Facet.define({ combine }); /** * A CodeMirror {@link StateField} used to track the {@link TextDocument}. */ const textDocumentField = StateField.define({ create(state) { const stateUri = state.facet(uriFacet); const stateLanguage = state.facet(language); const languageId = stateLanguage?.name || 'plaintext'; return TextDocument.create(stateUri, languageId, 0, String(state.doc)); }, update(value, transaction) { const stateUri = transaction.state.facet(uriFacet); const stateLanguage = transaction.state.facet(language); const languageId = stateLanguage?.name || 'plaintext'; if (stateUri !== value.uri) { return TextDocument.create(stateUri, languageId, 0, String(transaction.newDoc)); } if (transaction.docChanged || languageId !== value.languageId) { return TextDocument.create(stateUri, languageId, value.version + 1, String(transaction.newDoc)); } return value; } }); /** * Assign a {@link TextDocument} to an editor state. * * This text document is used by other extensions provided by `codemirror-languageservice`. * * The language ID is determined from the name of the * [language](https://codemirror.net/#languages) used. If this isn’t found, the language ID defaults * to `plaintext`. * * @param uri * The URI to use for the text document. If this is left unspecified, an auto-incremented * `inmemory://` URI is used. * @returns * A CodeMirror {@link Extension}. * @example * ```ts * import { json } from '@codemirror/lang-json' * import { EditorState } from '@codemirror/state' * import { textDocument } from 'codemirror-languageservice' * * const state = EditorState.create({ * doc: 'console.log("Hello world!")\n', * extensions: [ * json(), * textDocument('file:///example.js') * ] * }) * ``` */ export function textDocument(uri) { let realUri = uri; if (!realUri) { inmemoryDocumentCounter += 1; realUri = `inmemory://${inmemoryDocumentCounter}`; } return [uriFacet.of(realUri), textDocumentField]; } /** * Get the {@link TextDocument} for a CodeMirror {@link EditorState}. * * @param state * The editor state to get the text document for. * @returns * The text document. */ export function getTextDocument(state) { return state.field(textDocumentField); } //# sourceMappingURL=text-document.js.map