mirror of https://github.com/helix-editor/helix
Make the indent heuristic configurable
parent
559bfc1f5e
commit
938a710904
|
@ -6,7 +6,7 @@ use crate::{
|
|||
chars::{char_is_line_ending, char_is_whitespace},
|
||||
find_first_non_whitespace_char,
|
||||
graphemes::{grapheme_width, tab_width_at},
|
||||
syntax::{LanguageConfiguration, RopeProvider, Syntax},
|
||||
syntax::{IndentationHeuristic, LanguageConfiguration, RopeProvider, Syntax},
|
||||
tree_sitter::Node,
|
||||
Rope, RopeGraphemes, RopeSlice,
|
||||
};
|
||||
|
@ -931,6 +931,7 @@ pub fn treesitter_indent_for_pos<'a>(
|
|||
pub fn indent_for_newline(
|
||||
language_config: Option<&LanguageConfiguration>,
|
||||
syntax: Option<&Syntax>,
|
||||
indent_heuristic: &IndentationHeuristic,
|
||||
indent_style: &IndentStyle,
|
||||
tab_width: usize,
|
||||
text: RopeSlice,
|
||||
|
@ -939,7 +940,12 @@ pub fn indent_for_newline(
|
|||
current_line: usize,
|
||||
) -> String {
|
||||
let indent_width = indent_style.indent_width(tab_width);
|
||||
if let (Some(query), Some(syntax)) = (
|
||||
if let (
|
||||
IndentationHeuristic::TreeSitter | IndentationHeuristic::Hybrid,
|
||||
Some(query),
|
||||
Some(syntax),
|
||||
) = (
|
||||
indent_heuristic,
|
||||
language_config.and_then(|config| config.indent_query()),
|
||||
syntax,
|
||||
) {
|
||||
|
@ -953,6 +959,7 @@ pub fn indent_for_newline(
|
|||
line_before_end_pos,
|
||||
true,
|
||||
) {
|
||||
if let IndentationHeuristic::Hybrid = indent_heuristic {
|
||||
// We want to compute the indentation not only based on the
|
||||
// syntax tree but also on the actual indentation of a previous
|
||||
// line. This makes indentation computation more resilient to
|
||||
|
@ -998,6 +1005,7 @@ pub fn indent_for_newline(
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return indent.to_string(indent_style, tab_width);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -442,6 +442,22 @@ pub struct IndentationConfiguration {
|
|||
pub unit: String,
|
||||
}
|
||||
|
||||
/// How the indentation for a newly inserted line should be determined.
|
||||
/// If the selected heuristic is not available (e.g. because the current
|
||||
/// language has no tree-sitter indent queries), a simpler one will be used.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum IndentationHeuristic {
|
||||
/// Just copy the indentation of the line that the cursor is currently on.
|
||||
Simple,
|
||||
/// Use tree-sitter indent queries to compute the expected absolute indentation level of the new line.
|
||||
TreeSitter,
|
||||
/// Use tree-sitter indent queries to compute the expected difference in indentation between the new line
|
||||
/// and the line before. Add this to the actual indentation level of the line before.
|
||||
#[default]
|
||||
Hybrid,
|
||||
}
|
||||
|
||||
/// Configuration for auto pairs
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields, untagged)]
|
||||
|
|
|
@ -3053,6 +3053,7 @@ fn insert_with_indent(cx: &mut Context, cursor_fallback: IndentFallbackPos) {
|
|||
let indent = indent::indent_for_newline(
|
||||
language_config,
|
||||
syntax,
|
||||
&doc.config.load().indent_heuristic,
|
||||
&doc.indent_style,
|
||||
tab_width,
|
||||
text,
|
||||
|
@ -3181,6 +3182,7 @@ fn open(cx: &mut Context, open: Open) {
|
|||
let indent = indent::indent_for_newline(
|
||||
doc.language_config(),
|
||||
doc.syntax(),
|
||||
&doc.config.load().indent_heuristic,
|
||||
&doc.indent_style,
|
||||
doc.tab_width(),
|
||||
text,
|
||||
|
@ -3720,6 +3722,7 @@ pub mod insert {
|
|||
let indent = indent::indent_for_newline(
|
||||
doc.language_config(),
|
||||
doc.syntax(),
|
||||
&doc.config.load().indent_heuristic,
|
||||
&doc.indent_style,
|
||||
doc.tab_width(),
|
||||
text,
|
||||
|
|
|
@ -42,7 +42,7 @@ use anyhow::{anyhow, bail, Error};
|
|||
pub use helix_core::diagnostic::Severity;
|
||||
use helix_core::{
|
||||
auto_pairs::AutoPairs,
|
||||
syntax::{self, AutoPairConfig, SoftWrap},
|
||||
syntax::{self, AutoPairConfig, IndentationHeuristic, SoftWrap},
|
||||
Change, LineEnding, NATIVE_LINE_ENDING,
|
||||
};
|
||||
use helix_core::{Position, Selection};
|
||||
|
@ -291,6 +291,9 @@ pub struct Config {
|
|||
pub insert_final_newline: bool,
|
||||
/// Enables smart tab
|
||||
pub smart_tab: Option<SmartTabConfig>,
|
||||
/// Which indent heuristic to use when a new line is inserted
|
||||
#[serde(default)]
|
||||
pub indent_heuristic: IndentationHeuristic,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
|
||||
|
@ -841,6 +844,7 @@ impl Default for Config {
|
|||
default_line_ending: LineEndingConfig::default(),
|
||||
insert_final_newline: true,
|
||||
smart_tab: Some(SmartTabConfig::default()),
|
||||
indent_heuristic: IndentationHeuristic::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue