really ugly progress commit

This commit is contained in:
Timothy Warren 2019-08-22 16:44:47 -04:00
parent 6c967fe499
commit 144fd65412
3 changed files with 147 additions and 103 deletions

View File

@ -1,11 +1,71 @@
//! Editor functionality
use crate::helpers::*;
pub struct Editor {}
use nix::sys::termios::Termios;
use nix::unistd::read;
use std::io;
use std::io::{BufReader, Error, Stdin};
use std::io::prelude::*;
use term_parser::{Action, ActionIter};
/// Main structure for the editor
pub struct Editor {
/// Reference to terminal settings before setting up raw mode
original_termios: Termios,
}
impl Editor {
pub fn new() -> Self {
Editor {
original_termios: get_termios(STDIN_FILENO)
}
}
fn read_key(&mut self) -> char {
let stdin = io::stdin();
let mut in_str = String::new();
let mut input = BufReader::new(stdin.take(1));
input.read_to_string(&mut in_str).unwrap();
let mut chars = in_str.chars();
chars.next().unwrap()
}
fn read_term_code(&mut self) -> ActionIter<BufReader<Stdin>> {
let stdin = io::stdin();
let buffer = BufReader::new(stdin);
let term_code_iter = ActionIter::new(buffer);
term_code_iter
}
pub fn process_keypress(&mut self) -> Option<()> {
for term_code in self.read_term_code() {
let term_code = match term_code {
Ok(code) => code,
Err(e) => panic!("{:?}\r\n", e),
};
print!("{:?}\r\n", term_code);
}
/* let char = self.read_key();
if char == 'q' {
disable_raw_mode(&self.original_termios)?;
// Break out of the input loop
return None;
}
// Echo characters
if is_cntrl(char) {
print!("{}\r\n", char as u8);
} else {
print!("{} ('{}')\r\n", char as u8, char);
} */
Some(())
}
}

View File

@ -1,7 +1,25 @@
/// Helper functions, especially to reproduce C std/posix functions
use nix::errno::*;
use nix::Error as NixError;
use nix::sys::termios;
use nix::sys::termios::{
ControlFlags,
InputFlags,
LocalFlags,
OutputFlags,
SpecialCharacterIndices,
Termios
};
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;
/// Is this character an ASCII control character?
pub fn is_cntrl(c: char) -> bool {
let code = c as u8;
@ -13,4 +31,63 @@ 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")
}
}
}

View File

@ -1,108 +1,15 @@
use nix::Error as NixError;
use nix::sys::termios;
use nix::sys::termios::{InputFlags, LocalFlags, OutputFlags, SpecialCharacterIndices, Termios};
use std::io;
use std::io::{BufReader, Error};
use std::io::prelude::*;
use term_parser::ActionIter;
mod editor;
mod helpers;
// use crate::editor::Editor;
use crate::helpers::*;
use crate::editor::Editor;
use crate::helpers::{STDIN_FILENO, enable_raw_mode};
// Redefine the posix constants for rust land
const STDIN_FILENO: i32 = 0;
// const STDOUT_FILENO: i32 = 1;
// const STDERR_FILENO: i32 = 2;
fn main() {
enable_raw_mode().unwrap();
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")
}
let mut editor = Editor::new();
while editor.process_keypress().is_some() {
// loop
}
}
fn enable_raw_mode() -> Result<(), Error> {
let mut raw = termios::tcgetattr(STDIN_FILENO).unwrap();
raw.input_flags.remove(
InputFlags::BRKINT &
InputFlags::ICRNL &
InputFlags::INPCK &
InputFlags::ISTRIP &
InputFlags::IXON
);
raw.output_flags.remove(OutputFlags::OPOST);
raw.local_flags.remove(
LocalFlags::ECHO &
LocalFlags::ICANON &
LocalFlags::IEXTEN &
LocalFlags::ISIG
);
// 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")
}
}
}
fn main() -> Result<(), Error> {
let orig_termios = termios::tcgetattr(STDIN_FILENO).unwrap();
enable_raw_mode()?;
let stdin = io::stdin();
let buffer = BufReader::new(stdin);
let term_code_iter = ActionIter::new(buffer);
for term_code in term_code_iter {
let term_code = match term_code {
Ok(code) => code,
Err(e) => panic!("{:?}", e),
};
println!("\r{:?}", term_code);
}
Ok(())
// loop {
// let stdin = io::stdin();
// let mut in_str = String::new();
// let mut input = BufReader::new(stdin.take(1));
// input.read_to_string(&mut in_str)?;
//
// let mut chars = in_str.chars();
// let char = chars.next().unwrap();
//
// if char == 'q' {
// return disable_raw_mode(&orig_termios);
// }
//
// // Echo characters
// if is_cntrl(char) {
// print!("{}\r\n", char as u8);
// continue;
// } else {
// print!("{} ('{}')\r\n", char as u8, char);
// continue;
// }
// }
}