58758fee61
* WIP: Rework indentation system * Add ComplexNode for context-aware indentation (including a proof of concept for assignment statements in rust) * Add switch statements to Go indents.toml (fixes the second half of issue #1523) Remove commented-out code * Migrate all existing indentation queries. Add more options to ComplexNode and use them to improve C/C++ indentation. * Add comments & replace Option<Vec<_>> with Vec<_> * Add more detailed documentation for tree-sitter indentation * Improve code style in indent.rs * Use tree-sitter queries for indentation instead of TOML config. Migrate existing indent queries. * Add documentation for the new indent queries. Change xtask docgen to look for indents.scm instead of indents.toml * Improve code style in indent.rs. Fix an issue with the rust indent query. * Move indentation test sources to separate files. Add `#not-kind-eq?`, `#same-line?` and `#not-same-line` custom predicates. Improve the rust and c indent queries. * Fix indent test. Improve rust indent queries. * Move indentation tests to integration test folder. * Improve code style in indent.rs. Reuse tree-sitter cursors for indentation queries. * Migrate HCL indent query * Replace custom loading in indent tests with a designated languages.toml * Update indent query file name for --health command. * Fix single-space formatting in indent queries. * Add explanation for unwrapping. Co-authored-by: Triton171 <triton0171@gmail.com>
68 lines
2.4 KiB
Rust
68 lines
2.4 KiB
Rust
use helix_core::{
|
|
indent::{treesitter_indent_for_pos, IndentStyle},
|
|
syntax::Loader,
|
|
Syntax,
|
|
};
|
|
use std::path::PathBuf;
|
|
|
|
#[test]
|
|
fn test_treesitter_indent_rust() {
|
|
test_treesitter_indent("rust.rs", "source.rust");
|
|
}
|
|
#[test]
|
|
fn test_treesitter_indent_rust_2() {
|
|
test_treesitter_indent("indent.rs", "source.rust");
|
|
// TODO Use commands.rs as indentation test.
|
|
// Currently this fails because we can't align the parameters of a closure yet
|
|
// test_treesitter_indent("commands.rs", "source.rust");
|
|
}
|
|
|
|
fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
|
|
let mut test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
test_dir.push("tests/data/indent");
|
|
|
|
let mut test_file = test_dir.clone();
|
|
test_file.push(file_name);
|
|
let test_file = std::fs::File::open(test_file).unwrap();
|
|
let doc = ropey::Rope::from_reader(test_file).unwrap();
|
|
|
|
let mut config_file = test_dir;
|
|
config_file.push("languages.toml");
|
|
let config = std::fs::read(config_file).unwrap();
|
|
let config = toml::from_slice(&config).unwrap();
|
|
let loader = Loader::new(config);
|
|
|
|
// set runtime path so we can find the queries
|
|
let mut runtime = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
runtime.push("../runtime");
|
|
std::env::set_var("HELIX_RUNTIME", runtime.to_str().unwrap());
|
|
|
|
let language_config = loader.language_config_for_scope(lang_scope).unwrap();
|
|
let highlight_config = language_config.highlight_config(&[]).unwrap();
|
|
let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader));
|
|
let indent_query = language_config.indent_query().unwrap();
|
|
let text = doc.slice(..);
|
|
|
|
for i in 0..doc.len_lines() {
|
|
let line = text.line(i);
|
|
if let Some(pos) = helix_core::find_first_non_whitespace_char(line) {
|
|
let suggested_indent = treesitter_indent_for_pos(
|
|
indent_query,
|
|
&syntax,
|
|
&IndentStyle::Spaces(4),
|
|
text,
|
|
i,
|
|
text.line_to_char(i) + pos,
|
|
false,
|
|
)
|
|
.unwrap();
|
|
assert!(
|
|
line.get_slice(..pos).map_or(false, |s| s == suggested_indent),
|
|
"Wrong indentation on line {}:\n\"{}\" (original line)\n\"{}\" (suggested indentation)\n",
|
|
i+1,
|
|
line.slice(..line.len_chars()-1),
|
|
suggested_indent,
|
|
);
|
|
}
|
|
}
|
|
}
|