rs-kilo/src/helpers.rs

80 lines
2.2 KiB
Rust

/// Helper functions, especially to reproduce C std/posix functions
use nix::errno::*;
use nix::sys::termios;
use nix::sys::termios::{
ControlFlags, InputFlags, LocalFlags, OutputFlags, SpecialCharacterIndices, Termios,
};
use nix::Error as NixError;
use std::io::Error;
use std::os::unix::io::RawFd;
use std::process::exit;
// Redefine the posix constants for rust land
pub const STDIN_FILENO: i32 = 0;
// pub const STDOUT_FILENO: i32 = 1;
// pub const STDERR_FILENO: i32 = 2;
pub fn die(code: &Errno, msg: &str) -> ! {
eprintln!("{:?} ({})", code, msg);
exit(1)
}
pub fn get_termios(fd: RawFd) -> Termios {
termios::tcgetattr(fd).unwrap()
}
pub fn enable_raw_mode() -> Result<(), Error> {
let mut raw = get_termios(STDIN_FILENO);
raw.input_flags.remove(
InputFlags::BRKINT
| InputFlags::IGNCR
| InputFlags::IGNBRK
| InputFlags::ICRNL
| InputFlags::INLCR
| InputFlags::INPCK
| InputFlags::ISTRIP
| InputFlags::IXON
| InputFlags::PARMRK,
);
raw.output_flags.remove(OutputFlags::OPOST);
raw.local_flags.remove(
LocalFlags::ECHO
| LocalFlags::ECHONL
| LocalFlags::ICANON
| LocalFlags::IEXTEN
| LocalFlags::ISIG,
);
raw.control_flags
.remove(ControlFlags::CSIZE | ControlFlags::PARENB);
// 8 bit characters
raw.control_flags |= termios::ControlFlags::CS8;
raw.control_chars[SpecialCharacterIndices::VMIN as usize] = 0;
raw.control_chars[SpecialCharacterIndices::VTIME as usize] = 1;
match termios::tcsetattr(STDIN_FILENO, termios::SetArg::TCSAFLUSH, &raw) {
Ok(()) => Ok(()),
Err(e) => match e.as_errno() {
Some(errno) => die(&errno, "tcsetattr"),
None => panic!("Failed to enable raw mode"),
},
}
}
pub fn disable_raw_mode(original: &Termios) -> Result<(), Error> {
match termios::tcsetattr(STDIN_FILENO, termios::SetArg::TCSAFLUSH, original) {
Ok(()) => Ok(()),
Err(E) => match E.as_errno() {
Some(errno) => die(&errno, "tcsetattr"),
None => panic!("Failed to disable raw mode"),
},
}
}