fix(ux): properly echo characters and do not mess up exit (#44)
This commit is contained in:
parent
20617c0263
commit
8e6dfded7a
3 changed files with 31 additions and 6 deletions
|
|
@ -341,6 +341,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.ws_row, 1);
|
||||
let goodbye_message = format!("{}\n{}Bye from Mosaic!", goto_start_of_last_line, reset_style);
|
||||
|
||||
os_input.unset_raw_mode(0);
|
||||
os_input.get_stdout_writer().write(goodbye_message.as_bytes()).unwrap();
|
||||
os_input.get_stdout_writer().flush().unwrap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use nix::unistd::{read, write, ForkResult, Pid};
|
||||
use nix::fcntl::{fcntl, FcntlArg, OFlag};
|
||||
use nix::sys::termios::{
|
||||
Termios,
|
||||
tcgetattr,
|
||||
cfmakeraw,
|
||||
tcsetattr,
|
||||
|
|
@ -14,6 +15,7 @@ use std::os::unix::io::RawFd;
|
|||
use std::process::{Command, Child};
|
||||
use std::io::{Read, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use std::env;
|
||||
|
||||
|
|
@ -26,6 +28,13 @@ fn into_raw_mode(pid: RawFd) {
|
|||
};
|
||||
}
|
||||
|
||||
fn unset_raw_mode(pid: RawFd, mut orig_termios: Termios) {
|
||||
match tcsetattr(pid, SetArg::TCSANOW, &mut orig_termios) {
|
||||
Ok(_) => {},
|
||||
Err(e) => panic!("error {:?}", e)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_terminal_size_using_fd(fd: RawFd) -> Winsize {
|
||||
// TODO: do this with the nix ioctl
|
||||
use libc::ioctl;
|
||||
|
|
@ -91,10 +100,9 @@ fn handle_command_exit(mut child: Child) {
|
|||
}
|
||||
}
|
||||
|
||||
fn spawn_terminal (file_to_open: Option<PathBuf>) -> (RawFd, RawFd) {
|
||||
fn spawn_terminal (file_to_open: Option<PathBuf>, orig_termios: Termios) -> (RawFd, RawFd) {
|
||||
let (pid_primary, pid_secondary): (RawFd, RawFd) = {
|
||||
let current_termios = tcgetattr(0).unwrap();
|
||||
match forkpty(None, Some(¤t_termios)) {
|
||||
match forkpty(None, Some(&orig_termios)) {
|
||||
Ok(fork_pty_res) => {
|
||||
let pid_primary = fork_pty_res.master;
|
||||
let pid_secondary = match fork_pty_res.fork_result {
|
||||
|
|
@ -134,12 +142,15 @@ fn spawn_terminal (file_to_open: Option<PathBuf>) -> (RawFd, RawFd) {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct OsInputOutput {}
|
||||
pub struct OsInputOutput {
|
||||
orig_termios: Arc<Mutex<Termios>>,
|
||||
}
|
||||
|
||||
pub trait OsApi: Send + Sync {
|
||||
fn get_terminal_size_using_fd(&self, pid: RawFd) -> Winsize;
|
||||
fn set_terminal_size_using_fd(&mut self, pid: RawFd, cols: u16, rows: u16);
|
||||
fn into_raw_mode(&mut self, pid: RawFd);
|
||||
fn unset_raw_mode(&mut self, pid: RawFd);
|
||||
fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> (RawFd, RawFd);
|
||||
fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>;
|
||||
fn write_to_tty_stdin(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>;
|
||||
|
|
@ -160,8 +171,13 @@ impl OsApi for OsInputOutput {
|
|||
fn into_raw_mode(&mut self, pid: RawFd) {
|
||||
into_raw_mode(pid);
|
||||
}
|
||||
fn unset_raw_mode(&mut self, pid: RawFd) {
|
||||
let orig_termios = self.orig_termios.lock().unwrap();
|
||||
unset_raw_mode(pid, orig_termios.clone());
|
||||
}
|
||||
fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> (RawFd, RawFd) {
|
||||
spawn_terminal(file_to_open)
|
||||
let orig_termios = self.orig_termios.lock().unwrap();
|
||||
spawn_terminal(file_to_open, orig_termios.clone())
|
||||
}
|
||||
fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error> {
|
||||
read(pid, buf)
|
||||
|
|
@ -201,5 +217,9 @@ impl Clone for Box<dyn OsApi>
|
|||
}
|
||||
|
||||
pub fn get_os_input () -> OsInputOutput {
|
||||
OsInputOutput {}
|
||||
let current_termios = tcgetattr(0).unwrap();
|
||||
let orig_termios = Arc::new(Mutex::new(current_termios));
|
||||
OsInputOutput {
|
||||
orig_termios
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ pub enum IoEvent {
|
|||
Kill(RawFd),
|
||||
SetTerminalSizeUsingFd(RawFd, u16, u16),
|
||||
IntoRawMode(RawFd),
|
||||
UnsetRawMode(RawFd),
|
||||
TcDrain(RawFd),
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +124,9 @@ impl OsApi for FakeInputOutput {
|
|||
fn into_raw_mode(&mut self, pid: RawFd) {
|
||||
self.io_events.lock().unwrap().push(IoEvent::IntoRawMode(pid));
|
||||
}
|
||||
fn unset_raw_mode(&mut self, pid: RawFd) {
|
||||
self.io_events.lock().unwrap().push(IoEvent::UnsetRawMode(pid));
|
||||
}
|
||||
fn spawn_terminal(&mut self, _file_to_open: Option<PathBuf>) -> (RawFd, RawFd) {
|
||||
let next_terminal_id = { self.read_buffers.lock().unwrap().keys().len() as RawFd + 1 };
|
||||
self.add_terminal(next_terminal_id);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue