aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 75a6ebf3cb1e7d21e48240c7823e1897b993e638 (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
mod rope;
mod term;

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

const CTRL_Q: u8 = 17;

fn read_key(stdin: &mut Stdin) -> Result<u8, String> {
    let mut buf = vec![0; 1];
    match stdin.read(&mut buf) {
        Err(err) => {
            return Err(format!("read input: {}", err));
        }
        Ok(0) => {
            return Err(String::from("no input"));
        }
        _ => (),
    }
    return Ok(buf[0]);
}

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 read_key(&mut stdin) {
            Ok(c) => c,
            Err(err) => {
                return Err(err);
            }
        };
        if c == CTRL_Q {
            break;
        }
    }
    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);
    }
}