UNPKG

atom-languageclient

Version:
184 lines (172 loc) 8.27 kB
import type * as atomIde from "atom-ide-base" import Convert from "../convert" import { LanguageClientConnection, DocumentFormattingParams, DocumentRangeFormattingParams, DocumentOnTypeFormattingParams, FormattingOptions, ServerCapabilities, } from "../languageclient" import { TextEditor, Range, Point } from "atom" /** Public: Adapts the language server protocol "textDocument/completion" to the Atom IDE UI Code-format package. */ export default class CodeFormatAdapter { /** * Public: Determine whether this adapter can be used to adapt a language server based on the serverCapabilities * matrix containing either a documentFormattingProvider or a documentRangeFormattingProvider. * * @param serverCapabilities The {ServerCapabilities} of the language server to consider. * @returns A {Boolean} indicating this adapter can adapt the server based on the given serverCapabilities. */ public static canAdapt(serverCapabilities: ServerCapabilities): boolean { return ( serverCapabilities.documentRangeFormattingProvider === true || serverCapabilities.documentFormattingProvider === true ) } /** * Public: Format text in the editor using the given language server connection and an optional range. If the server * does not support range formatting then range will be ignored and the entire document formatted. * * @param connection A {LanguageClientConnection} to the language server that will format the text. * @param serverCapabilities The {ServerCapabilities} of the language server that will be used. * @param editor The Atom {TextEditor} containing the text that will be formatted. * @param range The optional Atom {Range} containing the subset of the text to be formatted. * @returns A {Promise} of an {Array} of {Object}s containing the AutoComplete+ suggestions to display. */ public static format( connection: LanguageClientConnection, serverCapabilities: ServerCapabilities, editor: TextEditor, range: Range ): Promise<atomIde.TextEdit[]> { if (serverCapabilities.documentRangeFormattingProvider) { return CodeFormatAdapter.formatRange(connection, editor, range) } if (serverCapabilities.documentFormattingProvider) { return CodeFormatAdapter.formatDocument(connection, editor) } throw new Error("Can not format document, language server does not support it") } /** * Public: Format the entire document of an Atom {TextEditor} by using a given language server. * * @param connection A {LanguageClientConnection} to the language server that will format the text. * @param editor The Atom {TextEditor} containing the document to be formatted. * @returns A {Promise} of an {Array} of {TextEdit} objects that can be applied to the Atom TextEditor to format the document. */ public static async formatDocument( connection: LanguageClientConnection, editor: TextEditor ): Promise<atomIde.TextEdit[]> { const edits = await connection.documentFormatting(CodeFormatAdapter.createDocumentFormattingParams(editor)) return Convert.convertLsTextEdits(edits) } /** * Public: Create {DocumentFormattingParams} to be sent to the language server when requesting an entire document is formatted. * * @param editor The Atom {TextEditor} containing the document to be formatted. * @returns A {DocumentFormattingParams} containing the identity of the text document as well as options to be used in * formatting the document such as tab size and tabs vs spaces. */ public static createDocumentFormattingParams(editor: TextEditor): DocumentFormattingParams { return { textDocument: Convert.editorToTextDocumentIdentifier(editor), options: CodeFormatAdapter.getFormatOptions(editor), } } /** * Public: Format a range within an Atom {TextEditor} by using a given language server. * * @param connection A {LanguageClientConnection} to the language server that will format the text. * @param range The Atom {Range} containing the range of text that should be formatted. * @param editor The Atom {TextEditor} containing the document to be formatted. * @returns A {Promise} of an {Array} of {TextEdit} objects that can be applied to the Atom TextEditor to format the document. */ public static async formatRange( connection: LanguageClientConnection, editor: TextEditor, range: Range ): Promise<atomIde.TextEdit[]> { const edits = await connection.documentRangeFormatting( CodeFormatAdapter.createDocumentRangeFormattingParams(editor, range) ) return Convert.convertLsTextEdits(edits) } /** * Public: Create {DocumentRangeFormattingParams} to be sent to the language server when requesting an entire document * is formatted. * * @param editor The Atom {TextEditor} containing the document to be formatted. * @param range The Atom {Range} containing the range of text that should be formatted. * @returns A {DocumentRangeFormattingParams} containing the identity of the text document, the range of the text to * be formatted as well as the options to be used in formatting the document such as tab size and tabs vs spaces. */ public static createDocumentRangeFormattingParams(editor: TextEditor, range: Range): DocumentRangeFormattingParams { return { textDocument: Convert.editorToTextDocumentIdentifier(editor), range: Convert.atomRangeToLSRange(range), options: CodeFormatAdapter.getFormatOptions(editor), } } /** * Public: Format on type within an Atom {TextEditor} by using a given language server. * * @param connection A {LanguageClientConnection} to the language server that will format the text. * @param editor The Atom {TextEditor} containing the document to be formatted. * @param point The {Point} at which the document to be formatted. * @param character A character that triggered formatting request. * @returns A {Promise} of an {Array} of {TextEdit} objects that can be applied to the Atom TextEditor to format the document. */ public static async formatOnType( connection: LanguageClientConnection, editor: TextEditor, point: Point, character: string ): Promise<atomIde.TextEdit[]> { const edits = await connection.documentOnTypeFormatting( CodeFormatAdapter.createDocumentOnTypeFormattingParams(editor, point, character) ) return Convert.convertLsTextEdits(edits) } /** * Public: Create {DocumentOnTypeFormattingParams} to be sent to the language server when requesting an entire * document is formatted. * * @param editor The Atom {TextEditor} containing the document to be formatted. * @param point The {Point} at which the document to be formatted. * @param character A character that triggered formatting request. * @returns A {DocumentOnTypeFormattingParams} containing the identity of the text document, the position of the text * to be formatted, the character that triggered formatting request as well as the options to be used in formatting * the document such as tab size and tabs vs spaces. */ public static createDocumentOnTypeFormattingParams( editor: TextEditor, point: Point, character: string ): DocumentOnTypeFormattingParams { return { textDocument: Convert.editorToTextDocumentIdentifier(editor), position: Convert.pointToPosition(point), ch: character, options: CodeFormatAdapter.getFormatOptions(editor), } } /** * Public: Create {DocumentRangeFormattingParams} to be sent to the language server when requesting an entire document * is formatted. * * @param editor The Atom {TextEditor} containing the document to be formatted. * @param range The Atom {Range} containing the range of document that should be formatted. * @returns The {FormattingOptions} to be used containing the keys: * * - `tabSize` The number of spaces a tab represents. * - `insertSpaces` {True} if spaces should be used, {False} for tab characters. */ public static getFormatOptions(editor: TextEditor): FormattingOptions { return { tabSize: editor.getTabLength(), insertSpaces: editor.getSoftTabs(), } } }