#[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> = Arc::new(Mutex::new(get_termios(STDOUT_FILENO))); } struct OnExit ()> { destructor: Option, } impl OnExit where T: FnOnce() -> () { fn new(destructor: T) -> OnExit { OnExit { destructor: Some(destructor), } } } impl Drop for OnExit 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 = 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(()) }