aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 9d51fc35f9352bda8ac920814a7ac5b83bd219bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
mod app;
mod config;

use std::{
    env, fs,
    path::Path,
    sync::{mpsc, Arc, RwLock},
    thread,
    time::Duration,
};

use app::App;
use console::{Key, Term};
use notify::{Event as WatchEvent, EventKind as WatchEventKind, RecursiveMode, Watcher};

fn main() {
    let mut args = env::args();
    let _ = args.next();

    let language = match args.next().as_ref().map(|s| s.as_str()) {
        Some("rust") => tree_sitter_rust::language(),
        Some("go") => tree_sitter_go::language(),
        Some("tsx") | Some("typescript") => tree_sitter_typescript::language_tsx(),
        Some("javascript") => tree_sitter_javascript::language(),
        Some("python") => tree_sitter_python::language(),
        Some("ruby") => tree_sitter_ruby::language(),
        Some("markdown") => tree_sitter_md::language(),
        Some(s) => panic!("invalid language passed: {s}"),
        None => panic!("no language passed"),
    };
    let path = args.next().expect("no arg passed");
    let query_path = args.next();
    let src = fs::read_to_string(&path).expect("unable to read file");

    let app = Arc::new(RwLock::new(App::new(
        src.as_bytes(),
        &path,
        query_path.as_ref(),
        language,
    )));

    let watch_fn = |watcher_app: Arc<RwLock<App>>| {
        move |ev| {
            if let Ok(WatchEvent {
                kind: WatchEventKind::Modify(..),
                ..
            }) = ev
            {
                if let Ok(mut locked) = watcher_app.try_write() {
                    locked.reload();
                    locked.draw();
                };
            }
        }
    };

    let mut watcher1 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap();
    watcher1
        .watch(Path::new(&path), RecursiveMode::NonRecursive)
        .unwrap();

    let mut watcher2 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap();
    if let Some(query_path) = query_path {
        watcher2
            .watch(Path::new(&query_path), RecursiveMode::NonRecursive)
            .unwrap();
    }

    let (tx, rx) = mpsc::channel();
    let tx0 = tx.clone();
    thread::spawn(move || {
        let term = Term::stdout();
        loop {
            if let Ok(Key::Char(ev)) = term.read_key() {
                tx0.send(ev).unwrap();
            }
        }
    });

    if let Ok(locked) = app.try_read() {
        locked.draw();
    }

    loop {
        match rx.try_recv() {
            Ok(ev) => {
                if let Ok(mut locked) = app.try_write() {
                    match ev {
                        '>' => locked.increase_indent(),
                        '<' => locked.decrease_indent(),
                        'n' => locked.toggle_ranges(),
                        's' => locked.toggle_source(),
                        'r' => locked.reload(),
                        _ => (),
                    }
                    locked.draw();
                }
            }
            _ => (),
        }
        thread::sleep(Duration::from_millis(10));
    }
}