visualize tree-sitter trees and queries
at main 3.1 kB view raw
1mod app; 2mod config; 3 4use std::{ 5 env, fs, 6 path::Path, 7 sync::{mpsc, Arc, RwLock}, 8 thread, 9 time::Duration, 10}; 11 12use app::App; 13use console::{Key, Term}; 14use notify::{Event as WatchEvent, EventKind as WatchEventKind, RecursiveMode, Watcher}; 15 16fn main() { 17 let mut args = env::args(); 18 let _ = args.next(); 19 20 let language = match args.next().as_ref().map(|s| s.as_str()) { 21 Some("rust") => tree_sitter_rust::LANGUAGE.into(), 22 // Some("go") => tree_sitter_go::language(), 23 // Some("tsx") | Some("typescript") => tree_sitter_typescript::language_tsx(), 24 // Some("javascript") => tree_sitter_javascript::language(), 25 // Some("java") => tree_sitter_java::language(), 26 // Some("python") => tree_sitter_python::language(), 27 // Some("ruby") => tree_sitter_ruby::language(), 28 // Some("markdown") => tree_sitter_md::language(), 29 Some(s) => panic!("invalid language passed: {s}"), 30 None => panic!("no language passed"), 31 }; 32 let path = args.next().expect("no arg passed"); 33 let query_path = args.next(); 34 let src = fs::read_to_string(&path).expect("unable to read file"); 35 36 let app = Arc::new(RwLock::new(App::new( 37 src.as_bytes(), 38 &path, 39 query_path.as_ref(), 40 language, 41 ))); 42 43 let watch_fn = |watcher_app: Arc<RwLock<App>>| { 44 move |ev| { 45 if let Ok(WatchEvent { 46 kind: WatchEventKind::Modify(..), 47 .. 48 }) = ev 49 { 50 if let Ok(mut locked) = watcher_app.try_write() { 51 locked.reload(); 52 locked.draw(); 53 }; 54 } 55 } 56 }; 57 58 let mut watcher1 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap(); 59 watcher1 60 .watch(Path::new(&path), RecursiveMode::NonRecursive) 61 .unwrap(); 62 63 let mut watcher2 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap(); 64 if let Some(query_path) = query_path { 65 watcher2 66 .watch(Path::new(&query_path), RecursiveMode::NonRecursive) 67 .unwrap(); 68 } 69 70 let (tx, rx) = mpsc::channel(); 71 let tx0 = tx.clone(); 72 thread::spawn(move || { 73 let term = Term::stdout(); 74 loop { 75 if let Ok(Key::Char(ev)) = term.read_key() { 76 tx0.send(ev).unwrap(); 77 } 78 } 79 }); 80 81 if let Ok(locked) = app.try_read() { 82 locked.draw(); 83 } 84 85 loop { 86 match rx.try_recv() { 87 Ok(ev) => { 88 if let Ok(mut locked) = app.try_write() { 89 match ev { 90 '>' => locked.increase_indent(), 91 '<' => locked.decrease_indent(), 92 'n' => locked.toggle_ranges(), 93 's' => locked.toggle_source(), 94 'r' => locked.reload(), 95 _ => (), 96 } 97 locked.draw(); 98 } 99 } 100 _ => (), 101 } 102 thread::sleep(Duration::from_millis(10)); 103 } 104}