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}