aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 592f89ca0c9bbbfa3f309f3310ab4ee3f7e1532c (plain) (blame)
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
mod rope;
mod term;

use rope::Rope;
use std::ffi::{OsStr, OsString};
use std::io::Write;
use std::path::Path;
use term::Key;

fn edit(file: &OsStr) -> Result<(), String> {
    let _raw_handle = match term::raw() {
        Some(h) => h,
        None => {
            return Err(String::from("cannot put terminal in raw mode"));
        }
    };

    let r = match Rope::open(Path::new(file)) {
        Ok(r) => r,
        Err(err) => {
            return Err(format!("open file {}: {}", file.to_string_lossy(), err));
        }
    };
    let size = match term::size() {
        Some(size) => size,
        None => {
            return Err(String::from("cannot get terminal size"));
        }
    };
    let mut stdout = std::io::stdout();
    for i in 0..usize::from(size.ws_row) {
        if i > 0 {
            let _ = stdout.write(b"\r\n");
        }
        let _ = r.print_line(&mut stdout, i);
    }
    let _ = stdout.flush();

    let mut stdin = std::io::stdin();
    loop {
        let c = match term::read_key(&mut stdin) {
            Ok(c) => c,
            Err(err) => {
                return Err(err);
            }
        };
        match c {
            Key::CtrlQ => {
                break;
            }
            Key::Up => {
                let _ = stdout.write(b"\x1b[A");
                let _ = stdout.flush();
            }
            Key::Down => {
                let _ = stdout.write(b"\x1b[B");
                let _ = stdout.flush();
            }
            Key::Left => {
                let _ = stdout.write(b"\x1b[D");
                let _ = stdout.flush();
            }
            Key::Right => {
                let _ = stdout.write(b"\x1b[C");
                let _ = stdout.flush();
            }
            Key::Char(c) => {
                print!("{} ", c);
                let _ = stdout.flush();
            }
        }
    }
    return Ok(());
}

fn main() {
    let args: Vec<OsString> = std::env::args_os().collect();
    if args.len() != 2 {
        println!("Usage: edit <filename>");
        std::process::exit(1);
    }
    if let Err(err) = edit(&args[1]) {
        println!("FAIL: {}", err);
        std::process::exit(1);
    }
}