Upgrade crossterm (#1288)

* WIP

* Finish porting to new crossterm

* Fmt
This commit is contained in:
Jonathan Turner 2020-01-27 15:51:46 +13:00 committed by GitHub
parent 32dfb32741
commit 6da9e2aced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 168 additions and 172 deletions

116
Cargo.lock generated
View File

@ -51,6 +51,12 @@ dependencies = [
"xdg", "xdg",
] ]
[[package]]
name = "arc-swap"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff"
[[package]] [[package]]
name = "arrayref" name = "arrayref"
version = "0.3.5" version = "0.3.5"
@ -575,92 +581,25 @@ dependencies = [
[[package]] [[package]]
name = "crossterm" name = "crossterm"
version = "0.10.2" version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9abce7d7c50e9823ea0c0dbeb8f16d7e247af06d75b4c6244ea0a0998b3a6f35" checksum = "5750773d74a7dc612eac2ded3f55e9cdeeaa072210cd17c0192aedb48adb3618"
dependencies = [
"crossterm_cursor",
"crossterm_input",
"crossterm_screen",
"crossterm_style",
"crossterm_terminal",
"crossterm_utils",
]
[[package]]
name = "crossterm_cursor"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb4bfd085f17d83e6cd2943f0150d3b4331e465de8dba1750d1966192faf63dc"
dependencies = [
"crossterm_utils",
"crossterm_winapi",
"winapi 0.3.8",
]
[[package]]
name = "crossterm_input"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6dd255ca05a596bae31ec392fdb67a829509bb767213f00f37c6b62814db663"
dependencies = [
"crossterm_screen",
"crossterm_utils",
"crossterm_winapi",
"libc",
"winapi 0.3.8",
]
[[package]]
name = "crossterm_screen"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf294484fc34c22d514c41afc0b97ce74e10ea54d6eb5fe4806d1e1ac0f7b76"
dependencies = [
"crossterm_utils",
"crossterm_winapi",
"winapi 0.3.8",
]
[[package]]
name = "crossterm_style"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b950f8262e29a446a8a976e0290b67a9067ddc9620f9fb37961d2377f0d8c09"
dependencies = [
"crossterm_utils",
"crossterm_winapi",
"winapi 0.3.8",
]
[[package]]
name = "crossterm_terminal"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8546b519e0c26aa1f43a4a4ea45ccb41eaca74b9a753ea1788f9ad90212636"
dependencies = [
"crossterm_cursor",
"crossterm_utils",
"crossterm_winapi",
"libc",
]
[[package]]
name = "crossterm_utils"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f874a71b2040c730669ddff805c9bc2a1a2f6de9d7f6aab2ae8d29ccbf8a0617"
dependencies = [ dependencies = [
"bitflags",
"crossterm_winapi", "crossterm_winapi",
"lazy_static 1.4.0",
"libc", "libc",
"mio",
"parking_lot",
"signal-hook",
"winapi 0.3.8", "winapi 0.3.8",
] ]
[[package]] [[package]]
name = "crossterm_winapi" name = "crossterm_winapi"
version = "0.1.5" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b055e7cc627c452e6a9b977022f48a2db6f0ff73df446ca970f95eef9c381d45" checksum = "8777c700901e2d5b50c406f736ed6b8f9e43645c7e104ddb74f8bc42b8ae62f6"
dependencies = [ dependencies = [
"winapi 0.3.8", "winapi 0.3.8",
] ]
@ -1610,9 +1549,9 @@ dependencies = [
[[package]] [[package]]
name = "image" name = "image"
version = "0.22.3" version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4be8aaefbe7545dc42ae925afb55a0098f226a3fe5ef721872806f44f57826" checksum = "53cb19c4e35102e5c6fb9ade5e0e236c5588424dc171a849af3141bf0b47768a"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"jpeg-decoder", "jpeg-decoder",
@ -3678,6 +3617,27 @@ dependencies = [
"dirs 2.0.2", "dirs 2.0.2",
] ]
[[package]]
name = "signal-hook"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10b9f3a1686a29f53cfd91ee5e3db3c12313ec02d33765f02c1a9645a1811e2c"
dependencies = [
"libc",
"mio",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-registry"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
dependencies = [
"arc-swap",
"libc",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.2" version = "0.4.2"

View File

@ -131,7 +131,7 @@ heim = {version = "0.0.9", optional = true}
battery = {version = "0.7.5", optional = true} battery = {version = "0.7.5", optional = true}
syntect = {version = "3.2.0", optional = true } syntect = {version = "3.2.0", optional = true }
onig_sys = {version = "=69.1.0", optional = true } onig_sys = {version = "=69.1.0", optional = true }
crossterm = {version = "0.10.2", optional = true} crossterm = {version = "0.14.2", optional = true}
url = {version = "2.1.1", optional = true} url = {version = "2.1.1", optional = true}
semver = {version = "0.9.0", optional = true} semver = {version = "0.9.0", optional = true}

View File

@ -171,7 +171,7 @@ impl TreeFrame {
write!( write!(
f, f,
"{}", "{}",
Color::Black.bold().paint(&format!("({})", self.token_desc)) Color::White.bold().paint(&format!("({})", self.token_desc))
)?; )?;
write!(f, " -> ")?; write!(f, " -> ")?;
@ -196,7 +196,7 @@ impl TreeFrame {
write!( write!(
f, f,
"{}", "{}",
Color::Black.bold().paint(&format!("({})", self.token_desc)) Color::White.bold().paint(&format!("({})", self.token_desc))
) )
} }
} }
@ -305,7 +305,7 @@ impl TreeChild {
for (i, (desc, err_desc)) in desc.iter().enumerate() { for (i, (desc, err_desc)) in desc.iter().enumerate() {
write!(f, "{}", Color::White.bold().on(Color::Red).paint(*desc))?; write!(f, "{}", Color::White.bold().on(Color::Red).paint(*desc))?;
write!(f, " {}", Color::Black.bold().paint(*err_desc))?; write!(f, " {}", Color::White.bold().paint(*err_desc))?;
if i != last { if i != last {
write!(f, "{}", Color::White.normal().paint(", "))?; write!(f, "{}", Color::White.normal().paint(", "))?;

View File

@ -8,13 +8,13 @@ license = "MIT"
[dependencies] [dependencies]
ansi_term = "0.12.1" ansi_term = "0.12.1"
crossterm = { version = "0.10.2" } crossterm = { version = "0.14.2" }
nu-plugin = { path = "../nu-plugin", version="0.8.0" } nu-plugin = { path = "../nu-plugin", version="0.8.0" }
nu-protocol = { path = "../nu-protocol", version = "0.8.0" } nu-protocol = { path = "../nu-protocol", version = "0.8.0" }
nu-source = { path = "../nu-source", version = "0.8.0" } nu-source = { path = "../nu-source", version = "0.8.0" }
nu-errors = { path = "../nu-errors", version = "0.8.0" } nu-errors = { path = "../nu-errors", version = "0.8.0" }
pretty-hex = "0.1.1" pretty-hex = "0.1.1"
image = { version = "0.22.3", default_features = false, features = ["png_codec", "jpeg"] } image = { version = "0.22.4", default_features = false, features = ["png_codec", "jpeg"] }
rawkey = "0.1.2" rawkey = "0.1.2"
neso = "0.5.0" neso = "0.5.0"

View File

@ -1,4 +1,4 @@
use crossterm::{cursor, terminal, Attribute, RawScreen}; use crossterm::{style::Attribute, ExecutableCommand};
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_plugin::{serve_plugin, Plugin}; use nu_plugin::{serve_plugin, Plugin};
use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value}; use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value};
@ -71,8 +71,7 @@ impl RenderContext {
let mut prev_color: Option<(u8, u8, u8)> = None; let mut prev_color: Option<(u8, u8, u8)> = None;
let mut prev_count = 1; let mut prev_count = 1;
let cursor = cursor(); let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0));
cursor.goto(0, 0)?;
for pixel in &self.frame_buffer { for pixel in &self.frame_buffer {
match prev_color { match prev_color {
@ -115,8 +114,7 @@ impl RenderContext {
let mut pos = 0; let mut pos = 0;
let fb_len = self.frame_buffer.len(); let fb_len = self.frame_buffer.len();
let cursor = cursor(); let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0));
cursor.goto(0, 0)?;
while pos < (fb_len - self.width) { while pos < (fb_len - self.width) {
let top_pixel = self.frame_buffer[pos]; let top_pixel = self.frame_buffer[pos];
@ -169,12 +167,10 @@ impl RenderContext {
} }
} }
pub fn update(&mut self) -> Result<(), Box<dyn std::error::Error>> { pub fn update(&mut self) -> Result<(), Box<dyn std::error::Error>> {
let terminal = terminal(); let terminal_size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24));
let terminal_size = terminal.terminal_size();
if (self.width != terminal_size.0 as usize) || (self.height != terminal_size.1 as usize) { if (self.width != terminal_size.0 as usize) || (self.height != terminal_size.1 as usize) {
let cursor = cursor(); let _ = std::io::stdout().execute(crossterm::cursor::Hide);
cursor.hide()?;
self.width = terminal_size.0 as usize; self.width = terminal_size.0 as usize;
self.height = if self.lores_mode { self.height = if self.lores_mode {
@ -305,10 +301,9 @@ pub fn view_contents(
render_context.flush()?; render_context.flush()?;
let cursor = cursor(); let _ = std::io::stdout().execute(crossterm::cursor::Show);
let _ = cursor.show();
let _ = RawScreen::disable_raw_mode(); let _ = crossterm::terminal::disable_raw_mode();
Ok(()) Ok(())
} }
@ -340,11 +335,8 @@ pub fn view_contents_interactive(
nes.reset(); nes.reset();
if let Ok(_raw) = RawScreen::into_raw_mode() { if let Ok(_raw) = crossterm::terminal::enable_raw_mode() {
let mut render_context: RenderContext = RenderContext::blank(lores_mode); let mut render_context: RenderContext = RenderContext::blank(lores_mode);
let input = crossterm::input();
let _ = input.read_async();
let cursor = cursor();
let buttons = vec![ let buttons = vec![
KeyCode::Alt, KeyCode::Alt,
@ -357,7 +349,7 @@ pub fn view_contents_interactive(
KeyCode::RightArrow, KeyCode::RightArrow,
]; ];
cursor.hide()?; let _ = std::io::stdout().execute(crossterm::cursor::Hide);
'gameloop: loop { 'gameloop: loop {
let _ = render_context.update(); let _ = render_context.update();
@ -397,6 +389,18 @@ pub fn view_contents_interactive(
nes.release_button(0, idx as u8); nes.release_button(0, idx as u8);
} }
} }
loop {
let x = crossterm::event::poll(std::time::Duration::from_secs(0));
match x {
Ok(true) => {
// Swallow the events so we don't queue them into the line editor
let _ = crossterm::event::read();
}
_ => {
break;
}
}
}
} }
} }
} }
@ -408,10 +412,9 @@ pub fn view_contents_interactive(
} }
} }
let cursor = cursor(); let _ = std::io::stdout().execute(crossterm::cursor::Show);
let _ = cursor.show();
let _screen = RawScreen::disable_raw_mode(); let _screen = crossterm::terminal::disable_raw_mode();
Ok(()) Ok(())
} }

