unix fixed not fully tested jet

This commit is contained in:
Timon 2018-07-26 16:25:20 +00:00
parent d38f406dc7
commit 1a64a21df2
13 changed files with 85 additions and 154 deletions

View File

@ -27,19 +27,7 @@ use crossterm::raw::IntoRawMode;
use std::{thread, time}; use std::{thread, time};
fn main() { fn main() {
// let context = Context::new(); async_input::read_async();
crossterm();
{
// let screen = ::crossterm::screen::AlternateScreen::from(context.clone());
// screen.into_raw_mode(context.clone());
// async_input::async_reading_on_alternate_screen();
// async_input::test();
// stdin::t();
// stdin::read_line();
// stdin::read_char();
// stdin::read_char();
}
} }
use crossterm::raw::RawTerminal; use crossterm::raw::RawTerminal;
@ -63,29 +51,34 @@ pub fn crossterm() {
let mut raw_screen = RawTerminal::new(&crossterm.context()); let mut raw_screen = RawTerminal::new(&crossterm.context());
raw_screen.enable(); raw_screen.enable();
let mut stdin = input.read_until_async().bytes(); let mut stdin = input.read_async().bytes();
let mut buf = String::new(); let mut buf = String::new();
//
let (term_x, term_y) = term.terminal_size(); // let (term_x, term_y) = term.terminal_size();
let mut command_bar_y = term_y; //
let (curs_x, curs_y) = cursor.pos(); // let mut command_bar_y = term_y;
// let (curs_x, curs_y) = cursor.pos();
let mut counter: u16 = 0 + curs_y; //
let mut counter: u16 = 0;
loop { loop {
cursor.goto(0, counter); // cursor.goto(0, counter);
let (curs_x, curs_y) = cursor.pos(); //
term.write(format!("cursor pos {} term pos: {} command pos: {}", curs_y, term_y, command_bar_y)); // let (curs_x, curs_y) = cursor.pos();
cursor.goto(0, counter + 1); // term.write(format!("cursor pos {} term pos: {} command pos: {}", curs_y, term_y, command_bar_y));
//
if (curs_y >= term_y - 1 ) // cursor.goto(0, counter + 1);
{ //
cursor.goto(0, counter + 1); // if (curs_y >= term_y - 1 )
term.clear(ClearType::CurrentLine); // {
cursor.goto(0, counter + 2); // cursor.goto(0, counter + 1);
// term.clear(ClearType::CurrentLine);
// cursor.goto(0, counter + 2);
// term.write(format!("> {}", buf));
// term.scroll_up(1);
// }
//
term.write(format!("> {}", buf)); term.write(format!("> {}", buf));
term.scroll_up(1);
}
while let Some(b) = stdin.next() { while let Some(b) = stdin.next() {
if let Ok(b) = b { if let Ok(b) = b {

View File

@ -83,8 +83,8 @@ pub fn read_async_demo() {
// get the next pressed key // get the next pressed key
let pressed_key = stdin.next(); let pressed_key = stdin.next();
terminal.write(format!("\r{:?} <- Character pressed", pressed_key));
write!(stdout, "\r{:?} <- Character pressed", pressed_key).unwrap();
// check if pressed key is enter (\r) // check if pressed key is enter (\r)
if let Some(Ok(b'\r')) = pressed_key { if let Some(Ok(b'\r')) = pressed_key {
@ -114,11 +114,6 @@ pub fn async_reading_on_alternate_screen() {
// this will setup the async reading. // this will setup the async reading.
let mut stdin = input.read_async().bytes(); let mut stdin = input.read_async().bytes();
// clear terminal and reset the cursor.
terminal.clear(ClearType::All);
cursor.goto(1, 1);
// panic!();
// loop until the enter key (\r) is pressed. // loop until the enter key (\r) is pressed.
loop { loop {
@ -128,11 +123,7 @@ pub fn async_reading_on_alternate_screen() {
// get the next pressed key // get the next pressed key
let pressed_key = stdin.next(); let pressed_key = stdin.next();
write!( terminal.write(format!("\r{:?} <- Character pressed", pressed_key));
alternate_screen,
"\r{:?} <- Character pressed",
pressed_key
).unwrap();
// check if pressed key is enter (\r) // check if pressed key is enter (\r)
if let Some(Ok(b'\r')) = pressed_key { if let Some(Ok(b'\r')) = pressed_key {

View File

@ -29,11 +29,6 @@ impl ITerminalCursor for AnsiCursor {
functions::get_cursor_position(self.context.clone()) functions::get_cursor_position(self.context.clone())
} }
fn absolute_pos(&self) -> (u16, u16)
{
functions::get_absolute_cursor_pos(&self.context)
}
fn move_up(&self, count: u16) { fn move_up(&self, count: u16) {
let mut screen = self.context.screen_manager.lock().unwrap(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {

View File

@ -86,11 +86,6 @@ impl TerminalCursor {
self.terminal_cursor.pos() self.terminal_cursor.pos()
} }
pub fn absolute_pos(&self) -> (u16, u16)
{
self.terminal_cursor.absolute_pos()
}
/// Move the current cursor position `n` times up. /// Move the current cursor position `n` times up.
/// ///
/// #Example /// #Example

View File

@ -34,9 +34,6 @@ pub trait ITerminalCursor {
fn goto(&self, x: u16, y: u16); fn goto(&self, x: u16, y: u16);
/// Get the location (x,y) of the current cusror in the context /// Get the location (x,y) of the current cusror in the context
fn pos(&self) -> (u16, u16); fn pos(&self) -> (u16, u16);
fn absolute_pos(&self) -> (u16, u16);
/// Move cursor n times up /// Move cursor n times up
fn move_up(&self, count: u16); fn move_up(&self, count: u16);
/// Move the cursor `n` times to the right. /// Move the cursor `n` times to the right.

View File

@ -29,11 +29,6 @@ impl ITerminalCursor for WinApiCursor {
cursor::pos(&self.screen_manager) cursor::pos(&self.screen_manager)
} }
fn absolute_pos(&self) -> (u16, u16)
{
cursor::absolute_cursor_pos(&self.screen_manager)
}
fn move_up(&self, count: u16) { fn move_up(&self, count: u16) {
let (xpos, ypos) = self.pos(); let (xpos, ypos) = self.pos();
self.goto(xpos, ypos - count); self.goto(xpos, ypos - count);

View File

@ -37,12 +37,10 @@ impl ITerminalInput for UnixInput {
fn read_async(&self) -> AsyncReader { fn read_async(&self) -> AsyncReader {
let (send, recv) = mpsc::channel(); let (send, recv) = mpsc::channel();
thread::spawn(move || { thread::spawn(move || for i in get_tty().unwrap().bytes() {
for i in get_tty().unwrap().bytes() {
if send.send(i).is_err() { if send.send(i).is_err() {
return; return;
} }
}
}); });
AsyncReader { recv: recv } AsyncReader { recv: recv }
@ -51,21 +49,16 @@ impl ITerminalInput for UnixInput {
fn read_until_async(&self, delimiter: u8) -> AsyncReader { fn read_until_async(&self, delimiter: u8) -> AsyncReader {
let (send, recv) = mpsc::channel(); let (send, recv) = mpsc::channel();
thread::spawn(move || { thread::spawn(move || for i in get_tty().unwrap().bytes() {
for i in get_tty().unwrap().bytes() {
match i { match i {
Ok(byte) => { Ok(byte) => {
let end_of_stream = &byte == &delimiter; let end_of_stream = &byte == &delimiter;
let send_error = send.send(Ok(byte)).is_err(); let send_error = send.send(Ok(byte)).is_err();
if end_of_stream || send_error { if end_of_stream || send_error { return; }
return; },
} Err(_) => { return; }
}
Err(_) => {
return;
}
}
} }
}); });

View File

@ -2,7 +2,7 @@
pub use self::libc::termios; pub use self::libc::termios;
use self::libc::{c_int, c_ushort, ioctl, STDOUT_FILENO, TIOCGWINSZ}; use self::libc::{c_int, c_ushort, ioctl, STDOUT_FILENO, TIOCGWINSZ};
use state::commands::{IStateCommand, NoncanonicalModeCommand}; use state::commands::{IStateCommand, NoncanonicalModeCommand, EnableRawModeCommand};
use {libc, CommandManager, Context, StateManager}; use {libc, CommandManager, Context, StateManager};
use std::io::Error; use std::io::Error;
@ -19,8 +19,8 @@ pub struct UnixSize {
pub rows: c_ushort, pub rows: c_ushort,
/// number of columns /// number of columns
pub cols: c_ushort, pub cols: c_ushort,
x: c_ushort, pub ws_xpixel: c_ushort,
y: c_ushort, pub ws_ypixel: c_ushort,
} }
/// Get the current terminal size. /// Get the current terminal size.
@ -29,81 +29,75 @@ pub fn terminal_size() -> (u16, u16) {
let us = UnixSize { let us = UnixSize {
rows: 0, rows: 0,
cols: 0, cols: 0,
x: 0, ws_xpixel: 0,
y: 0, ws_ypixel: 0,
}; };
let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) }; let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
if r == 0 { if r == 0 {
// because crossterm works starts counting at 0 and unix terminal starts at cell 1 you have subtract one to get 0-based results. // because crossterm works starts counting at 0 and unix terminal starts at cell 1 you have subtract one to get 0-based results.
(us.cols - 1, us.rows - 1) (us.cols - 1, us.rows - 1)
} else { } else {
(0, 0) (0, 0)
} }
} }
use std::time::{SystemTime, Duration};
use std::io::ErrorKind;
use Crossterm;
use std::io::Read;
/// Get the current cursor position. /// Get the current cursor position.
pub fn pos(context: Rc<Context>) -> (u16, u16) { pub fn pos(context: Rc<Context>) -> (u16, u16) {
use std::io::{Read, Write}; let crossterm = Crossterm::from(context.clone());
let input = crossterm.input();
let mut command_id = NoncanonicalModeCommand::new(&context.state_manager); let delimiter = b'R';
let mut stdin = input.read_until_async(delimiter);
CommandManager::execute(context.clone(), command_id); // Where is the cursor?
// Use `ESC [ 6 n`.
// This code is original written by term_cursor credits to them. crossterm.write("\x1B[6n");
use std::io;
let mut std = io::stdout();
// Write command
std.write(b"\x1B[6n");
std.flush();
// Read back result let mut buf: [u8; 1] = [0];
let mut buf = [0u8; 2]; let mut read_chars = Vec::new();
// Expect `ESC[`
io::stdin().read_exact(&mut buf); let timeout = Duration::from_millis(2000);
if buf[0] != 0x1B || buf[1] as char != '[' { let now = SystemTime::now();
// Either consume all data up to R or wait for a timeout.
while buf[0] != delimiter && now.elapsed().unwrap() < timeout {
if let Ok(c) = stdin.read(&mut buf){
if c >= 0
{
read_chars.push(buf[0]);
}
}
}
if read_chars.len() == 0 {
return (0, 0); return (0, 0);
} }
// Read rows and cols through a ad-hoc integer parsing function // The answer will look like `ESC [ Cy ; Cx R`.
let read_num = || -> (i32, char) {
let mut num = 0;
let mut c;
loop { read_chars.pop(); // remove trailing R.
let mut buf = [0u8; 1]; let read_str = String::from_utf8(read_chars).unwrap();
io::stdin().read_exact(&mut buf); let beg = read_str.rfind('[').unwrap();
c = buf[0] as char; let coords: String = read_str.chars().skip(beg + 1).collect();
if let Some(d) = c.to_digit(10) { let mut nums = coords.split(';');
num = if num == 0 { 0 } else { num * 10 };
num += d as i32;
} else {
break;
}
}
(num, c) let cy = nums.next()
}; .unwrap()
.parse::<u16>()
.unwrap();
let cx = nums.next()
.unwrap()
.parse::<u16>()
.unwrap();
// Read rows and expect `;` (cx, cy)
let (rows, c) = read_num();
if c != ';' {
return (0, 0);
}
// Read cols
let (cols, c) = read_num();
// Expect `R`
let res = if c == 'R' {
(cols as u16, rows as u16)
} else {
return (0, 0);
};
CommandManager::undo(context.clone(), command_id);
res
} }
/// Set the terminal mode to the given mode. /// Set the terminal mode to the given mode.

View File

@ -32,16 +32,6 @@ pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16) {
return pos(&context.screen_manager); return pos(&context.screen_manager);
} }
pub fn get_buffer_size(context: &Rc<Context>) -> (u16, u16)
{
return buffer_size(&context.screen_manager);
}
pub fn get_absolute_cursor_pos(context: &Rc<Context>) -> (u16, u16)
{
return absolute_cursor_pos(&context.screen_manager);
}
/// exit the current terminal. /// exit the current terminal.
pub fn exit_terminal() { pub fn exit_terminal() {
#[cfg(unix)] #[cfg(unix)]

View File

@ -45,8 +45,6 @@ impl ITerminal for AnsiTerminal {
functions::get_terminal_size(&self.context.screen_manager) functions::get_terminal_size(&self.context.screen_manager)
} }
fn buffer_size(&self) -> (u16, u16) { functions::get_buffer_size(&self.context) }
fn scroll_up(&self, count: i16) { fn scroll_up(&self, count: i16) {
let mut screen = self.context.screen_manager.lock().unwrap(); let mut screen = self.context.screen_manager.lock().unwrap();
{ {

View File

@ -42,10 +42,6 @@ pub trait ITerminal {
fn clear(&self, clear_type: ClearType); fn clear(&self, clear_type: ClearType);
/// Get the terminal size (x,y) /// Get the terminal size (x,y)
fn terminal_size(&self) -> (u16, u16); fn terminal_size(&self) -> (u16, u16);
// get the size of the current buffer
fn buffer_size(&self) -> (u16, u16);
/// Scroll `n` lines up in the current terminal. /// Scroll `n` lines up in the current terminal.
fn scroll_up(&self, count: i16); fn scroll_up(&self, count: i16);
/// Scroll `n` lines down in the current terminal. /// Scroll `n` lines down in the current terminal.

View File

@ -85,10 +85,6 @@ impl Terminal {
return self.terminal.terminal_size(); return self.terminal.terminal_size();
} }
pub fn buffer_size(&self) -> (u16, u16) {
return self.terminal.buffer_size();
}
/// Scroll `n` lines up in the current terminal. /// Scroll `n` lines up in the current terminal.
/// ///
/// #Example /// #Example

View File

@ -40,8 +40,6 @@ impl ITerminal for WinApiTerminal {
terminal::terminal_size(&self.context.screen_manager) terminal::terminal_size(&self.context.screen_manager)
} }
fn buffer_size(&self) -> (u16, u16) {terminal::buffer_size(&self.context.screen_manager)}
fn scroll_up(&self, count: i16) { fn scroll_up(&self, count: i16) {
let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap(); let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap();