helix-view: optionally bypass indent style auto detection

Some code formatting styles are too challenging for the indent style auto
detection heuristic.

The indent style for C code in [GStreamer] should use 2 spaces, but auto
detection leads to the followings being used:

* [gst.c] -> 2 spaces.
* [gstrtsp.c] -> 1 space.
* [gstrtspsrc.c] -> 4 spaces.

This commit adds the language configuration flag `auto-detect-indent` which
defaults to `true`. When set to `false`, it bypasses auto detection, always
using language defined indent style or `DEFAULT_INDENT` in last resort.

[GStreamer]: https://gitlab.freedesktop.org/gstreamer/gstreamer
[gst.c]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gstreamer/gst/gst.c
[gstrtsp.c]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gst-plugins-good/gst/rtsp/gstrtsp.c
[gstrtspsrc.c]: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gst-plugins-good/gst/rtsp/gstrtspsrc.c
pull/11920/head
François Laignel 1 month ago
parent be2884d800
commit c718cf4bd3

@ -44,6 +44,7 @@ injection-regex = "mylang"
file-types = ["mylang", "myl"]
comment-tokens = "#"
indent = { tab-width = 2, unit = " " }
auto-detect-indent = true
formatter = { command = "mylang-formatter" , args = ["--stdin"] }
language-servers = [ "mylang-lsp" ]
```
@ -64,6 +65,7 @@ These configuration keys are available:
| `comment-tokens` | The tokens to use as a comment token, either a single token `"//"` or an array `["//", "///", "//!"]` (the first token will be used for commenting). Also configurable as `comment-token` for backwards compatibility|
| `block-comment-tokens`| The start and end tokens for a multiline comment either an array or single table of `{ start = "/*", end = "*/"}`. The first set of tokens will be used for commenting, any pairs in the array can be uncommented |
| `indent` | The indent to use. Has sub keys `unit` (the text inserted into the document when indenting; usually set to N spaces or `"\t"` for tabs) and `tab-width` (the number of spaces rendered for a tab) |
| `auto-detect-indent` | Whether to attempt to auto-detect the indent style for current document. Set to `false` to always use language defined ident style instead. (defaults to `true`) |
| `language-servers` | The Language Servers used for this language. See below for more information in the section [Configuring Language Servers for a language](#configuring-language-servers-for-a-language) |
| `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) |
| `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout |

@ -80,6 +80,10 @@ fn default_timeout() -> u64 {
20
}
fn default_as_true() -> bool {
true
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Configuration {
@ -148,6 +152,9 @@ pub struct LanguageConfiguration {
#[serde(skip_serializing_if = "Option::is_none")]
pub indent: Option<IndentationConfiguration>,
#[serde(default = "default_as_true")]
pub auto_detect_indent: bool,
#[serde(skip)]
pub(crate) indent_query: OnceCell<Option<Query>>,
#[serde(skip)]

@ -1069,11 +1069,22 @@ impl Document {
/// configured in `languages.toml`, with a fallback to tabs if it isn't specified. Line ending
/// is likewise auto-detected, and will remain unchanged if no line endings were detected.
pub fn detect_indent_and_line_ending(&mut self) {
self.indent_style = auto_detect_indent_style(&self.text).unwrap_or_else(|| {
self.language_config()
.and_then(|config| config.indent.as_ref())
.map_or(DEFAULT_INDENT, |config| IndentStyle::from_str(&config.unit))
});
self.indent_style = self
.language_config()
.and_then(|config| {
config
.auto_detect_indent
.then(|| auto_detect_indent_style(&self.text))
.flatten()
.or_else(|| {
config
.indent
.as_ref()
.map(|ident| IndentStyle::from_str(&ident.unit))
})
})
.unwrap_or(DEFAULT_INDENT);
if let Some(line_ending) = auto_detect_line_ending(&self.text) {
self.line_ending = line_ending;
}

Loading…
Cancel
Save