on master help sign in
Passing extra formatting options to LSPs (#2635)
f92a25afarwyler
book/src/languages.md+12
@@ -14,6 +14,18 @@ name = "rust"
14auto-format = false
14auto-format = false
15```
15```
16
16
17+## LSP formatting options
18+
19+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).
20+
21+```toml
22+[[language]]
23+name = "typescript"
24+auto-format = true
25+# pass format options according to https://github.com/typescript-language-server/typescript-language-server#workspacedidchangeconfiguration omitting the "[language].format." prefix.
26+config = { format = { "semicolons" = "insert", "insertSpaceBeforeFunctionParenthesis" = true } }
27+```
28+
17## Tree-sitter grammars
29## Tree-sitter grammars
18
30
19Tree-sitter grammars can also be configured in `languages.toml`:
31Tree-sitter grammars can also be configured in `languages.toml`:
helix-core/src/syntax.rs+1
@@ -78,6 +78,7 @@ pub struct LanguageConfiguration {
78
78
79 #[serde(default)]
79 #[serde(default)]
80 pub auto_format: bool,
80 pub auto_format: bool,
81+
81 #[serde(default)]
82 #[serde(default)]
82 pub diagnostic_severity: Severity,
83 pub diagnostic_severity: Severity,
83
84
helix-lsp/src/client.rs+20
@@ -7,7 +7,9 @@ use anyhow::anyhow;
7use helix_core::{find_root, ChangeSet, Rope};
7use helix_core::{find_root, ChangeSet, Rope};
8use jsonrpc_core as jsonrpc;
8use jsonrpc_core as jsonrpc;
9use lsp_types as lsp;
9use lsp_types as lsp;
10+use serde::Deserialize;
10use serde_json::Value;
11use serde_json::Value;
12+use std::collections::HashMap;
11use std::future::Future;
13use std::future::Future;
12use std::process::Stdio;
14use std::process::Stdio;
13use std::sync::{
15use std::sync::{
@@ -693,6 +695,24 @@ impl Client {
693 };
695 };
694 // TODO: return err::unavailable so we can fall back to tree sitter formatting
696 // TODO: return err::unavailable so we can fall back to tree sitter formatting
695
697
698+ // merge FormattingOptions with 'config.format'
699+ let config_format = self
700+ .config
701+ .as_ref()
702+ .and_then(|cfg| cfg.get("format"))
703+ .and_then(|fmt| HashMap::<String, lsp::FormattingProperty>::deserialize(fmt).ok());
704+
705+ let options = if let Some(mut properties) = config_format {
706+ // passed in options take precedence over 'config.format'
707+ properties.extend(options.properties);
708+ lsp::FormattingOptions {
709+ properties,
710+ ..options
711+ }
712+ } else {
713+ options
714+ };
715+
696 let params = lsp::DocumentFormattingParams {
716 let params = lsp::DocumentFormattingParams {
697 text_document,
717 text_document,
698 options,
718 options,
helix-view/src/document.rs+1
@@ -410,6 +410,7 @@ impl Document {
410 let language_server = self.language_server()?;
410 let language_server = self.language_server()?;
411 let text = self.text.clone();
411 let text = self.text.clone();
412 let offset_encoding = language_server.offset_encoding();
412 let offset_encoding = language_server.offset_encoding();
413+
413 let request = language_server.text_document_formatting(
414 let request = language_server.text_document_formatting(
414 self.identifier(),
415 self.identifier(),
415 lsp::FormattingOptions {
416 lsp::FormattingOptions {