rs-kilo/src/main.rs

81 lines
2.0 KiB
Rust

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
pub mod editor;
pub mod terminal_helpers;
use crate::editor::Editor;
use crate::terminal_helpers::*;
use nix::libc::STDOUT_FILENO;
use nix::sys::termios::Termios;
use std::env;
use std::io::Error;
use std::result::Result;
use std::sync::{Arc, Mutex};
// Much ugliness to get and keep a reference to the original terminal settings
lazy_static! {
// Save terminal flags on start
pub static ref ORIGINAL_TERMIOS: Arc<Mutex<Termios>> = Arc::new(Mutex::new(get_termios(STDOUT_FILENO)));
}
struct OnExit<T: FnOnce() -> ()> {
destructor: Option<T>,
}
impl<T> OnExit<T> where T: FnOnce() -> () {
fn new(destructor: T) -> OnExit<T> {
OnExit {
destructor: Some(destructor),
}
}
}
impl<T> Drop for OnExit<T> where T: FnOnce() -> () {
fn drop(&mut self) {
if self.destructor.is_some() {
let option = self.destructor.take();
let destructor = option.unwrap();
destructor();
}
}
}
fn main() -> Result<(), Error> {
// Save existing Termios settings
lazy_static::initialize(&ORIGINAL_TERMIOS);
// Disable canonical/"cooked" terminal mode
enable_raw_mode();
// Revert raw mode on exit
let _destructor = OnExit::new(disable_raw_mode);
// Initialize the editor
let mut editor = Editor::new();
// Open the file if specified, from the command line
let args: Vec<String> = env::args().collect();
if args.len() >= 2 {
editor.open(&args[1])?;
} else {
editor.set_status_message("HELP: Ctrl-S = save | Ctrl-Q = quit | Ctrl-F = find");
}
// Main input loop. Editor::process_keypress uses an Option Enum as a sentinel.
// `None` is returned on a quit action, in other cases, `Some(())` is returned,
// continuing the loop
loop {
editor.refresh_screen();
if editor.process_keypress().is_none() {
break;
}
}
Ok(())
}