Skip to content

Commit

Permalink
Add more detailed documentation for tree-sitter indentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Triton171 committed Jan 29, 2022
1 parent d4c4533 commit c4a256e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
40 changes: 40 additions & 0 deletions helix-core/src/indent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ impl AddedIndent {
outdent: false,
}
}
/// Combine this [AddedIndent] with other.
/// This is intended for indents that apply to the same line.
fn combine_with(&mut self, other: &AddedIndent) {
self.indent |= other.indent;
self.outdent |= other.outdent;
Expand All @@ -218,6 +220,8 @@ impl IndentResult {
fn new() -> Self {
IndentResult { indent: 0 }
}
/// Add the given [AddedIndent] to the [IndentResult].
/// The [AddedIndent] should be the combination of all the added indents for one line.
fn add(&mut self, added: &AddedIndent) {
if added.indent && !added.outdent {
self.indent += 1;
Expand Down Expand Up @@ -378,6 +382,42 @@ fn added_indent<'a>(
(line, next)
}

/// Use the syntax tree to determine the indentation for a given position.
/// This can be used in 2 ways:
///
/// - To get the correct indentation for an existing line (new_line=false), not necessarily equal to the current indentation.
/// - In this case, pos should be inside the first tree-sitter node on that line.
/// In most cases, this can just be the first non-whitespace on that line.
/// - To get the indentation for a new line (new_line=true). This behaves like the first usecase if the part of the current line
/// after pos were moved to a new line.
///
/// The indentation is determined by traversing all the tree-sitter nodes containing the position.
/// Each of these nodes produces some [AddedIndent] for:
///
/// - The line of the (beginning of the) node. This is defined by the scope `all` if this is the first node on its line.
/// - The line after the node. This is defined by:
/// - The scope `tail`.
/// - The scope `all` if this node is not the first node on its line.
/// Intuitively, `all` applies to everything contained in this node while `tail` applies to everything except for the first line of the node.
/// The indents from different nodes for the same line are then combined.
/// The [IndentResult] is simply the sum of the [AddedIndent] for all lines.
///
/// Specifying which line exactly an [AddedIndent] applies to is important because indents on the same line combine differently than indents on different lines:
/// ```ignore
/// some_function(|| {
/// // Both the function parameters as well as the contained block should be indented.
/// // Because they are on the same line, this only yields one indent level
/// });
/// ```
///
/// ```ignore
/// some_function(
/// parm1,
/// || {
/// // Here we get 2 indent levels because the 'parameters' and the 'block' node begin on different lines
/// },
/// );
/// ```
fn treesitter_indent_for_pos(
query: &IndentQuery,
syntax: &Syntax,
Expand Down
2 changes: 2 additions & 0 deletions helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,10 @@ impl<'de> Deserialize<'de> for IndentQueryScopes {
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct IndentQuery {
/// Every node specified here increases the indent level by one (in total at most one per line)
#[serde(default)]
pub indent: IndentQueryScopes,
/// Every node specified here decreases the indent level by one (in total at most one per line)
#[serde(default)]
pub outdent: IndentQueryScopes,
}
Expand Down

0 comments on commit c4a256e

Please sign in to comment.