From 2d126c7c5c7dba232435245a51cc1398509bb4df Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Wed, 6 Jul 2022 13:20:54 -0700 Subject: [PATCH 1/3] add terminal modal which can be displayed and dismissed while preserving the terminal state --- assets/keymaps/default.json | 9 +- crates/terminal/src/modal.rs | 44 ++++++++ crates/terminal/src/terminal.rs | 54 ++++++++-- crates/terminal/src/terminal_element.rs | 134 ++++++++++++++---------- crates/theme/src/theme.rs | 7 ++ styles/src/styleTree/terminal.ts | 16 ++- 6 files changed, 196 insertions(+), 68 deletions(-) create mode 100644 crates/terminal/src/modal.rs diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index bea53ece45b2a672879453bb522fd64814e635f3..8aaf66eaf1f4eef12d557276d113e6f59ff7a4b0 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -303,7 +303,8 @@ "cmd-shift-P": "command_palette::Toggle", "cmd-shift-M": "diagnostics::Deploy", "cmd-shift-E": "project_panel::Toggle", - "cmd-alt-s": "workspace::SaveAll" + "cmd-alt-s": "workspace::SaveAll", + "shift-space t": "terminal::DeployModal" } }, // Bindings from Sublime Text @@ -419,5 +420,11 @@ "tab": "terminal::Tab", "cmd-v": "terminal::Paste" } + }, + { + "context": "ModalTerminal", + "bindings": { + "escape": "terminal::DeployModal" + } } ] \ No newline at end of file diff --git a/crates/terminal/src/modal.rs b/crates/terminal/src/modal.rs new file mode 100644 index 0000000000000000000000000000000000000000..60e14fa8a923d23e1c5da31e1844db3f417bc9bf --- /dev/null +++ b/crates/terminal/src/modal.rs @@ -0,0 +1,44 @@ +use gpui::{ViewContext, ViewHandle}; +use workspace::Workspace; + +use crate::{DeployModal, Event, Terminal}; + +pub fn deploy_modal(workspace: &mut Workspace, _: &DeployModal, cx: &mut ViewContext) { + if let Some(stored_terminal) = cx.default_global::>>().clone() { + workspace.toggle_modal(cx, |_, _| stored_terminal); + } else { + let project = workspace.project().read(cx); + let abs_path = project + .active_entry() + .and_then(|entry_id| project.worktree_for_entry(entry_id, cx)) + .and_then(|worktree_handle| worktree_handle.read(cx).as_local()) + .map(|wt| wt.abs_path().to_path_buf()); + + let displaced_modal = workspace.toggle_modal(cx, |_, cx| { + let this = cx.add_view(|cx| Terminal::new(cx, abs_path, true)); + cx.subscribe(&this, on_event).detach(); + this + }); + cx.set_global(displaced_modal); + } +} + +pub fn on_event( + workspace: &mut Workspace, + _: ViewHandle, + event: &Event, + cx: &mut ViewContext, +) { + // Dismiss the modal if the terminal quit + if let Event::CloseTerminal = event { + cx.set_global::>>(None); + if workspace + .modal() + .cloned() + .and_then(|modal| modal.downcast::()) + .is_some() + { + workspace.dismiss_modal(cx) + } + } +} diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index eb7f2a0a90b0d6d4b1204bdc13396634145c4371..00b1e44d5f59f2c5f1394e48903d3b4b7d3f0747 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -1,3 +1,7 @@ +pub mod gpui_func_tools; +mod modal; +pub mod terminal_element; + use alacritty_terminal::{ config::{Config, Program, PtyConfig}, event::{Event as AlacTermEvent, EventListener, Notify}, @@ -17,6 +21,7 @@ use gpui::{ actions, color::Color, elements::*, impl_internal_actions, platform::CursorStyle, ClipboardItem, Entity, MutableAppContext, View, ViewContext, }; +use modal::deploy_modal; use project::{Project, ProjectPath}; use settings::Settings; use smallvec::SmallVec; @@ -37,9 +42,6 @@ const UP_SEQ: &str = "\x1b[A"; const DOWN_SEQ: &str = "\x1b[B"; const DEFAULT_TITLE: &str = "Terminal"; -pub mod gpui_func_tools; -pub mod terminal_element; - ///Action for carrying the input to the PTY #[derive(Clone, Default, Debug, PartialEq, Eq)] pub struct Input(pub String); @@ -50,7 +52,22 @@ pub struct ScrollTerminal(pub i32); actions!( terminal, - [Sigint, Escape, Del, Return, Left, Right, Up, Down, Tab, Clear, Paste, Deploy, Quit] + [ + Sigint, + Escape, + Del, + Return, + Left, + Right, + Up, + Down, + Tab, + Clear, + Paste, + Deploy, + Quit, + DeployModal, + ] ); impl_internal_actions!(terminal, [Input, ScrollTerminal]); @@ -70,6 +87,7 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(Terminal::tab); cx.add_action(Terminal::paste); cx.add_action(Terminal::scroll_terminal); + cx.add_action(deploy_modal); } ///A translation struct for Alacritty to communicate with us from their event loop @@ -90,6 +108,7 @@ pub struct Terminal { has_new_content: bool, has_bell: bool, //Currently using iTerm bell, show bell emoji in tab until input is received cur_size: SizeInfo, + modal: bool, } ///Upward flowing events, for changing the title and such @@ -105,7 +124,7 @@ impl Entity for Terminal { impl Terminal { ///Create a new Terminal view. This spawns a task, a thread, and opens the TTY devices - fn new(cx: &mut ViewContext, working_directory: Option) -> Self { + fn new(cx: &mut ViewContext, working_directory: Option, modal: bool) -> Self { //Spawn a task so the Alacritty EventLoop can communicate with us in a view context let (events_tx, mut events_rx) = unbounded(); cx.spawn_weak(|this, mut cx| async move { @@ -172,6 +191,7 @@ impl Terminal { has_new_content: false, has_bell: false, cur_size: size_info, + modal, } } @@ -218,7 +238,7 @@ impl Terminal { ), AlacTermEvent::ColorRequest(index, format) => { let color = self.term.lock().colors()[index].unwrap_or_else(|| { - let term_style = &cx.global::().theme.terminal; + let term_style = &cx.global::().theme.terminal.colors; match index { 0..=255 => to_alac_rgb(get_color_at_index(&(index as u8), term_style)), //These additional values are required to match the Alacritty Colors object's behavior @@ -274,7 +294,10 @@ impl Terminal { .and_then(|worktree_handle| worktree_handle.read(cx).as_local()) .map(|wt| wt.abs_path().to_path_buf()); - workspace.add_item(Box::new(cx.add_view(|cx| Terminal::new(cx, abs_path))), cx); + workspace.add_item( + Box::new(cx.add_view(|cx| Terminal::new(cx, abs_path, false))), + cx, + ); } ///Send the shutdown message to Alacritty @@ -367,13 +390,26 @@ impl View for Terminal { } fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox { - TerminalEl::new(cx.handle()).contained().boxed() + let element = TerminalEl::new(cx.handle()).contained(); + if self.modal { + let settings = cx.global::(); + let container_style = settings.theme.terminal.modal_container; + element.with_style(container_style).boxed() + } else { + element.boxed() + } } fn on_focus(&mut self, cx: &mut ViewContext) { cx.emit(Event::Activate); self.has_new_content = false; } + + fn keymap_context(&self, _: &gpui::AppContext) -> gpui::keymap::Context { + let mut context = Self::default_keymap_context(); + context.set.insert("ModalTerminal".into()); + context + } } impl Item for Terminal { @@ -488,7 +524,7 @@ mod tests { //and produce noticable output? #[gpui::test] async fn test_terminal(cx: &mut TestAppContext) { - let terminal = cx.add_view(Default::default(), |cx| Terminal::new(cx, None)); + let terminal = cx.add_view(Default::default(), |cx| Terminal::new(cx, None, false)); terminal.update(cx, |terminal, cx| { terminal.write_to_pty(&Input(("expr 3 + 4".to_string()).to_string()), cx); diff --git a/crates/terminal/src/terminal_element.rs b/crates/terminal/src/terminal_element.rs index 408fb0dcecc35c844e78ad4240e48bdbd657662f..b4e43bfc4f574c3aa99bec6bf01ebf3235ff0e14 100644 --- a/crates/terminal/src/terminal_element.rs +++ b/crates/terminal/src/terminal_element.rs @@ -25,7 +25,7 @@ use itertools::Itertools; use ordered_float::OrderedFloat; use settings::Settings; use std::rc::Rc; -use theme::TerminalStyle; +use theme::{TerminalColors, TerminalStyle}; use crate::{gpui_func_tools::paint_layer, Input, ScrollTerminal, Terminal}; @@ -110,7 +110,8 @@ impl Element for TerminalEl { //Now that we're done with the mutable portion, grab the immutable settings and view again let terminal_theme = &(cx.global::()).theme.terminal; - let term = view_handle.read(cx).term.lock(); + let view = view_handle.read(cx); + let term = view.term.lock(); let grid = term.grid(); let cursor_point = grid.cursor.point; @@ -123,6 +124,7 @@ impl Element for TerminalEl { &text_style, terminal_theme, cx.text_layout_cache, + view.modal, ); let cells = layout_cells @@ -152,7 +154,7 @@ impl Element for TerminalEl { cursor_text.len(), RunStyle { font_id: text_style.font_id, - color: terminal_theme.background, + color: terminal_theme.colors.background, underline: Default::default(), }, )], @@ -178,12 +180,18 @@ impl Element for TerminalEl { cursor_position, block_width, line_height.0, - terminal_theme.cursor, + terminal_theme.colors.cursor, CursorShape::Block, Some(block_text.clone()), ) }); + let background_color = if view.modal { + terminal_theme.colors.modal_background + } else { + terminal_theme.colors.background + }; + ( constraint.max, LayoutState { @@ -193,7 +201,7 @@ impl Element for TerminalEl { cursor, cur_size, background_rects, - background_color: terminal_theme.background, + background_color, }, ) } @@ -348,6 +356,7 @@ fn layout_cells( text_style: &TextStyle, terminal_theme: &TerminalStyle, text_layout_cache: &TextLayoutCache, + modal: bool, ) -> Vec { let mut line_count: i32 = 0; let lines = grid.group_by(|i| i.point.line); @@ -358,7 +367,7 @@ fn layout_cells( line.map(|indexed_cell| { let cell_text = &indexed_cell.c.to_string(); - let cell_style = cell_style(&indexed_cell, terminal_theme, text_style); + let cell_style = cell_style(&indexed_cell, terminal_theme, text_style, modal); let layout_cell = text_layout_cache.layout_str( cell_text, @@ -368,7 +377,7 @@ fn layout_cells( LayoutCell::new( Point::new(line_count - 1, indexed_cell.point.column.0 as i32), layout_cell, - convert_color(&indexed_cell.bg, terminal_theme), + convert_color(&indexed_cell.bg, &terminal_theme.colors, modal), ) }) .collect::>() @@ -410,9 +419,14 @@ fn get_cursor_shape( } ///Convert the Alacritty cell styles to GPUI text styles and background color -fn cell_style(indexed: &Indexed<&Cell>, style: &TerminalStyle, text_style: &TextStyle) -> RunStyle { +fn cell_style( + indexed: &Indexed<&Cell>, + style: &TerminalStyle, + text_style: &TextStyle, + modal: bool, +) -> RunStyle { let flags = indexed.cell.flags; - let fg = convert_color(&indexed.cell.fg, style); + let fg = convert_color(&indexed.cell.fg, &style.colors, modal); let underline = flags .contains(Flags::UNDERLINE) @@ -431,67 +445,73 @@ fn cell_style(indexed: &Indexed<&Cell>, style: &TerminalStyle, text_style: &Text } ///Converts a 2, 8, or 24 bit color ANSI color to the GPUI equivalent -fn convert_color(alac_color: &AnsiColor, style: &TerminalStyle) -> Color { +fn convert_color(alac_color: &AnsiColor, colors: &TerminalColors, modal: bool) -> Color { + let background = if modal { + colors.modal_background + } else { + colors.background + }; + match alac_color { //Named and theme defined colors alacritty_terminal::ansi::Color::Named(n) => match n { - alacritty_terminal::ansi::NamedColor::Black => style.black, - alacritty_terminal::ansi::NamedColor::Red => style.red, - alacritty_terminal::ansi::NamedColor::Green => style.green, - alacritty_terminal::ansi::NamedColor::Yellow => style.yellow, - alacritty_terminal::ansi::NamedColor::Blue => style.blue, - alacritty_terminal::ansi::NamedColor::Magenta => style.magenta, - alacritty_terminal::ansi::NamedColor::Cyan => style.cyan, - alacritty_terminal::ansi::NamedColor::White => style.white, - alacritty_terminal::ansi::NamedColor::BrightBlack => style.bright_black, - alacritty_terminal::ansi::NamedColor::BrightRed => style.bright_red, - alacritty_terminal::ansi::NamedColor::BrightGreen => style.bright_green, - alacritty_terminal::ansi::NamedColor::BrightYellow => style.bright_yellow, - alacritty_terminal::ansi::NamedColor::BrightBlue => style.bright_blue, - alacritty_terminal::ansi::NamedColor::BrightMagenta => style.bright_magenta, - alacritty_terminal::ansi::NamedColor::BrightCyan => style.bright_cyan, - alacritty_terminal::ansi::NamedColor::BrightWhite => style.bright_white, - alacritty_terminal::ansi::NamedColor::Foreground => style.foreground, - alacritty_terminal::ansi::NamedColor::Background => style.background, - alacritty_terminal::ansi::NamedColor::Cursor => style.cursor, - alacritty_terminal::ansi::NamedColor::DimBlack => style.dim_black, - alacritty_terminal::ansi::NamedColor::DimRed => style.dim_red, - alacritty_terminal::ansi::NamedColor::DimGreen => style.dim_green, - alacritty_terminal::ansi::NamedColor::DimYellow => style.dim_yellow, - alacritty_terminal::ansi::NamedColor::DimBlue => style.dim_blue, - alacritty_terminal::ansi::NamedColor::DimMagenta => style.dim_magenta, - alacritty_terminal::ansi::NamedColor::DimCyan => style.dim_cyan, - alacritty_terminal::ansi::NamedColor::DimWhite => style.dim_white, - alacritty_terminal::ansi::NamedColor::BrightForeground => style.bright_foreground, - alacritty_terminal::ansi::NamedColor::DimForeground => style.dim_foreground, + alacritty_terminal::ansi::NamedColor::Black => colors.black, + alacritty_terminal::ansi::NamedColor::Red => colors.red, + alacritty_terminal::ansi::NamedColor::Green => colors.green, + alacritty_terminal::ansi::NamedColor::Yellow => colors.yellow, + alacritty_terminal::ansi::NamedColor::Blue => colors.blue, + alacritty_terminal::ansi::NamedColor::Magenta => colors.magenta, + alacritty_terminal::ansi::NamedColor::Cyan => colors.cyan, + alacritty_terminal::ansi::NamedColor::White => colors.white, + alacritty_terminal::ansi::NamedColor::BrightBlack => colors.bright_black, + alacritty_terminal::ansi::NamedColor::BrightRed => colors.bright_red, + alacritty_terminal::ansi::NamedColor::BrightGreen => colors.bright_green, + alacritty_terminal::ansi::NamedColor::BrightYellow => colors.bright_yellow, + alacritty_terminal::ansi::NamedColor::BrightBlue => colors.bright_blue, + alacritty_terminal::ansi::NamedColor::BrightMagenta => colors.bright_magenta, + alacritty_terminal::ansi::NamedColor::BrightCyan => colors.bright_cyan, + alacritty_terminal::ansi::NamedColor::BrightWhite => colors.bright_white, + alacritty_terminal::ansi::NamedColor::Foreground => colors.foreground, + alacritty_terminal::ansi::NamedColor::Background => background, + alacritty_terminal::ansi::NamedColor::Cursor => colors.cursor, + alacritty_terminal::ansi::NamedColor::DimBlack => colors.dim_black, + alacritty_terminal::ansi::NamedColor::DimRed => colors.dim_red, + alacritty_terminal::ansi::NamedColor::DimGreen => colors.dim_green, + alacritty_terminal::ansi::NamedColor::DimYellow => colors.dim_yellow, + alacritty_terminal::ansi::NamedColor::DimBlue => colors.dim_blue, + alacritty_terminal::ansi::NamedColor::DimMagenta => colors.dim_magenta, + alacritty_terminal::ansi::NamedColor::DimCyan => colors.dim_cyan, + alacritty_terminal::ansi::NamedColor::DimWhite => colors.dim_white, + alacritty_terminal::ansi::NamedColor::BrightForeground => colors.bright_foreground, + alacritty_terminal::ansi::NamedColor::DimForeground => colors.dim_foreground, }, //'True' colors alacritty_terminal::ansi::Color::Spec(rgb) => Color::new(rgb.r, rgb.g, rgb.b, u8::MAX), //8 bit, indexed colors - alacritty_terminal::ansi::Color::Indexed(i) => get_color_at_index(i, style), + alacritty_terminal::ansi::Color::Indexed(i) => get_color_at_index(i, colors), } } ///Converts an 8 bit ANSI color to it's GPUI equivalent. -pub fn get_color_at_index(index: &u8, style: &TerminalStyle) -> Color { +pub fn get_color_at_index(index: &u8, colors: &TerminalColors) -> Color { match index { //0-15 are the same as the named colors above - 0 => style.black, - 1 => style.red, - 2 => style.green, - 3 => style.yellow, - 4 => style.blue, - 5 => style.magenta, - 6 => style.cyan, - 7 => style.white, - 8 => style.bright_black, - 9 => style.bright_red, - 10 => style.bright_green, - 11 => style.bright_yellow, - 12 => style.bright_blue, - 13 => style.bright_magenta, - 14 => style.bright_cyan, - 15 => style.bright_white, + 0 => colors.black, + 1 => colors.red, + 2 => colors.green, + 3 => colors.yellow, + 4 => colors.blue, + 5 => colors.magenta, + 6 => colors.cyan, + 7 => colors.white, + 8 => colors.bright_black, + 9 => colors.bright_red, + 10 => colors.bright_green, + 11 => colors.bright_yellow, + 12 => colors.bright_blue, + 13 => colors.bright_magenta, + 14 => colors.bright_cyan, + 15 => colors.bright_white, //16-231 are mapped to their RGB colors on a 0-5 range per channel 16..=231 => { let (r, g, b) = rgb_for_index(index); //Split the index into it's ANSI-RGB components diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 184b1880f0c0a05cc581059b80766b3d282cc9cc..a3af61a41cb8cacf9e372b43367ca5d42d2824b7 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -637,6 +637,12 @@ pub struct HoverPopover { #[derive(Clone, Deserialize, Default)] pub struct TerminalStyle { + pub colors: TerminalColors, + pub modal_container: ContainerStyle, +} + +#[derive(Clone, Deserialize, Default)] +pub struct TerminalColors { pub black: Color, pub red: Color, pub green: Color, @@ -655,6 +661,7 @@ pub struct TerminalStyle { pub bright_white: Color, pub foreground: Color, pub background: Color, + pub modal_background: Color, pub cursor: Color, pub dim_black: Color, pub dim_red: Color, diff --git a/styles/src/styleTree/terminal.ts b/styles/src/styleTree/terminal.ts index ef9e4f93ddf1a66d96ed683769bd52655247a326..bc133f09c8a0564854120e1dd329de73e9f05353 100644 --- a/styles/src/styleTree/terminal.ts +++ b/styles/src/styleTree/terminal.ts @@ -1,7 +1,8 @@ import Theme from "../themes/common/theme"; +import { border, modalShadow } from "./components"; export default function terminal(theme: Theme) { - return { + let colors = { black: theme.ramps.neutral(0).hex(), red: theme.ramps.red(0.5).hex(), green: theme.ramps.green(0.5).hex(), @@ -20,6 +21,7 @@ export default function terminal(theme: Theme) { brightWhite: theme.ramps.neutral(7).hex(), foreground: theme.ramps.neutral(7).hex(), background: theme.ramps.neutral(0).hex(), + modalBackground: theme.ramps.neutral(1).hex(), cursor: theme.ramps.neutral(7).hex(), dimBlack: theme.ramps.neutral(7).hex(), dimRed: theme.ramps.red(0.75).hex(), @@ -32,4 +34,16 @@ export default function terminal(theme: Theme) { brightForeground: theme.ramps.neutral(7).hex(), dimForeground: theme.ramps.neutral(0).hex(), }; + + return { + colors, + modalContainer: { + background: colors.modalBackground, + cornerRadius: 8, + padding: 8, + margin: 25, + border: border(theme, "primary"), + shadow: modalShadow(theme), + } + }; } \ No newline at end of file From 525e317d96a6192829fa81757bff082527ae6a48 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Wed, 6 Jul 2022 13:22:54 -0700 Subject: [PATCH 2/3] remove custom terminal keybindings --- assets/keymaps/default.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 8aaf66eaf1f4eef12d557276d113e6f59ff7a4b0..bea53ece45b2a672879453bb522fd64814e635f3 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -303,8 +303,7 @@ "cmd-shift-P": "command_palette::Toggle", "cmd-shift-M": "diagnostics::Deploy", "cmd-shift-E": "project_panel::Toggle", - "cmd-alt-s": "workspace::SaveAll", - "shift-space t": "terminal::DeployModal" + "cmd-alt-s": "workspace::SaveAll" } }, // Bindings from Sublime Text @@ -420,11 +419,5 @@ "tab": "terminal::Tab", "cmd-v": "terminal::Paste" } - }, - { - "context": "ModalTerminal", - "bindings": { - "escape": "terminal::DeployModal" - } } ] \ No newline at end of file From 4a860d4da42c6ff75044772318870bd68af0661c Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 7 Jul 2022 18:05:37 -0700 Subject: [PATCH 3/3] Properly fixed merge issues --- crates/terminal/src/color_translation.rs | 130 ++++++++++++----------- crates/terminal/src/modal.rs | 4 +- crates/terminal/src/terminal.rs | 11 +- crates/terminal/src/terminal_element.rs | 54 +--------- 4 files changed, 77 insertions(+), 122 deletions(-) diff --git a/crates/terminal/src/color_translation.rs b/crates/terminal/src/color_translation.rs index 78c2a569dbbeac5806e6535a2c87b7c0b6b57c03..946a22d3043e3eb1238b833974a17b29143e7ddf 100644 --- a/crates/terminal/src/color_translation.rs +++ b/crates/terminal/src/color_translation.rs @@ -1,71 +1,77 @@ use alacritty_terminal::{ansi::Color as AnsiColor, term::color::Rgb as AlacRgb}; use gpui::color::Color; -use theme::TerminalStyle; +use theme::TerminalColors; ///Converts a 2, 8, or 24 bit color ANSI color to the GPUI equivalent -pub fn convert_color(alac_color: &AnsiColor, style: &TerminalStyle) -> Color { +pub fn convert_color(alac_color: &AnsiColor, colors: &TerminalColors, modal: bool) -> Color { + let background = if modal { + colors.modal_background + } else { + colors.background + }; + match alac_color { //Named and theme defined colors alacritty_terminal::ansi::Color::Named(n) => match n { - alacritty_terminal::ansi::NamedColor::Black => style.black, - alacritty_terminal::ansi::NamedColor::Red => style.red, - alacritty_terminal::ansi::NamedColor::Green => style.green, - alacritty_terminal::ansi::NamedColor::Yellow => style.yellow, - alacritty_terminal::ansi::NamedColor::Blue => style.blue, - alacritty_terminal::ansi::NamedColor::Magenta => style.magenta, - alacritty_terminal::ansi::NamedColor::Cyan => style.cyan, - alacritty_terminal::ansi::NamedColor::White => style.white, - alacritty_terminal::ansi::NamedColor::BrightBlack => style.bright_black, - alacritty_terminal::ansi::NamedColor::BrightRed => style.bright_red, - alacritty_terminal::ansi::NamedColor::BrightGreen => style.bright_green, - alacritty_terminal::ansi::NamedColor::BrightYellow => style.bright_yellow, - alacritty_terminal::ansi::NamedColor::BrightBlue => style.bright_blue, - alacritty_terminal::ansi::NamedColor::BrightMagenta => style.bright_magenta, - alacritty_terminal::ansi::NamedColor::BrightCyan => style.bright_cyan, - alacritty_terminal::ansi::NamedColor::BrightWhite => style.bright_white, - alacritty_terminal::ansi::NamedColor::Foreground => style.foreground, - alacritty_terminal::ansi::NamedColor::Background => style.background, - alacritty_terminal::ansi::NamedColor::Cursor => style.cursor, - alacritty_terminal::ansi::NamedColor::DimBlack => style.dim_black, - alacritty_terminal::ansi::NamedColor::DimRed => style.dim_red, - alacritty_terminal::ansi::NamedColor::DimGreen => style.dim_green, - alacritty_terminal::ansi::NamedColor::DimYellow => style.dim_yellow, - alacritty_terminal::ansi::NamedColor::DimBlue => style.dim_blue, - alacritty_terminal::ansi::NamedColor::DimMagenta => style.dim_magenta, - alacritty_terminal::ansi::NamedColor::DimCyan => style.dim_cyan, - alacritty_terminal::ansi::NamedColor::DimWhite => style.dim_white, - alacritty_terminal::ansi::NamedColor::BrightForeground => style.bright_foreground, - alacritty_terminal::ansi::NamedColor::DimForeground => style.dim_foreground, + alacritty_terminal::ansi::NamedColor::Black => colors.black, + alacritty_terminal::ansi::NamedColor::Red => colors.red, + alacritty_terminal::ansi::NamedColor::Green => colors.green, + alacritty_terminal::ansi::NamedColor::Yellow => colors.yellow, + alacritty_terminal::ansi::NamedColor::Blue => colors.blue, + alacritty_terminal::ansi::NamedColor::Magenta => colors.magenta, + alacritty_terminal::ansi::NamedColor::Cyan => colors.cyan, + alacritty_terminal::ansi::NamedColor::White => colors.white, + alacritty_terminal::ansi::NamedColor::BrightBlack => colors.bright_black, + alacritty_terminal::ansi::NamedColor::BrightRed => colors.bright_red, + alacritty_terminal::ansi::NamedColor::BrightGreen => colors.bright_green, + alacritty_terminal::ansi::NamedColor::BrightYellow => colors.bright_yellow, + alacritty_terminal::ansi::NamedColor::BrightBlue => colors.bright_blue, + alacritty_terminal::ansi::NamedColor::BrightMagenta => colors.bright_magenta, + alacritty_terminal::ansi::NamedColor::BrightCyan => colors.bright_cyan, + alacritty_terminal::ansi::NamedColor::BrightWhite => colors.bright_white, + alacritty_terminal::ansi::NamedColor::Foreground => colors.foreground, + alacritty_terminal::ansi::NamedColor::Background => background, + alacritty_terminal::ansi::NamedColor::Cursor => colors.cursor, + alacritty_terminal::ansi::NamedColor::DimBlack => colors.dim_black, + alacritty_terminal::ansi::NamedColor::DimRed => colors.dim_red, + alacritty_terminal::ansi::NamedColor::DimGreen => colors.dim_green, + alacritty_terminal::ansi::NamedColor::DimYellow => colors.dim_yellow, + alacritty_terminal::ansi::NamedColor::DimBlue => colors.dim_blue, + alacritty_terminal::ansi::NamedColor::DimMagenta => colors.dim_magenta, + alacritty_terminal::ansi::NamedColor::DimCyan => colors.dim_cyan, + alacritty_terminal::ansi::NamedColor::DimWhite => colors.dim_white, + alacritty_terminal::ansi::NamedColor::BrightForeground => colors.bright_foreground, + alacritty_terminal::ansi::NamedColor::DimForeground => colors.dim_foreground, }, //'True' colors alacritty_terminal::ansi::Color::Spec(rgb) => Color::new(rgb.r, rgb.g, rgb.b, u8::MAX), //8 bit, indexed colors - alacritty_terminal::ansi::Color::Indexed(i) => get_color_at_index(&(*i as usize), style), + alacritty_terminal::ansi::Color::Indexed(i) => get_color_at_index(&(*i as usize), colors), } } ///Converts an 8 bit ANSI color to it's GPUI equivalent. ///Accepts usize for compatability with the alacritty::Colors interface, ///Other than that use case, should only be called with values in the [0,255] range -pub fn get_color_at_index(index: &usize, style: &TerminalStyle) -> Color { +pub fn get_color_at_index(index: &usize, colors: &TerminalColors) -> Color { match index { //0-15 are the same as the named colors above - 0 => style.black, - 1 => style.red, - 2 => style.green, - 3 => style.yellow, - 4 => style.blue, - 5 => style.magenta, - 6 => style.cyan, - 7 => style.white, - 8 => style.bright_black, - 9 => style.bright_red, - 10 => style.bright_green, - 11 => style.bright_yellow, - 12 => style.bright_blue, - 13 => style.bright_magenta, - 14 => style.bright_cyan, - 15 => style.bright_white, + 0 => colors.black, + 1 => colors.red, + 2 => colors.green, + 3 => colors.yellow, + 4 => colors.blue, + 5 => colors.magenta, + 6 => colors.cyan, + 7 => colors.white, + 8 => colors.bright_black, + 9 => colors.bright_red, + 10 => colors.bright_green, + 11 => colors.bright_yellow, + 12 => colors.bright_blue, + 13 => colors.bright_magenta, + 14 => colors.bright_cyan, + 15 => colors.bright_white, //16-231 are mapped to their RGB colors on a 0-5 range per channel 16..=231 => { let (r, g, b) = rgb_for_index(&(*index as u8)); //Split the index into it's ANSI-RGB components @@ -79,19 +85,19 @@ pub fn get_color_at_index(index: &usize, style: &TerminalStyle) -> Color { Color::new(i * step, i * step, i * step, u8::MAX) //Map the ANSI-grayscale components to the RGB-grayscale } //For compatability with the alacritty::Colors interface - 256 => style.foreground, - 257 => style.background, - 258 => style.cursor, - 259 => style.dim_black, - 260 => style.dim_red, - 261 => style.dim_green, - 262 => style.dim_yellow, - 263 => style.dim_blue, - 264 => style.dim_magenta, - 265 => style.dim_cyan, - 266 => style.dim_white, - 267 => style.bright_foreground, - 268 => style.black, //'Dim Background', non-standard color + 256 => colors.foreground, + 257 => colors.background, + 258 => colors.cursor, + 259 => colors.dim_black, + 260 => colors.dim_red, + 261 => colors.dim_green, + 262 => colors.dim_yellow, + 263 => colors.dim_blue, + 264 => colors.dim_magenta, + 265 => colors.dim_cyan, + 266 => colors.dim_white, + 267 => colors.bright_foreground, + 268 => colors.black, //'Dim Background', non-standard color _ => Color::new(0, 0, 0, 255), } } diff --git a/crates/terminal/src/modal.rs b/crates/terminal/src/modal.rs index 60e14fa8a923d23e1c5da31e1844db3f417bc9bf..2a1c16ae4bf3df89fae485720a7a2744608cd430 100644 --- a/crates/terminal/src/modal.rs +++ b/crates/terminal/src/modal.rs @@ -1,7 +1,7 @@ use gpui::{ViewContext, ViewHandle}; use workspace::Workspace; -use crate::{DeployModal, Event, Terminal}; +use crate::{get_working_directory, DeployModal, Event, Terminal}; pub fn deploy_modal(workspace: &mut Workspace, _: &DeployModal, cx: &mut ViewContext) { if let Some(stored_terminal) = cx.default_global::>>().clone() { @@ -12,7 +12,7 @@ pub fn deploy_modal(workspace: &mut Workspace, _: &DeployModal, cx: &mut ViewCon .active_entry() .and_then(|entry_id| project.worktree_for_entry(entry_id, cx)) .and_then(|worktree_handle| worktree_handle.read(cx).as_local()) - .map(|wt| wt.abs_path().to_path_buf()); + .and_then(get_working_directory); let displaced_modal = workspace.toggle_modal(cx, |_, cx| { let this = cx.add_view(|cx| Terminal::new(cx, abs_path, true)); diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 437c5995df6f7155417f054c584c0e8a3a60c0fd..017bb5f00a192e6f08037dae0d7fd15bd8364a9f 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -1,3 +1,4 @@ +pub mod color_translation; pub mod gpui_func_tools; mod modal; pub mod terminal_element; @@ -47,10 +48,6 @@ const DEBUG_TERMINAL_HEIGHT: f32 = 200.; const DEBUG_CELL_WIDTH: f32 = 5.; const DEBUG_LINE_HEIGHT: f32 = 5.; -pub mod color_translation; -pub mod gpui_func_tools; -pub mod terminal_element; - ///Action for carrying the input to the PTY #[derive(Clone, Default, Debug, PartialEq, Eq)] pub struct Input(pub String); @@ -258,7 +255,7 @@ impl Terminal { AlacTermEvent::ColorRequest(index, format) => { let color = self.term.lock().colors()[index].unwrap_or_else(|| { let term_style = &cx.global::().theme.terminal; - to_alac_rgb(get_color_at_index(&index, term_style)) + to_alac_rgb(get_color_at_index(&index, &term_style.colors)) }); self.write_to_pty(&Input(format(color)), cx) } @@ -461,7 +458,7 @@ impl Item for Terminal { //From what I can tell, there's no way to tell the current working //Directory of the terminal from outside the terminal. There might be //solutions to this, but they are non-trivial and require more IPC - Some(Terminal::new(cx, self.associated_directory.clone())) + Some(Terminal::new(cx, self.associated_directory.clone(), false)) } fn project_path(&self, _cx: &gpui::AppContext) -> Option { @@ -650,7 +647,7 @@ mod tests { ///If this test is failing for you, check that DEBUG_TERMINAL_WIDTH is wide enough to fit your entire command prompt! #[gpui::test] async fn test_copy(cx: &mut TestAppContext) { - let terminal = cx.add_view(Default::default(), |cx| Terminal::new(cx, None)); + let terminal = cx.add_view(Default::default(), |cx| Terminal::new(cx, None, false)); cx.set_condition_duration(Duration::from_secs(2)); terminal.update(cx, |terminal, cx| { diff --git a/crates/terminal/src/terminal_element.rs b/crates/terminal/src/terminal_element.rs index 329fbaabe094c539f0a02a6a5ccfe5057314a24e..ec48996e7801e6a8a92e8c54ea165ca711af7a9b 100644 --- a/crates/terminal/src/terminal_element.rs +++ b/crates/terminal/src/terminal_element.rs @@ -26,7 +26,7 @@ use gpui::{ use itertools::Itertools; use ordered_float::OrderedFloat; use settings::Settings; -use theme::{TerminalColors, TerminalStyle}; +use theme::TerminalStyle; use std::{cmp::min, ops::Range, rc::Rc, sync::Arc}; use std::{fmt::Debug, ops::Sub}; @@ -130,7 +130,7 @@ impl Element for TerminalEl { //Now that we're done with the mutable portion, grab the immutable settings and view again let view = view_handle.read(cx); - let term = view.term.lock(); + let (selection_color, terminal_theme) = { let theme = &(cx.global::()).theme; (theme.editor.selection.selection, &theme.terminal) @@ -388,7 +388,7 @@ impl Element for TerminalEl { } } -fn mouse_to_cell_data( +pub fn mouse_to_cell_data( pos: Vector2F, origin: Vector2F, cur_size: SizeInfo, @@ -543,54 +543,6 @@ fn cell_style( } } -///Converts a 2, 8, or 24 bit color ANSI color to the GPUI equivalent -fn convert_color(alac_color: &AnsiColor, colors: &TerminalColors, modal: bool) -> Color { - let background = if modal { - colors.modal_background - } else { - colors.background - }; - - match alac_color { - //Named and theme defined colors - alacritty_terminal::ansi::Color::Named(n) => match n { - alacritty_terminal::ansi::NamedColor::Black => colors.black, - alacritty_terminal::ansi::NamedColor::Red => colors.red, - alacritty_terminal::ansi::NamedColor::Green => colors.green, - alacritty_terminal::ansi::NamedColor::Yellow => colors.yellow, - alacritty_terminal::ansi::NamedColor::Blue => colors.blue, - alacritty_terminal::ansi::NamedColor::Magenta => colors.magenta, - alacritty_terminal::ansi::NamedColor::Cyan => colors.cyan, - alacritty_terminal::ansi::NamedColor::White => colors.white, - alacritty_terminal::ansi::NamedColor::BrightBlack => colors.bright_black, - alacritty_terminal::ansi::NamedColor::BrightRed => colors.bright_red, - alacritty_terminal::ansi::NamedColor::BrightGreen => colors.bright_green, - alacritty_terminal::ansi::NamedColor::BrightYellow => colors.bright_yellow, - alacritty_terminal::ansi::NamedColor::BrightBlue => colors.bright_blue, - alacritty_terminal::ansi::NamedColor::BrightMagenta => colors.bright_magenta, - alacritty_terminal::ansi::NamedColor::BrightCyan => colors.bright_cyan, - alacritty_terminal::ansi::NamedColor::BrightWhite => colors.bright_white, - alacritty_terminal::ansi::NamedColor::Foreground => colors.foreground, - alacritty_terminal::ansi::NamedColor::Background => background, - alacritty_terminal::ansi::NamedColor::Cursor => colors.cursor, - alacritty_terminal::ansi::NamedColor::DimBlack => colors.dim_black, - alacritty_terminal::ansi::NamedColor::DimRed => colors.dim_red, - alacritty_terminal::ansi::NamedColor::DimGreen => colors.dim_green, - alacritty_terminal::ansi::NamedColor::DimYellow => colors.dim_yellow, - alacritty_terminal::ansi::NamedColor::DimBlue => colors.dim_blue, - alacritty_terminal::ansi::NamedColor::DimMagenta => colors.dim_magenta, - alacritty_terminal::ansi::NamedColor::DimCyan => colors.dim_cyan, - alacritty_terminal::ansi::NamedColor::DimWhite => colors.dim_white, - alacritty_terminal::ansi::NamedColor::BrightForeground => colors.bright_foreground, - alacritty_terminal::ansi::NamedColor::DimForeground => colors.dim_foreground, - }, - //'True' colors - alacritty_terminal::ansi::Color::Spec(rgb) => Color::new(rgb.r, rgb.g, rgb.b, u8::MAX), - //8 bit, indexed colors - alacritty_terminal::ansi::Color::Indexed(i) => get_color_at_index(i, colors), - } -} - fn attach_mouse_handlers( origin: Vector2F, cur_size: SizeInfo,