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 = std::env::args_os().collect(); if args.len() != 2 { println!("Usage: edit "); std::process::exit(1); } if let Err(err) = edit(&args[1]) { println!("FAIL: {}", err); std::process::exit(1); } }