diff --git a/helix-core/tests/indent.rs b/helix-core/tests/indent.rs index cead3ef43e612..6ab5fd37abb7c 100644 --- a/helix-core/tests/indent.rs +++ b/helix-core/tests/indent.rs @@ -1,22 +1,49 @@ use helix_core::{ indent::{indent_level_for_line, treesitter_indent_for_pos, IndentStyle}, - syntax::Loader, + syntax::{Configuration, Loader}, Syntax, }; -use std::path::PathBuf; +use std::{ + fs, + path::{Path, PathBuf}, +}; #[test] fn test_treesitter_indent_rust() { - test_treesitter_indent("rust.rs", "source.rust"); + test_treesitter_indent(&indent_test_path("rust.rs"), "source.rust"); } #[test] fn test_treesitter_indent_rust_2() { - test_treesitter_indent("commands.rs", "source.rust"); + test_treesitter_indent(&indent_test_path("commands.rs"), "source.rust"); +} + +#[test] +fn test_treesitter_indent_rust_helix() -> Result<(), std::io::Error> { + let mut root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + root_dir.pop(); + root_dir.push("helix-term"); + root_dir.push("src"); + let mut queue = vec![root_dir]; + while let Some(dir) = queue.pop() { + for entry in fs::read_dir(dir)? { + let entry = entry?; + let file_type = entry.file_type()?; + if file_type.is_dir() { + queue.push(entry.path()); + } else if file_type.is_file() { + let path = entry.path(); + if path.extension().map_or(false, |ext| ext == "rs") { + test_treesitter_indent(&path, "source.rust"); + } + } + } + } + Ok(()) } #[test] fn test_treesitter_indent_cpp() { - test_treesitter_indent("cpp.cpp", "source.cpp"); + test_treesitter_indent(&indent_test_path("cpp.cpp"), "source.cpp"); } #[test] @@ -52,20 +79,30 @@ fn test_indent_level_for_line_with_spaces_and_tabs() { assert_eq!(indent_level, 2) } -fn test_treesitter_indent(file_name: &str, lang_scope: &str) { +fn indent_tests_dir() -> PathBuf { let mut test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); test_dir.push("tests/data/indent"); + test_dir +} + +fn indent_test_path(name: &str) -> PathBuf { + let mut path = indent_tests_dir(); + path.push(name); + path +} + +fn indent_tests_config() -> Configuration { + let mut config_path = indent_tests_dir(); + config_path.push("languages.toml"); + let config = std::fs::read_to_string(config_path).unwrap(); + toml::from_str(&config).unwrap() +} - let mut test_file = test_dir.clone(); - test_file.push(file_name); - let test_file = std::fs::File::open(test_file).unwrap(); +fn test_treesitter_indent(test_path: &Path, lang_scope: &str) { + let test_file = std::fs::File::open(test_path).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_to_string(config_file).unwrap(); - let config = toml::from_str(&config).unwrap(); - let loader = Loader::new(config); + let loader = Loader::new(indent_tests_config()); // set runtime path so we can find the queries let mut runtime = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -97,7 +134,8 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) { .unwrap(); assert!( line.get_slice(..pos).map_or(false, |s| s == suggested_indent), - "Wrong indentation on line {}:\n\"{}\" (original line)\n\"{}\" (suggested indentation)\n", + "Wrong indentation for file {:?} on line {}:\n\"{}\" (original line)\n\"{}\" (suggested indentation)\n", + test_path, i+1, line.slice(..line.len_chars()-1), suggested_indent, diff --git a/runtime/queries/rust/indents.scm b/runtime/queries/rust/indents.scm index e7ea85cf9c19a..1e2aff850dbb4 100644 --- a/runtime/queries/rust/indents.scm +++ b/runtime/queries/rust/indents.scm @@ -83,6 +83,15 @@ (#not-same-line? @indent @expr-start) (#set! "scope" "all") ) +; Indent type aliases that span multiple lines, similar to +; regular assignment expressions +(type_item + . + (_) @expr-start + type: (_) @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) ; Some field expressions where the left part is a multiline expression are not ; indented by cargo fmt.