From 6da9e2aced7d398042439c40dec202b69610b2bb Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Mon, 27 Jan 2020 15:51:46 +1300 Subject: [PATCH] Upgrade crossterm (#1288) * WIP * Finish porting to new crossterm * Fmt --- Cargo.lock | 116 ++++++------------ Cargo.toml | 2 +- .../hir/tokens_iterator/debug/expand_trace.rs | 6 +- crates/nu_plugin_binaryview/Cargo.toml | 4 +- crates/nu_plugin_binaryview/src/main.rs | 43 ++++--- crates/nu_plugin_textview/Cargo.toml | 4 +- crates/nu_plugin_textview/src/main.rs | 81 +++++++----- src/lib.rs | 1 - src/plugins/nu_plugin_core_textview.rs | 81 +++++++----- src/shell/helper.rs | 2 +- 10 files changed, 168 insertions(+), 172 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 107637c766..fe82ffccdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,6 +51,12 @@ dependencies = [ "xdg", ] +[[package]] +name = "arc-swap" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" + [[package]] name = "arrayref" version = "0.3.5" @@ -575,92 +581,25 @@ dependencies = [ [[package]] name = "crossterm" -version = "0.10.2" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9abce7d7c50e9823ea0c0dbeb8f16d7e247af06d75b4c6244ea0a0998b3a6f35" -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" +checksum = "5750773d74a7dc612eac2ded3f55e9cdeeaa072210cd17c0192aedb48adb3618" dependencies = [ + "bitflags", "crossterm_winapi", + "lazy_static 1.4.0", "libc", + "mio", + "parking_lot", + "signal-hook", "winapi 0.3.8", ] [[package]] name = "crossterm_winapi" -version = "0.1.5" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b055e7cc627c452e6a9b977022f48a2db6f0ff73df446ca970f95eef9c381d45" +checksum = "8777c700901e2d5b50c406f736ed6b8f9e43645c7e104ddb74f8bc42b8ae62f6" dependencies = [ "winapi 0.3.8", ] @@ -1610,9 +1549,9 @@ dependencies = [ [[package]] name = "image" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4be8aaefbe7545dc42ae925afb55a0098f226a3fe5ef721872806f44f57826" +checksum = "53cb19c4e35102e5c6fb9ade5e0e236c5588424dc171a849af3141bf0b47768a" dependencies = [ "byteorder", "jpeg-decoder", @@ -3678,6 +3617,27 @@ dependencies = [ "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]] name = "slab" version = "0.4.2" diff --git a/Cargo.toml b/Cargo.toml index 2b7b6fa50c..688e2dee1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -131,7 +131,7 @@ heim = {version = "0.0.9", optional = true} battery = {version = "0.7.5", optional = true} syntect = {version = "3.2.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} semver = {version = "0.9.0", optional = true} diff --git a/crates/nu-parser/src/hir/tokens_iterator/debug/expand_trace.rs b/crates/nu-parser/src/hir/tokens_iterator/debug/expand_trace.rs index 25a92faafe..57b3aa3ee4 100644 --- a/crates/nu-parser/src/hir/tokens_iterator/debug/expand_trace.rs +++ b/crates/nu-parser/src/hir/tokens_iterator/debug/expand_trace.rs @@ -171,7 +171,7 @@ impl TreeFrame { write!( f, "{}", - Color::Black.bold().paint(&format!("({})", self.token_desc)) + Color::White.bold().paint(&format!("({})", self.token_desc)) )?; write!(f, " -> ")?; @@ -196,7 +196,7 @@ impl TreeFrame { write!( 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() { 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 { write!(f, "{}", Color::White.normal().paint(", "))?; diff --git a/crates/nu_plugin_binaryview/Cargo.toml b/crates/nu_plugin_binaryview/Cargo.toml index 379a3598c6..2c90db3406 100644 --- a/crates/nu_plugin_binaryview/Cargo.toml +++ b/crates/nu_plugin_binaryview/Cargo.toml @@ -8,13 +8,13 @@ license = "MIT" [dependencies] 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-protocol = { path = "../nu-protocol", version = "0.8.0" } nu-source = { path = "../nu-source", version = "0.8.0" } nu-errors = { path = "../nu-errors", version = "0.8.0" } 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" neso = "0.5.0" diff --git a/crates/nu_plugin_binaryview/src/main.rs b/crates/nu_plugin_binaryview/src/main.rs index 9923a6c5ad..6ae7dff790 100644 --- a/crates/nu_plugin_binaryview/src/main.rs +++ b/crates/nu_plugin_binaryview/src/main.rs @@ -1,4 +1,4 @@ -use crossterm::{cursor, terminal, Attribute, RawScreen}; +use crossterm::{style::Attribute, ExecutableCommand}; use nu_errors::ShellError; use nu_plugin::{serve_plugin, Plugin}; 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_count = 1; - let cursor = cursor(); - cursor.goto(0, 0)?; + let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0)); for pixel in &self.frame_buffer { match prev_color { @@ -115,8 +114,7 @@ impl RenderContext { let mut pos = 0; let fb_len = self.frame_buffer.len(); - let cursor = cursor(); - cursor.goto(0, 0)?; + let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0)); while pos < (fb_len - self.width) { let top_pixel = self.frame_buffer[pos]; @@ -169,12 +167,10 @@ impl RenderContext { } } pub fn update(&mut self) -> Result<(), Box> { - let terminal = terminal(); - let terminal_size = terminal.terminal_size(); + let terminal_size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24)); if (self.width != terminal_size.0 as usize) || (self.height != terminal_size.1 as usize) { - let cursor = cursor(); - cursor.hide()?; + let _ = std::io::stdout().execute(crossterm::cursor::Hide); self.width = terminal_size.0 as usize; self.height = if self.lores_mode { @@ -305,10 +301,9 @@ pub fn view_contents( render_context.flush()?; - let cursor = cursor(); - let _ = cursor.show(); + let _ = std::io::stdout().execute(crossterm::cursor::Show); - let _ = RawScreen::disable_raw_mode(); + let _ = crossterm::terminal::disable_raw_mode(); Ok(()) } @@ -340,11 +335,8 @@ pub fn view_contents_interactive( 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 input = crossterm::input(); - let _ = input.read_async(); - let cursor = cursor(); let buttons = vec![ KeyCode::Alt, @@ -357,7 +349,7 @@ pub fn view_contents_interactive( KeyCode::RightArrow, ]; - cursor.hide()?; + let _ = std::io::stdout().execute(crossterm::cursor::Hide); 'gameloop: loop { let _ = render_context.update(); @@ -397,6 +389,18 @@ pub fn view_contents_interactive( 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 _ = cursor.show(); + let _ = std::io::stdout().execute(crossterm::cursor::Show); - let _screen = RawScreen::disable_raw_mode(); + let _screen = crossterm::terminal::disable_raw_mode(); Ok(()) } diff --git a/crates/nu_plugin_textview/Cargo.toml b/crates/nu_plugin_textview/Cargo.toml index fefe78310c..f19ed1ca5d 100644 --- a/crates/nu_plugin_textview/Cargo.toml +++ b/crates/nu_plugin_textview/Cargo.toml @@ -12,11 +12,11 @@ nu-protocol = { path = "../nu-protocol", version = "0.8.0" } nu-source = { path = "../nu-source", 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" onig_sys = "~69.1.0" ansi_term = "0.12.1" -url = "2.1.0" +url = "2.1.1" [build-dependencies] nu-build = { version = "0.8.0", path = "../nu-build" } diff --git a/crates/nu_plugin_textview/src/main.rs b/crates/nu_plugin_textview/src/main.rs index ae28bd7d8f..98da9567db 100644 --- a/crates/nu_plugin_textview/src/main.rs +++ b/crates/nu_plugin_textview/src/main.rs @@ -1,5 +1,7 @@ -use crossterm::{cursor, terminal, RawScreen}; -use crossterm::{InputEvent, KeyEvent}; +use crossterm::{ + event::{KeyCode, KeyEvent}, + ExecutableCommand, +}; use nu_errors::ShellError; use nu_plugin::{serve_plugin, Plugin}; use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value}; @@ -42,10 +44,7 @@ fn paint_textview( starting_row: usize, use_color_buffer: bool, ) -> usize { - let terminal = terminal(); - let cursor = cursor(); - - let size = terminal.terminal_size(); + let size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24)); // render let mut pos = 0; @@ -105,7 +104,7 @@ fn paint_textview( } if buffer_needs_scrolling { - let _ = cursor.goto(0, 0); + let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0)); } if use_color_buffer { @@ -116,7 +115,7 @@ fn paint_textview( } if buffer_needs_scrolling { - let _ = cursor.goto(0, size.1); + let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, size.1)); print!( "{}", 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, use_color_buffer: bool) { let mut starting_row = 0; - if let Ok(_raw) = RawScreen::into_raw_mode() { - let terminal = terminal(); - let mut size = terminal.terminal_size(); + if let Ok(_raw) = crossterm::terminal::enable_raw_mode() { + let mut size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24)); let height = size.1 as usize - 1; let mut max_bottom_line = paint_textview(&draw_commands, starting_row, use_color_buffer); // Only scroll if needed if max_bottom_line > height as usize { - let cursor = cursor(); - let _ = cursor.hide(); - - let input = crossterm::input(); - let mut sync_stdin = input.read_sync(); + let _ = std::io::stdout().execute(crossterm::cursor::Hide); loop { - if let Some(ev) = sync_stdin.next() { - if let InputEvent::Keyboard(k) = ev { - match k { - KeyEvent::Esc => { + if let Ok(ev) = crossterm::event::read() { + if let crossterm::event::Event::Key(KeyEvent { code, modifiers }) = ev { + match code { + KeyCode::Esc => { break; } - KeyEvent::Up | KeyEvent::Char('k') => { + KeyCode::Up | KeyCode::Char('k') => { if starting_row > 0 { starting_row -= 1; max_bottom_line = paint_textview( @@ -163,19 +157,39 @@ fn scroll_view_lines_if_needed(draw_commands: Vec, use_color_buffer ); } } - KeyEvent::Down | KeyEvent::Char('j') => { + KeyCode::Down | KeyCode::Char('j') => { if starting_row < (max_bottom_line - height) { starting_row += 1; } max_bottom_line = 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); max_bottom_line = 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) { starting_row += height; @@ -191,17 +205,20 @@ fn scroll_view_lines_if_needed(draw_commands: Vec, use_color_buffer } } - let new_size = terminal.terminal_size(); - if size != new_size { - size = new_size; - let _ = terminal.clear(crossterm::ClearType::All); - max_bottom_line = - paint_textview(&draw_commands, starting_row, use_color_buffer); + if let Ok(new_size) = crossterm::terminal::size() { + if size != new_size { + size = new_size; + let _ = std::io::stdout().execute(crossterm::terminal::Clear( + crossterm::terminal::ClearType::All, + )); + 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(); } } diff --git a/src/lib.rs b/src/lib.rs index 61a12f8883..9793c56787 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,4 +32,3 @@ pub use num_traits::cast::ToPrimitive; // TODO: Temporary redirect pub use nu_protocol::{did_you_mean, TaggedDictBuilder}; -//pub use nu_plugin::{serve_plugin, Plugin}; diff --git a/src/plugins/nu_plugin_core_textview.rs b/src/plugins/nu_plugin_core_textview.rs index f59a2f53a2..9f6860bb1c 100644 --- a/src/plugins/nu_plugin_core_textview.rs +++ b/src/plugins/nu_plugin_core_textview.rs @@ -1,5 +1,7 @@ -use crossterm::{cursor, terminal, RawScreen}; -use crossterm::{InputEvent, KeyEvent}; +use crossterm::{ + event::{KeyCode, KeyEvent}, + ExecutableCommand, +}; use nu_errors::ShellError; use nu_plugin::{serve_plugin, Plugin}; use nu_protocol::{outln, CallInfo, Primitive, Signature, UntaggedValue, Value}; @@ -42,10 +44,7 @@ fn paint_textview( starting_row: usize, use_color_buffer: bool, ) -> usize { - let terminal = terminal(); - let cursor = cursor(); - - let size = terminal.terminal_size(); + let size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24)); // render let mut pos = 0; @@ -105,7 +104,7 @@ fn paint_textview( } if buffer_needs_scrolling { - let _ = cursor.goto(0, 0); + let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, 0)); } if use_color_buffer { @@ -116,7 +115,7 @@ fn paint_textview( } if buffer_needs_scrolling { - let _ = cursor.goto(0, size.1); + let _ = std::io::stdout().execute(crossterm::cursor::MoveTo(0, size.1)); print!( "{}", 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, use_color_buffer: bool) { let mut starting_row = 0; - if let Ok(_raw) = RawScreen::into_raw_mode() { - let terminal = terminal(); - let mut size = terminal.terminal_size(); + if let Ok(_raw) = crossterm::terminal::enable_raw_mode() { + let mut size = crossterm::terminal::size().unwrap_or_else(|_| (80, 24)); let height = size.1 as usize - 1; let mut max_bottom_line = paint_textview(&draw_commands, starting_row, use_color_buffer); // Only scroll if needed if max_bottom_line > height as usize { - let cursor = cursor(); - let _ = cursor.hide(); - - let input = crossterm::input(); - let mut sync_stdin = input.read_sync(); + let _ = std::io::stdout().execute(crossterm::cursor::Hide); loop { - if let Some(ev) = sync_stdin.next() { - if let InputEvent::Keyboard(k) = ev { - match k { - KeyEvent::Esc => { + if let Ok(ev) = crossterm::event::read() { + if let crossterm::event::Event::Key(KeyEvent { code, modifiers }) = ev { + match code { + KeyCode::Esc => { break; } - KeyEvent::Up | KeyEvent::Char('k') => { + KeyCode::Up | KeyCode::Char('k') => { if starting_row > 0 { starting_row -= 1; max_bottom_line = paint_textview( @@ -163,19 +157,39 @@ fn scroll_view_lines_if_needed(draw_commands: Vec, use_color_buffer ); } } - KeyEvent::Down | KeyEvent::Char('j') => { + KeyCode::Down | KeyCode::Char('j') => { if starting_row < (max_bottom_line - height) { starting_row += 1; } max_bottom_line = 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); max_bottom_line = 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) { starting_row += height; @@ -191,17 +205,20 @@ fn scroll_view_lines_if_needed(draw_commands: Vec, use_color_buffer } } - let new_size = terminal.terminal_size(); - if size != new_size { - size = new_size; - let _ = terminal.clear(crossterm::ClearType::All); - max_bottom_line = - paint_textview(&draw_commands, starting_row, use_color_buffer); + if let Ok(new_size) = crossterm::terminal::size() { + if size != new_size { + size = new_size; + let _ = std::io::stdout().execute(crossterm::terminal::Clear( + crossterm::terminal::ClearType::All, + )); + 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(); } } diff --git a/src/shell/helper.rs b/src/shell/helper.rs index eac5f03c0e..070a10bb8c 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -159,7 +159,7 @@ impl Painter { FlatShape::Type => Color::Blue.bold(), FlatShape::CompareOperator => Color::Yellow.normal(), 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::ExternalCommand => Color::Cyan.normal(), FlatShape::ExternalWord => Color::Green.bold(),