diff --git a/Cargo.lock b/Cargo.lock index 0a848c8..45fbca2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,6 +411,7 @@ dependencies = [ "tree-sitter-swift", "tree-sitter-toml-ng", "tree-sitter-typescript", + "tree-sitter-yaml", "tree-sitter-zig", "unicode-segmentation", ] @@ -3023,6 +3024,16 @@ dependencies = [ "tree-sitter-language", ] +[[package]] +name = "tree-sitter-yaml" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c223db85f05e34794f065454843b0668ebc15d240ada63e2b5939f43ce7c97" +dependencies = [ + "cc", + "tree-sitter-language", +] + [[package]] name = "tree-sitter-zig" version = "1.1.2" diff --git a/Cargo.toml b/Cargo.toml index 782c1ae..d8459aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,7 @@ tree-sitter-rust = "<0.25.0" tree-sitter-swift = "<0.8.0" tree-sitter-toml-ng = "<0.8.0" tree-sitter-typescript = "0.23.2" +tree-sitter-yaml = "0.7.2" tree-sitter-zig = "<2" tree-sitter-c-sharp= "<0.24.0" codebook-tree-sitter-latex = "<0.7.0" diff --git a/README.md b/README.md index 5798fb2..ae6bc4c 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ Codebook is in active development. As better dictionaries are added, words that | TOML | ✅ | | TypeScript | ✅ | | Typst | ⚠️ | +| YAML | ⚠️ | | Zig | ✅ | ✅ = Good to go. diff --git a/crates/codebook/Cargo.toml b/crates/codebook/Cargo.toml index 62ce146..e5e3992 100644 --- a/crates/codebook/Cargo.toml +++ b/crates/codebook/Cargo.toml @@ -52,6 +52,7 @@ tree-sitter-swift.workspace = true tree-sitter-toml-ng.workspace = true tree-sitter-typescript.workspace = true codebook-tree-sitter-typst.workspace = true +tree-sitter-yaml.workspace = true tree-sitter-zig.workspace = true tree-sitter-c-sharp.workspace = true tree-sitter.workspace = true diff --git a/crates/codebook/src/queries.rs b/crates/codebook/src/queries.rs index 85fc001..c22867f 100644 --- a/crates/codebook/src/queries.rs +++ b/crates/codebook/src/queries.rs @@ -29,6 +29,7 @@ pub enum LanguageType { Text, Typescript, Typst, + YAML, Zig, } @@ -217,6 +218,13 @@ pub static LANGUAGE_SETTINGS: &[LanguageSetting] = &[ query: include_str!("queries/r.scm"), extensions: &["r", "R"], }, + LanguageSetting { + type_: LanguageType::YAML, + ids: &["yaml"], + dictionary_ids: &["yaml"], + query: include_str!("queries/yaml.scm"), + extensions: &["yaml", "yml"], + }, LanguageSetting { type_: LanguageType::Zig, ids: &["zig"], @@ -278,6 +286,7 @@ impl LanguageSetting { LanguageType::Text => None, LanguageType::Typescript => Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()), LanguageType::Typst => Some(codebook_tree_sitter_typst::LANGUAGE.into()), + LanguageType::YAML => Some(tree_sitter_yaml::LANGUAGE.into()), LanguageType::Zig => Some(tree_sitter_zig::LANGUAGE.into()), } } diff --git a/crates/codebook/src/queries/yaml.scm b/crates/codebook/src/queries/yaml.scm new file mode 100644 index 0000000..4a0b805 --- /dev/null +++ b/crates/codebook/src/queries/yaml.scm @@ -0,0 +1,28 @@ +; Capture YAML comments and scalar values for spell-checking +(comment) @comment + +; Unquoted plain scalars +(plain_scalar) @string + +; Single- and double-quoted scalars +(single_quote_scalar) @string +(double_quote_scalar) @string + +; Block scalars (literal '|' and folded '>') +(block_scalar) @string + +; Capture mapping keys as identifiers (useful for keys that are plain scalars) +(block_mapping_pair + key: (flow_node + [ + (double_quote_scalar) + (single_quote_scalar) + ] @identifier)) + +(flow_mapping + (_ + key: (flow_node + [ + (double_quote_scalar) + (single_quote_scalar) + ] @identifier))) diff --git a/crates/codebook/tests/test_yaml.rs b/crates/codebook/tests/test_yaml.rs new file mode 100644 index 0000000..8b3f4dd --- /dev/null +++ b/crates/codebook/tests/test_yaml.rs @@ -0,0 +1,120 @@ +use codebook::{ + parser::{TextRange, WordLocation}, + queries::LanguageType, +}; + +mod utils; + +#[test] +fn test_yaml_simple() { + utils::init_logging(); + let processor = utils::get_processor(); + let sample_text = r#" + # On a sepaate line + title: "Example lne" + nested: + name: Naame + nested: + item_name: Iteem name + details: | + # can be inented + This is comented out + this wors, too + options: + - opttions + - parameters + flags: froozen + var: 'helo' + symbol: ':hello' + "#; + let expected = vec![ + "Iteem", "Naame", "comented", "froozen", "helo", "inented", "lne", "opttions", "sepaate", + "wors", + ]; + let binding = processor + .spell_check(sample_text, Some(LanguageType::YAML), None) + .to_vec(); + let mut misspelled = binding + .iter() + .map(|r| r.word.as_str()) + .collect::>(); + misspelled.sort(); + println!("Misspelled words: {misspelled:?}"); + assert_eq!(misspelled, expected); +} + +#[test] +fn test_yaml_code() { + utils::init_logging(); + let sample_yaml_code = r#" + # On a separate line + tiitle: "Example line" + subtiitle: Subtitle + descriptioon: 'hello' + nested_struucture: + name: "Name" + nestted: + item_name: 'Item name' + another_name: Another Name + options: + - parameters: + - parameters + items: [ { id: 1, naame: "one" }, { id: 2, name: "two" } ] + + "#; + + let expected = vec![ + WordLocation::new( + "tiitle".to_string(), + vec![TextRange { + start_byte: 34, + end_byte: 40, + }], + ), + WordLocation::new( + "subtiitle".to_string(), + vec![TextRange { + start_byte: 63, + end_byte: 72, + }], + ), + WordLocation::new( + "descriptioon".to_string(), + vec![TextRange { + start_byte: 89, + end_byte: 101, + }], + ), + WordLocation::new( + "struucture".to_string(), + vec![TextRange { + start_byte: 124, + end_byte: 134, + }], + ), + WordLocation::new( + "nestted".to_string(), + vec![TextRange { + start_byte: 165, + end_byte: 172, + }], + ), + WordLocation::new( + "naame".to_string(), + vec![TextRange { + start_byte: 326, + end_byte: 331, + }], + ), + ]; + let processor = utils::get_processor(); + let misspelled = processor + .spell_check(sample_yaml_code, Some(LanguageType::YAML), None) + .to_vec(); + println!("Misspelled words: {misspelled:?}"); + for e in &expected { + let miss = misspelled.iter().find(|r| r.word == e.word).unwrap(); + println!("Expecting: {e:?}"); + assert_eq!(miss.locations, e.locations); + } +} diff --git a/editors/vscode/package.json b/editors/vscode/package.json index 4630044..f975f9d 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -44,6 +44,7 @@ "onLanguage:toml", "onLanguage:typescript", "onLanguage:typst", + "onLanguage:yaml", "onLanguage:zig", "onLanguage:csharp" ], diff --git a/editors/vscode/src/languages.ts b/editors/vscode/src/languages.ts index 2ba31b4..387fc76 100644 --- a/editors/vscode/src/languages.ts +++ b/editors/vscode/src/languages.ts @@ -19,6 +19,7 @@ export const SUPPORTED_LANGUAGES = [ "toml", "typescript", "typst", + "yaml", "zig", "csharp" ] as const;