Commit

Author:

Hash:

Timestamp:

+34 -10 +/-5 browse

Kevin Schoon [me@kevinschoon.com]

669262b372377cf6a9dd7710d1a47577b9f993b1

Fri, 16 May 2025 13:28:19 +0000 (6 months ago)

add the ability to load extra tree-sitter modules
1diff --git a/ayllu/src/config.rs b/ayllu/src/config.rs
2index c877daf..0561de8 100644
3--- a/ayllu/src/config.rs
4+++ b/ayllu/src/config.rs
5 @@ -182,6 +182,7 @@ pub struct TreeSitter {
6 #[serde(default = "TreeSitter::default_queries_path")]
7 pub queries_path: String,
8 pub queries_extras_path: Option<String>,
9+ pub modules_extras_path: Option<String>,
10 pub parsers: Option<Vec<TreeSitterParser>>,
11 #[serde(default = "TreeSitter::default_keywords")]
12 pub keywords: Vec<String>,
13 diff --git a/ayllu/src/highlight.rs b/ayllu/src/highlight.rs
14index 656d63b..49c6633 100644
15--- a/ayllu/src/highlight.rs
16+++ b/ayllu/src/highlight.rs
17 @@ -3,7 +3,7 @@ use std::collections::HashMap;
18 use std::fs;
19 use std::io::{Cursor, Error, Write};
20 use std::mem;
21- use std::path::Path;
22+ use std::path::{Path, PathBuf};
23 use std::sync::RwLock;
24
25 use comrak::adapters::SyntaxHighlighterAdapter;
26 @@ -49,6 +49,7 @@ pub struct Loader {
27 // typically /usr/share/tree-sitter
28 query_path: String,
29 dynamic_ok: bool,
30+ extra_modules_path: Option<PathBuf>,
31 extra_queries_path: Option<String>,
32 extra_parsers: Vec<TreeSitterParser>,
33 // user configured highlight overrides
34 @@ -62,6 +63,7 @@ impl Loader {
35 query_path: query_path.to_string(),
36 dynamic_ok: false,
37 extra_queries_path: None,
38+ extra_modules_path: None,
39 extra_parsers: Vec::new(),
40 highlight_overrides: HashMap::new(),
41 }
42 @@ -72,6 +74,11 @@ impl Loader {
43 self
44 }
45
46+ pub fn extra_modules_path(mut self, path: &Path) -> Self {
47+ self.extra_modules_path = Some(path.to_path_buf());
48+ self
49+ }
50+
51 pub fn extra_queries(mut self, path: &str) -> Self {
52 self.extra_queries_path = Some(path.to_string());
53 self
54 @@ -133,13 +140,25 @@ impl Loader {
55 }
56
57 pub fn load(&self) -> Result<(), Error> {
58- let modules = fs::read_dir(Path::new(&self.lib_path))?;
59- for module in modules {
60- let fp = module?;
61+ let mut entries =
62+ fs::read_dir(Path::new(&self.lib_path))?.try_fold(Vec::new(), |mut accm, path| {
63+ accm.push(path?);
64+ Ok::<Vec<std::fs::DirEntry>, std::io::Error>(accm)
65+ })?;
66+ if let Some(additional_modules) = self.extra_modules_path.as_ref() {
67+ tracing::debug!("Loading additional TS modules from {:?}", additional_modules);
68+ entries.extend(fs::read_dir(additional_modules.as_path())?.try_fold(
69+ Vec::new(),
70+ |mut accm, path| {
71+ accm.push(path?);
72+ Ok::<Vec<std::fs::DirEntry>, std::io::Error>(accm)
73+ },
74+ )?);
75+ }
76+ for fp in entries {
77 let file_name = fp.file_name().into_string().unwrap();
78 if file_name.starts_with("libtree-sitter-") && file_name.ends_with(".so") {
79 let language_name = file_name.replace("libtree-sitter-", "").replace(".so", "");
80-
81 let hint = Hint(language_name);
82 let language = unsafe { load_language(fp.path().to_str().unwrap(), &hint) };
83 LANGUAGES.write().unwrap().insert(hint.clone(), language);
84 diff --git a/ayllu/src/web2/server.rs b/ayllu/src/web2/server.rs
85index 10fa968..45fcbdd 100644
86--- a/ayllu/src/web2/server.rs
87+++ b/ayllu/src/web2/server.rs
88 @@ -1,4 +1,4 @@
89- use std::collections::HashMap;
90+ use std::{collections::HashMap, path::Path};
91 use std::error::Error;
92 use std::net::SocketAddrV4;
93 use std::sync::Arc;
94 @@ -41,6 +41,9 @@ pub async fn serve(cfg: &Config) -> Result<(), Box<dyn Error>> {
95 let keywords = match &cfg.tree_sitter {
96 Some(ts_config) => {
97 let mut loader = Loader::new(&ts_config.base_path, &ts_config.queries_path);
98+ if let Some(extra_modules_path) = ts_config.modules_extras_path.as_ref() {
99+ loader = loader.extra_modules_path(Path::new(extra_modules_path));
100+ }
101 loader = loader.dynamic(true);
102 if let Some(overrides) = &ts_config.highlights {
103 loader = loader.overrides(overrides.clone());
104 diff --git a/ayllu/themes/nord.css b/ayllu/themes/nord.css
105index 720bf89..d7be16a 100644
106--- a/ayllu/themes/nord.css
107+++ b/ayllu/themes/nord.css
108 @@ -89,8 +89,8 @@ section.info-bar.single {
109 }
110
111 .positive {
112- color: var(--nord7);
113- border-bottom: 2px solid var(--nord7);
114+ color: var(--nord14);
115+ border-bottom: 2px solid var(--nord14);
116 }
117
118 .negative {
119 @@ -164,11 +164,11 @@ span.ts_variable {
120 }
121
122 span.ts_removal {
123- color: var(--primary-color);
124+ color: var(--nord11);
125 }
126
127 span.ts_addition {
128- color: var(--primary-color);
129+ color: var(--nord14);
130 }
131
132 /* Dark Mode */
133 diff --git a/config.example.toml b/config.example.toml
134index 4308272..3f0679d 100644
135--- a/config.example.toml
136+++ b/config.example.toml
137 @@ -122,6 +122,7 @@ enabled = false
138 # queries_path = "/usr/share/tree-sitter/queries"
139 # additional queries
140 # queries_extras_path = "/etc/ayllu/queries"
141+ # modules_extras_path = "/path/to/extra/tree-sitter-$lang.so objects"
142
143 # tree-sitter highlighting keywords, these are attributes that will be
144 # exposed as CSS classes which can be used to create themes.