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};
|
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.write(format!("> {}", buf));
|
// term.clear(ClearType::CurrentLine);
|
||||||
term.scroll_up(1);
|
// cursor.goto(0, counter + 2);
|
||||||
}
|
// term.write(format!("> {}", buf));
|
||||||
|
// term.scroll_up(1);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
term.write(format!("> {}", buf));
|
||||||
|
|
||||||
while let Some(b) = stdin.next() {
|
while let Some(b) = stdin.next() {
|
||||||
if let Ok(b) = b {
|
if let Ok(b) = b {
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -37,11 +37,9 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -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 {
|
|
||||||
Ok(byte) => {
|
|
||||||
let end_of_stream = &byte == &delimiter;
|
|
||||||
let send_error = send.send(Ok(byte)).is_err();
|
|
||||||
|
|
||||||
if end_of_stream || send_error {
|
match i {
|
||||||
return;
|
Ok(byte) => {
|
||||||
}
|
let end_of_stream = &byte == &delimiter;
|
||||||
}
|
let send_error = send.send(Ok(byte)).is_err();
|
||||||
Err(_) => {
|
|
||||||
return;
|
if end_of_stream || send_error { return; }
|
||||||
}
|
},
|
||||||
}
|
Err(_) => { return; }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
if buf[0] != 0x1B || buf[1] as char != '[' {
|
|
||||||
return (0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read rows and cols through a ad-hoc integer parsing function
|
let timeout = Duration::from_millis(2000);
|
||||||
let read_num = || -> (i32, char) {
|
let now = SystemTime::now();
|
||||||
let mut num = 0;
|
|
||||||
let mut c;
|
|
||||||
|
|
||||||
loop {
|
// Either consume all data up to R or wait for a timeout.
|
||||||
let mut buf = [0u8; 1];
|
while buf[0] != delimiter && now.elapsed().unwrap() < timeout {
|
||||||
io::stdin().read_exact(&mut buf);
|
if let Ok(c) = stdin.read(&mut buf){
|
||||||
c = buf[0] as char;
|
if c >= 0
|
||||||
if let Some(d) = c.to_digit(10) {
|
{
|
||||||
num = if num == 0 { 0 } else { num * 10 };
|
read_chars.push(buf[0]);
|
||||||
num += d as i32;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(num, c)
|
if read_chars.len() == 0 {
|
||||||
};
|
|
||||||
|
|
||||||
// Read rows and expect `;`
|
|
||||||
let (rows, c) = read_num();
|
|
||||||
|
|
||||||
if c != ';' {
|
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read cols
|
// The answer will look like `ESC [ Cy ; Cx R`.
|
||||||
let (cols, c) = read_num();
|
|
||||||
|
|
||||||
// Expect `R`
|
read_chars.pop(); // remove trailing R.
|
||||||
let res = if c == 'R' {
|
let read_str = String::from_utf8(read_chars).unwrap();
|
||||||
(cols as u16, rows as u16)
|
let beg = read_str.rfind('[').unwrap();
|
||||||
} else {
|
let coords: String = read_str.chars().skip(beg + 1).collect();
|
||||||
return (0, 0);
|
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.
|
/// 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);
|
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)]
|
||||||
|
@ -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();
|
||||||
{
|
{
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user