diff --git a/book/src/languages.md b/book/src/languages.md index 1fa24787..8c27785e 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -14,6 +14,18 @@ name = "rust" auto-format = false ``` +## LSP formatting options + +Use `format` field to pass extra formatting options to [Document Formatting Requests](https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-16.md#document-formatting-request--leftwards_arrow_with_hook). + +```toml +[[language]] +name = "typescript" +auto-format = true +# pass format options according to https://github.com/typescript-language-server/typescript-language-server#workspacedidchangeconfiguration omitting the "[language].format." prefix. +config = { format = { "semicolons" = "insert", "insertSpaceBeforeFunctionParenthesis" = true } } +``` + ## Tree-sitter grammars Tree-sitter grammars can also be configured in `languages.toml`: diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 1cfa04e7..ca497b64 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -78,6 +78,7 @@ pub struct LanguageConfiguration { #[serde(default)] pub auto_format: bool, + #[serde(default)] pub diagnostic_severity: Severity, diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 08201b3f..7f556ca6 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -7,7 +7,9 @@ use anyhow::anyhow; use helix_core::{find_root, ChangeSet, Rope}; use jsonrpc_core as jsonrpc; use lsp_types as lsp; +use serde::Deserialize; use serde_json::Value; +use std::collections::HashMap; use std::future::Future; use std::process::Stdio; use std::sync::{ @@ -693,6 +695,24 @@ impl Client { }; // TODO: return err::unavailable so we can fall back to tree sitter formatting + // merge FormattingOptions with 'config.format' + let config_format = self + .config + .as_ref() + .and_then(|cfg| cfg.get("format")) + .and_then(|fmt| HashMap::::deserialize(fmt).ok()); + + let options = if let Some(mut properties) = config_format { + // passed in options take precedence over 'config.format' + properties.extend(options.properties); + lsp::FormattingOptions { + properties, + ..options + } + } else { + options + }; + let params = lsp::DocumentFormattingParams { text_document, options, diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 9c3853c8..2c4b5de9 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -410,6 +410,7 @@ impl Document { let language_server = self.language_server()?; let text = self.text.clone(); let offset_encoding = language_server.offset_encoding(); + let request = language_server.text_document_formatting( self.identifier(), lsp::FormattingOptions {