View File

@ -12,11 +12,11 @@ nu-protocol = { path = "../nu-protocol", version = "0.8.0" }
nu-source = { path = "../nu-source", version = "0.8.0" } nu-source = { path = "../nu-source", version = "0.8.0" }
nu-errors = { path = "../nu-errors", version = "0.8.0" } nu-errors = { path = "../nu-errors", version = "0.8.0" }
crossterm = "0.10.2" crossterm = "0.14.2"
syntect = "3.2.0" syntect = "3.2.0"
onig_sys = "~69.1.0" onig_sys = "~69.1.0"
ansi_term = "0.12.1" ansi_term = "0.12.1"
url = "2.1.0" url = "2.1.1"
[build-dependencies] [build-dependencies]
nu-build = { version = "0.8.0", path = "../nu-build" } nu-build = { version = "0.8.0", path = "../nu-build" }

View File

@ -1,5 +1,7 @@
use crossterm::{cursor, terminal, RawScreen}; use crossterm::{
use crossterm::{InputEvent, KeyEvent}; event::{KeyCode, KeyEvent},
ExecutableCommand,
};
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_plugin::{serve_plugin, Plugin}; use nu_plugin::{serve_plugin, Plugin};
use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value}; use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value};
@ -42,10 +44,7 @@ fn paint_textview(
starting_row: usize, starting_row: usize,
use_color_buffer: bool, use_color_buffer: bool,
) -> usize { ) -> usize {
let terminal = terminal(); let size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24));
let cursor = cursor();
let size = terminal.terminal_size();
// render // render
let mut pos = 0; let mut pos = 0;
@ -105,7 +104,7 @@ fn paint_textview(
} }
if buffer_needs_scrolling { if buffer_needs_scrolling {
let _ = cursor.goto(0, 0); let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0));
} }
if use_color_buffer { if use_color_buffer {
@ -116,7 +115,7 @@ fn paint_textview(
} }
if buffer_needs_scrolling { if buffer_needs_scrolling {
let _ = cursor.goto(0, size.1); let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, size.1));
print!( print!(
"{}", "{}",
ansi_term::Colour::Blue.paint("[ESC to quit, arrow keys to move]") ansi_term::Colour::Blue.paint("[ESC to quit, arrow keys to move]")
@ -131,29 +130,24 @@ fn paint_textview(
fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer: bool) { fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer: bool) {
let mut starting_row = 0; let mut starting_row = 0;
if let Ok(_raw) = RawScreen::into_raw_mode() { if let Ok(_raw) = crossterm::terminal::enable_raw_mode() {
let terminal = terminal(); let mut size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24));
let mut size = terminal.terminal_size();
let height = size.1 as usize - 1; let height = size.1 as usize - 1;
let mut max_bottom_line = paint_textview(&draw_commands, starting_row, use_color_buffer); let mut max_bottom_line = paint_textview(&draw_commands, starting_row, use_color_buffer);
// Only scroll if needed // Only scroll if needed
if max_bottom_line > height as usize { if max_bottom_line > height as usize {
let cursor = cursor(); let _ = std::io::stdout().execute(crossterm::cursor::Hide);
let _ = cursor.hide();
let input = crossterm::input();
let mut sync_stdin = input.read_sync();
loop { loop {
if let Some(ev) = sync_stdin.next() { if let Ok(ev) = crossterm::event::read() {
if let InputEvent::Keyboard(k) = ev { if let crossterm::event::Event::Key(KeyEvent { code, modifiers }) = ev {
match k { match code {
KeyEvent::Esc => { KeyCode::Esc => {
break; break;
} }
KeyEvent::Up | KeyEvent::Char('k') => { KeyCode::Up | KeyCode::Char('k') => {
if starting_row > 0 { if starting_row > 0 {
starting_row -= 1; starting_row -= 1;
max_bottom_line = paint_textview( max_bottom_line = paint_textview(
@ -163,19 +157,39 @@ fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer
); );
} }
} }
KeyEvent::Down | KeyEvent::Char('j') => { KeyCode::Down | KeyCode::Char('j') => {
if starting_row < (max_bottom_line - height) { if starting_row < (max_bottom_line - height) {
starting_row += 1; starting_row += 1;
} }
max_bottom_line = max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer); paint_textview(&draw_commands, starting_row, use_color_buffer);
} }
KeyEvent::PageUp | KeyEvent::Ctrl('b') => { KeyCode::Char('b')
if modifiers.contains(crossterm::event::KeyModifiers::CONTROL) =>
{
starting_row -= std::cmp::min(height, starting_row); starting_row -= std::cmp::min(height, starting_row);
max_bottom_line = max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer); paint_textview(&draw_commands, starting_row, use_color_buffer);
} }
KeyEvent::PageDown | KeyEvent::Ctrl('f') | KeyEvent::Char(' ') => { KeyCode::PageUp => {
starting_row -= std::cmp::min(height, starting_row);
max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer);
}
KeyCode::Char('f')
if modifiers.contains(crossterm::event::KeyModifiers::CONTROL) =>
{
if starting_row < (max_bottom_line - height) {
starting_row += height;
if starting_row > (max_bottom_line - height) {
starting_row = max_bottom_line - height;
}
}
max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer);
}
KeyCode::PageDown | KeyCode::Char(' ') => {
if starting_row < (max_bottom_line - height) { if starting_row < (max_bottom_line - height) {
starting_row += height; starting_row += height;
@ -191,17 +205,20 @@ fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer
} }
} }
let new_size = terminal.terminal_size(); if let Ok(new_size) = crossterm::terminal::size() {
if size != new_size { if size != new_size {
size = new_size; size = new_size;
let _ = terminal.clear(crossterm::ClearType::All); let _ = std::io::stdout().execute(crossterm::terminal::Clear(
max_bottom_line = crossterm::terminal::ClearType::All,
paint_textview(&draw_commands, starting_row, use_color_buffer); ));
max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer);
}
} }
} }
let _ = cursor.show(); let _ = std::io::stdout().execute(crossterm::cursor::Show);
let _ = RawScreen::disable_raw_mode(); let _ = crossterm::terminal::disable_raw_mode();
} }
} }

View File

@ -32,4 +32,3 @@ pub use num_traits::cast::ToPrimitive;
// TODO: Temporary redirect // TODO: Temporary redirect
pub use nu_protocol::{did_you_mean, TaggedDictBuilder}; pub use nu_protocol::{did_you_mean, TaggedDictBuilder};
//pub use nu_plugin::{serve_plugin, Plugin};

View File

@ -1,5 +1,7 @@
use crossterm::{cursor, terminal, RawScreen}; use crossterm::{
use crossterm::{InputEvent, KeyEvent}; event::{KeyCode, KeyEvent},
ExecutableCommand,
};
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_plugin::{serve_plugin, Plugin}; use nu_plugin::{serve_plugin, Plugin};
use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value}; use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value};
@ -42,10 +44,7 @@ fn paint_textview(
starting_row: usize, starting_row: usize,
use_color_buffer: bool, use_color_buffer: bool,
) -> usize { ) -> usize {
let terminal = terminal(); let size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24));
let cursor = cursor();
let size = terminal.terminal_size();
// render // render
let mut pos = 0; let mut pos = 0;
@ -105,7 +104,7 @@ fn paint_textview(
} }
if buffer_needs_scrolling { if buffer_needs_scrolling {
let _ = cursor.goto(0, 0); let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0));
} }
if use_color_buffer { if use_color_buffer {
@ -116,7 +115,7 @@ fn paint_textview(
} }
if buffer_needs_scrolling { if buffer_needs_scrolling {
let _ = cursor.goto(0, size.1); let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, size.1));
print!( print!(
"{}", "{}",
ansi_term::Colour::Blue.paint("[ESC to quit, arrow keys to move]") ansi_term::Colour::Blue.paint("[ESC to quit, arrow keys to move]")
@ -131,29 +130,24 @@ fn paint_textview(
fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer: bool) { fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer: bool) {
let mut starting_row = 0; let mut starting_row = 0;
if let Ok(_raw) = RawScreen::into_raw_mode() { if let Ok(_raw) = crossterm::terminal::enable_raw_mode() {
let terminal = terminal(); let mut size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24));
let mut size = terminal.terminal_size();
let height = size.1 as usize - 1; let height = size.1 as usize - 1;
let mut max_bottom_line = paint_textview(&draw_commands, starting_row, use_color_buffer); let mut max_bottom_line = paint_textview(&draw_commands, starting_row, use_color_buffer);
// Only scroll if needed // Only scroll if needed
if max_bottom_line > height as usize { if max_bottom_line > height as usize {
let cursor = cursor(); let _ = std::io::stdout().execute(crossterm::cursor::Hide);
let _ = cursor.hide();
let input = crossterm::input();
let mut sync_stdin = input.read_sync();
loop { loop {
if let Some(ev) = sync_stdin.next() { if let Ok(ev) = crossterm::event::read() {
if let InputEvent::Keyboard(k) = ev { if let crossterm::event::Event::Key(KeyEvent { code, modifiers }) = ev {
match k { match code {
KeyEvent::Esc => { KeyCode::Esc => {
break; break;
} }
KeyEvent::Up | KeyEvent::Char('k') => { KeyCode::Up | KeyCode::Char('k') => {
if starting_row > 0 { if starting_row > 0 {
starting_row -= 1; starting_row -= 1;
max_bottom_line = paint_textview( max_bottom_line = paint_textview(
@ -163,19 +157,39 @@ fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer
); );
} }
} }
KeyEvent::Down | KeyEvent::Char('j') => { KeyCode::Down | KeyCode::Char('j') => {
if starting_row < (max_bottom_line - height) { if starting_row < (max_bottom_line - height) {
starting_row += 1; starting_row += 1;
} }
max_bottom_line = max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer); paint_textview(&draw_commands, starting_row, use_color_buffer);
} }
KeyEvent::PageUp | KeyEvent::Ctrl('b') => { KeyCode::Char('b')
if modifiers.contains(crossterm::event::KeyModifiers::CONTROL) =>
{
starting_row -= std::cmp::min(height, starting_row); starting_row -= std::cmp::min(height, starting_row);
max_bottom_line = max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer); paint_textview(&draw_commands, starting_row, use_color_buffer);
} }
KeyEvent::PageDown | KeyEvent::Ctrl('f') | KeyEvent::Char(' ') => { KeyCode::PageUp => {
starting_row -= std::cmp::min(height, starting_row);
max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer);
}
KeyCode::Char('f')
if modifiers.contains(crossterm::event::KeyModifiers::CONTROL) =>
{
if starting_row < (max_bottom_line - height) {
starting_row += height;
if starting_row > (max_bottom_line - height) {
starting_row = max_bottom_line - height;
}
}
max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer);
}
KeyCode::PageDown | KeyCode::Char(' ') => {
if starting_row < (max_bottom_line - height) { if starting_row < (max_bottom_line - height) {
starting_row += height; starting_row += height;
@ -191,17 +205,20 @@ fn scroll_view_lines_if_needed(draw_commands: Vec<DrawCommand>, use_color_buffer
} }
} }
let new_size = terminal.terminal_size(); if let Ok(new_size) = crossterm::terminal::size() {
if size != new_size { if size != new_size {
size = new_size; size = new_size;
let _ = terminal.clear(crossterm::ClearType::All); let _ = std::io::stdout().execute(crossterm::terminal::Clear(
max_bottom_line = crossterm::terminal::ClearType::All,
paint_textview(&draw_commands, starting_row, use_color_buffer); ));
max_bottom_line =
paint_textview(&draw_commands, starting_row, use_color_buffer);
}
} }
} }
let _ = cursor.show(); let _ = std::io::stdout().execute(crossterm::cursor::Show);
let _ = RawScreen::disable_raw_mode(); let _ = crossterm::terminal::disable_raw_mode();
} }
} }

View File

@ -159,7 +159,7 @@ impl Painter {
FlatShape::Type => Color::Blue.bold(), FlatShape::Type => Color::Blue.bold(),
FlatShape::CompareOperator => Color::Yellow.normal(), FlatShape::CompareOperator => Color::Yellow.normal(),
FlatShape::DotDot => Color::Yellow.bold(), FlatShape::DotDot => Color::Yellow.bold(),
FlatShape::Dot => Style::new().fg(Color::White).on(Color::Black), FlatShape::Dot => Style::new().fg(Color::White),
FlatShape::InternalCommand => Color::Cyan.bold(), FlatShape::InternalCommand => Color::Cyan.bold(),
FlatShape::ExternalCommand => Color::Cyan.normal(), FlatShape::ExternalCommand => Color::Cyan.normal(),
FlatShape::ExternalWord => Color::Green.bold(), FlatShape::ExternalWord => Color::Green.bold(),