unix fixed not fully tested jet
This commit is contained in:
parent
d38f406dc7
commit
1a64a21df2
@ -27,19 +27,7 @@ use crossterm::raw::IntoRawMode;
|
||||
use std::{thread, time};
|
||||
|
||||
fn main() {
|
||||
// let context = Context::new();
|
||||
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();
|
||||
}
|
||||
async_input::read_async();
|
||||
}
|
||||
|
||||
use crossterm::raw::RawTerminal;
|
||||
@ -63,29 +51,34 @@ pub fn crossterm() {
|
||||
let mut raw_screen = RawTerminal::new(&crossterm.context());
|
||||
raw_screen.enable();
|
||||
|
||||
let mut stdin = input.read_until_async().bytes();
|
||||
let mut stdin = input.read_async().bytes();
|
||||
|
||||
let mut buf = String::new();
|
||||
|
||||
let (term_x, term_y) = term.terminal_size();
|
||||
let mut command_bar_y = term_y;
|
||||
let (curs_x, curs_y) = cursor.pos();
|
||||
|
||||
let mut counter: u16 = 0 + curs_y;
|
||||
//
|
||||
// let (term_x, term_y) = term.terminal_size();
|
||||
//
|
||||
// let mut command_bar_y = term_y;
|
||||
// let (curs_x, curs_y) = cursor.pos();
|
||||
//
|
||||
let mut counter: u16 = 0;
|
||||
loop {
|
||||
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));
|
||||
cursor.goto(0, counter + 1);
|
||||
|
||||
if (curs_y >= term_y - 1 )
|
||||
{
|
||||
cursor.goto(0, counter + 1);
|
||||
term.clear(ClearType::CurrentLine);
|
||||
cursor.goto(0, counter + 2);
|
||||
term.write(format!("> {}", buf));
|
||||
term.scroll_up(1);
|
||||
}
|
||||
// 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));
|
||||
//
|
||||
// cursor.goto(0, counter + 1);
|
||||
//
|
||||
// if (curs_y >= term_y - 1 )
|
||||
// {
|
||||
// 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));
|
||||
|
||||
while let Some(b) = stdin.next() {
|
||||
if let Ok(b) = b {
|
||||
|
@ -83,8 +83,8 @@ pub fn read_async_demo() {
|
||||
|
||||
// get the next pressed key
|
||||
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)
|
||||
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.
|
||||
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 {
|
||||
@ -128,11 +123,7 @@ pub fn async_reading_on_alternate_screen() {
|
||||
// get the next pressed key
|
||||
let pressed_key = stdin.next();
|
||||
|
||||
write!(
|
||||
alternate_screen,
|
||||
"\r{:?} <- Character pressed",
|
||||
pressed_key
|
||||
).unwrap();
|
||||
terminal.write(format!("\r{:?} <- Character pressed", pressed_key));
|
||||
|
||||
// check if pressed key is enter (\r)
|
||||
if let Some(Ok(b'\r')) = pressed_key {
|
||||
|
@ -29,11 +29,6 @@ impl ITerminalCursor for AnsiCursor {
|
||||
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) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
|
@ -86,11 +86,6 @@ impl TerminalCursor {
|
||||
self.terminal_cursor.pos()
|
||||
}
|
||||
|
||||
pub fn absolute_pos(&self) -> (u16, u16)
|
||||
{
|
||||
self.terminal_cursor.absolute_pos()
|
||||
}
|
||||
|
||||
/// Move the current cursor position `n` times up.
|
||||
///
|
||||
/// #Example
|
||||
|
@ -34,9 +34,6 @@ pub trait ITerminalCursor {
|
||||
fn goto(&self, x: u16, y: u16);
|
||||
/// Get the location (x,y) of the current cusror in the context
|
||||
fn pos(&self) -> (u16, u16);
|
||||
|
||||
fn absolute_pos(&self) -> (u16, u16);
|
||||
|
||||
/// Move cursor n times up
|
||||
fn move_up(&self, count: u16);
|
||||
/// Move the cursor `n` times to the right.
|
||||
|
@ -29,11 +29,6 @@ impl ITerminalCursor for WinApiCursor {
|
||||
cursor::pos(&self.screen_manager)
|
||||
}
|
||||
|
||||
fn absolute_pos(&self) -> (u16, u16)
|
||||
{
|
||||
cursor::absolute_cursor_pos(&self.screen_manager)
|
||||
}
|
||||
|
||||
fn move_up(&self, count: u16) {
|
||||
let (xpos, ypos) = self.pos();
|
||||
self.goto(xpos, ypos - count);
|
||||
|
@ -37,11 +37,9 @@ impl ITerminalInput for UnixInput {
|
||||
fn read_async(&self) -> AsyncReader {
|
||||
let (send, recv) = mpsc::channel();
|
||||
|
||||
thread::spawn(move || {
|
||||
for i in get_tty().unwrap().bytes() {
|
||||
if send.send(i).is_err() {
|
||||
return;
|
||||
}
|
||||
thread::spawn(move || for i in get_tty().unwrap().bytes() {
|
||||
if send.send(i).is_err() {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
@ -51,21 +49,16 @@ impl ITerminalInput for UnixInput {
|
||||
fn read_until_async(&self, delimiter: u8) -> AsyncReader {
|
||||
let (send, recv) = mpsc::channel();
|
||||
|
||||
thread::spawn(move || {
|
||||
for i in get_tty().unwrap().bytes() {
|
||||
match i {
|
||||
Ok(byte) => {
|
||||
let end_of_stream = &byte == &delimiter;
|
||||
let send_error = send.send(Ok(byte)).is_err();
|
||||
thread::spawn(move || for i in get_tty().unwrap().bytes() {
|
||||
|
||||
if end_of_stream || send_error {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
match i {
|
||||
Ok(byte) => {
|
||||
let end_of_stream = &byte == &delimiter;
|
||||
let send_error = send.send(Ok(byte)).is_err();
|
||||
|
||||
if end_of_stream || send_error { return; }
|
||||
},
|
||||
Err(_) => { return; }
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
pub use self::libc::termios;
|
||||
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 std::io::Error;
|
||||
@ -19,8 +19,8 @@ pub struct UnixSize {
|
||||
pub rows: c_ushort,
|
||||
/// number of columns
|
||||
pub cols: c_ushort,
|
||||
x: c_ushort,
|
||||
y: c_ushort,
|
||||
pub ws_xpixel: c_ushort,
|
||||
pub ws_ypixel: c_ushort,
|
||||
}
|
||||
|
||||
/// Get the current terminal size.
|
||||
@ -29,81 +29,75 @@ pub fn terminal_size() -> (u16, u16) {
|
||||
let us = UnixSize {
|
||||
rows: 0,
|
||||
cols: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
ws_xpixel: 0,
|
||||
ws_ypixel: 0,
|
||||
};
|
||||
let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
|
||||
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.
|
||||
(us.cols - 1, us.rows - 1)
|
||||
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use std::time::{SystemTime, Duration};
|
||||
use std::io::ErrorKind;
|
||||
use Crossterm;
|
||||
use std::io::Read;
|
||||
/// Get the current cursor position.
|
||||
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.
|
||||
use std::io;
|
||||
let mut std = io::stdout();
|
||||
// Write command
|
||||
std.write(b"\x1B[6n");
|
||||
std.flush();
|
||||
crossterm.write("\x1B[6n");
|
||||
|
||||
// Read back result
|
||||
let mut buf = [0u8; 2];
|
||||
// Expect `ESC[`
|
||||
io::stdin().read_exact(&mut buf);
|
||||
if buf[0] != 0x1B || buf[1] as char != '[' {
|
||||
return (0, 0);
|
||||
}
|
||||
let mut buf: [u8; 1] = [0];
|
||||
let mut read_chars = Vec::new();
|
||||
|
||||
// Read rows and cols through a ad-hoc integer parsing function
|
||||
let read_num = || -> (i32, char) {
|
||||
let mut num = 0;
|
||||
let mut c;
|
||||
let timeout = Duration::from_millis(2000);
|
||||
let now = SystemTime::now();
|
||||
|
||||
loop {
|
||||
let mut buf = [0u8; 1];
|
||||
io::stdin().read_exact(&mut buf);
|
||||
c = buf[0] as char;
|
||||
if let Some(d) = c.to_digit(10) {
|
||||
num = if num == 0 { 0 } else { num * 10 };
|
||||
num += d as i32;
|
||||
} else {
|
||||
break;
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(num, c)
|
||||
};
|
||||
|
||||
// Read rows and expect `;`
|
||||
let (rows, c) = read_num();
|
||||
|
||||
if c != ';' {
|
||||
if read_chars.len() == 0 {
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
// Read cols
|
||||
let (cols, c) = read_num();
|
||||
// The answer will look like `ESC [ Cy ; Cx R`.
|
||||
|
||||
// Expect `R`
|
||||
let res = if c == 'R' {
|
||||
(cols as u16, rows as u16)
|
||||
} else {
|
||||
return (0, 0);
|
||||
};
|
||||
read_chars.pop(); // remove trailing R.
|
||||
let read_str = String::from_utf8(read_chars).unwrap();
|
||||
let beg = read_str.rfind('[').unwrap();
|
||||
let coords: String = read_str.chars().skip(beg + 1).collect();
|
||||
let mut nums = coords.split(';');
|
||||
|
||||
CommandManager::undo(context.clone(), command_id);
|
||||
let cy = nums.next()
|
||||
.unwrap()
|
||||
.parse::<u16>()
|
||||
.unwrap();
|
||||
let cx = nums.next()
|
||||
.unwrap()
|
||||
.parse::<u16>()
|
||||
.unwrap();
|
||||
|
||||
res
|
||||
(cx, cy)
|
||||
}
|
||||
|
||||
/// Set the terminal mode to the given mode.
|
||||
|
@ -32,16 +32,6 @@ pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16) {
|
||||
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.
|
||||
pub fn exit_terminal() {
|
||||
#[cfg(unix)]
|
||||
|
@ -45,8 +45,6 @@ impl ITerminal for AnsiTerminal {
|
||||
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) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
|
@ -42,10 +42,6 @@ pub trait ITerminal {
|
||||
fn clear(&self, clear_type: ClearType);
|
||||
/// Get the terminal size (x,y)
|
||||
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.
|
||||
fn scroll_up(&self, count: i16);
|
||||
/// Scroll `n` lines down in the current terminal.
|
||||
|
@ -85,10 +85,6 @@ impl Terminal {
|
||||
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.
|
||||
///
|
||||
/// #Example
|
||||
|
@ -40,8 +40,6 @@ impl ITerminal for WinApiTerminal {
|
||||
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) {
|
||||
let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user