add terminal modal which can be displayed and dismissed while preserving the terminal state
This commit is contained in:
parent
00d1c2e56f
commit
2d126c7c5c
6 changed files with 196 additions and 68 deletions
|
@ -303,7 +303,8 @@
|
||||||
"cmd-shift-P": "command_palette::Toggle",
|
"cmd-shift-P": "command_palette::Toggle",
|
||||||
"cmd-shift-M": "diagnostics::Deploy",
|
"cmd-shift-M": "diagnostics::Deploy",
|
||||||
"cmd-shift-E": "project_panel::Toggle",
|
"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
|
// Bindings from Sublime Text
|
||||||
|
@ -419,5 +420,11 @@
|
||||||
"tab": "terminal::Tab",
|
"tab": "terminal::Tab",
|
||||||
"cmd-v": "terminal::Paste"
|
"cmd-v": "terminal::Paste"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"context": "ModalTerminal",
|
||||||
|
"bindings": {
|
||||||
|
"escape": "terminal::DeployModal"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
44
crates/terminal/src/modal.rs
Normal file
44
crates/terminal/src/modal.rs
Normal file
|
@ -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<Workspace>) {
|
||||||
|
if let Some(stored_terminal) = cx.default_global::<Option<ViewHandle<Terminal>>>().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<Terminal>,
|
||||||
|
event: &Event,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) {
|
||||||
|
// Dismiss the modal if the terminal quit
|
||||||
|
if let Event::CloseTerminal = event {
|
||||||
|
cx.set_global::<Option<ViewHandle<Terminal>>>(None);
|
||||||
|
if workspace
|
||||||
|
.modal()
|
||||||
|
.cloned()
|
||||||
|
.and_then(|modal| modal.downcast::<Terminal>())
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
workspace.dismiss_modal(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,7 @@
|
||||||
|
pub mod gpui_func_tools;
|
||||||
|
mod modal;
|
||||||
|
pub mod terminal_element;
|
||||||
|
|
||||||
use alacritty_terminal::{
|
use alacritty_terminal::{
|
||||||
config::{Config, Program, PtyConfig},
|
config::{Config, Program, PtyConfig},
|
||||||
event::{Event as AlacTermEvent, EventListener, Notify},
|
event::{Event as AlacTermEvent, EventListener, Notify},
|
||||||
|
@ -17,6 +21,7 @@ use gpui::{
|
||||||
actions, color::Color, elements::*, impl_internal_actions, platform::CursorStyle,
|
actions, color::Color, elements::*, impl_internal_actions, platform::CursorStyle,
|
||||||
ClipboardItem, Entity, MutableAppContext, View, ViewContext,
|
ClipboardItem, Entity, MutableAppContext, View, ViewContext,
|
||||||
};
|
};
|
||||||
|
use modal::deploy_modal;
|
||||||
use project::{Project, ProjectPath};
|
use project::{Project, ProjectPath};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -37,9 +42,6 @@ const UP_SEQ: &str = "\x1b[A";
|
||||||
const DOWN_SEQ: &str = "\x1b[B";
|
const DOWN_SEQ: &str = "\x1b[B";
|
||||||
const DEFAULT_TITLE: &str = "Terminal";
|
const DEFAULT_TITLE: &str = "Terminal";
|
||||||
|
|
||||||
pub mod gpui_func_tools;
|
|
||||||
pub mod terminal_element;
|
|
||||||
|
|
||||||
///Action for carrying the input to the PTY
|
///Action for carrying the input to the PTY
|
||||||
#[derive(Clone, Default, Debug, PartialEq, Eq)]
|
#[derive(Clone, Default, Debug, PartialEq, Eq)]
|
||||||
pub struct Input(pub String);
|
pub struct Input(pub String);
|
||||||
|
@ -50,7 +52,22 @@ pub struct ScrollTerminal(pub i32);
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
terminal,
|
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]);
|
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::tab);
|
||||||
cx.add_action(Terminal::paste);
|
cx.add_action(Terminal::paste);
|
||||||
cx.add_action(Terminal::scroll_terminal);
|
cx.add_action(Terminal::scroll_terminal);
|
||||||
|
cx.add_action(deploy_modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
///A translation struct for Alacritty to communicate with us from their event loop
|
///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_new_content: bool,
|
||||||
has_bell: bool, //Currently using iTerm bell, show bell emoji in tab until input is received
|
has_bell: bool, //Currently using iTerm bell, show bell emoji in tab until input is received
|
||||||
cur_size: SizeInfo,
|
cur_size: SizeInfo,
|
||||||
|
modal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
///Upward flowing events, for changing the title and such
|
///Upward flowing events, for changing the title and such
|
||||||
|
@ -105,7 +124,7 @@ impl Entity for Terminal {
|
||||||
|
|
||||||
impl Terminal {
|
impl Terminal {
|
||||||
///Create a new Terminal view. This spawns a task, a thread, and opens the TTY devices
|
///Create a new Terminal view. This spawns a task, a thread, and opens the TTY devices
|
||||||
fn new(cx: &mut ViewContext<Self>, working_directory: Option<PathBuf>) -> Self {
|
fn new(cx: &mut ViewContext<Self>, working_directory: Option<PathBuf>, modal: bool) -> Self {
|
||||||
//Spawn a task so the Alacritty EventLoop can communicate with us in a view context
|
//Spawn a task so the Alacritty EventLoop can communicate with us in a view context
|
||||||
let (events_tx, mut events_rx) = unbounded();
|
let (events_tx, mut events_rx) = unbounded();
|
||||||
cx.spawn_weak(|this, mut cx| async move {
|
cx.spawn_weak(|this, mut cx| async move {
|
||||||
|
@ -172,6 +191,7 @@ impl Terminal {
|
||||||
has_new_content: false,
|
has_new_content: false,
|
||||||
has_bell: false,
|
has_bell: false,
|
||||||
cur_size: size_info,
|
cur_size: size_info,
|
||||||
|
modal,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +238,7 @@ impl Terminal {
|
||||||
),
|
),
|
||||||
AlacTermEvent::ColorRequest(index, format) => {
|
AlacTermEvent::ColorRequest(index, format) => {
|
||||||
let color = self.term.lock().colors()[index].unwrap_or_else(|| {
|
let color = self.term.lock().colors()[index].unwrap_or_else(|| {
|
||||||
let term_style = &cx.global::<Settings>().theme.terminal;
|
let term_style = &cx.global::<Settings>().theme.terminal.colors;
|
||||||
match index {
|
match index {
|
||||||
0..=255 => to_alac_rgb(get_color_at_index(&(index as u8), term_style)),
|
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
|
//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())
|
.and_then(|worktree_handle| worktree_handle.read(cx).as_local())
|
||||||
.map(|wt| wt.abs_path().to_path_buf());
|
.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
|
///Send the shutdown message to Alacritty
|
||||||
|
@ -367,13 +390,26 @@ impl View for Terminal {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox {
|
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::<Settings>();
|
||||||
|
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<Self>) {
|
fn on_focus(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
cx.emit(Event::Activate);
|
cx.emit(Event::Activate);
|
||||||
self.has_new_content = false;
|
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 {
|
impl Item for Terminal {
|
||||||
|
@ -488,7 +524,7 @@ mod tests {
|
||||||
//and produce noticable output?
|
//and produce noticable output?
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_terminal(cx: &mut TestAppContext) {
|
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.update(cx, |terminal, cx| {
|
||||||
terminal.write_to_pty(&Input(("expr 3 + 4".to_string()).to_string()), cx);
|
terminal.write_to_pty(&Input(("expr 3 + 4".to_string()).to_string()), cx);
|
||||||
|
|
|
@ -25,7 +25,7 @@ use itertools::Itertools;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use theme::TerminalStyle;
|
use theme::{TerminalColors, TerminalStyle};
|
||||||
|
|
||||||
use crate::{gpui_func_tools::paint_layer, Input, ScrollTerminal, Terminal};
|
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
|
//Now that we're done with the mutable portion, grab the immutable settings and view again
|
||||||
let terminal_theme = &(cx.global::<Settings>()).theme.terminal;
|
let terminal_theme = &(cx.global::<Settings>()).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 grid = term.grid();
|
||||||
let cursor_point = grid.cursor.point;
|
let cursor_point = grid.cursor.point;
|
||||||
|
@ -123,6 +124,7 @@ impl Element for TerminalEl {
|
||||||
&text_style,
|
&text_style,
|
||||||
terminal_theme,
|
terminal_theme,
|
||||||
cx.text_layout_cache,
|
cx.text_layout_cache,
|
||||||
|
view.modal,
|
||||||
);
|
);
|
||||||
|
|
||||||
let cells = layout_cells
|
let cells = layout_cells
|
||||||
|
@ -152,7 +154,7 @@ impl Element for TerminalEl {
|
||||||
cursor_text.len(),
|
cursor_text.len(),
|
||||||
RunStyle {
|
RunStyle {
|
||||||
font_id: text_style.font_id,
|
font_id: text_style.font_id,
|
||||||
color: terminal_theme.background,
|
color: terminal_theme.colors.background,
|
||||||
underline: Default::default(),
|
underline: Default::default(),
|
||||||
},
|
},
|
||||||
)],
|
)],
|
||||||
|
@ -178,12 +180,18 @@ impl Element for TerminalEl {
|
||||||
cursor_position,
|
cursor_position,
|
||||||
block_width,
|
block_width,
|
||||||
line_height.0,
|
line_height.0,
|
||||||
terminal_theme.cursor,
|
terminal_theme.colors.cursor,
|
||||||
CursorShape::Block,
|
CursorShape::Block,
|
||||||
Some(block_text.clone()),
|
Some(block_text.clone()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let background_color = if view.modal {
|
||||||
|
terminal_theme.colors.modal_background
|
||||||
|
} else {
|
||||||
|
terminal_theme.colors.background
|
||||||
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
constraint.max,
|
constraint.max,
|
||||||
LayoutState {
|
LayoutState {
|
||||||
|
@ -193,7 +201,7 @@ impl Element for TerminalEl {
|
||||||
cursor,
|
cursor,
|
||||||
cur_size,
|
cur_size,
|
||||||
background_rects,
|
background_rects,
|
||||||
background_color: terminal_theme.background,
|
background_color,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -348,6 +356,7 @@ fn layout_cells(
|
||||||
text_style: &TextStyle,
|
text_style: &TextStyle,
|
||||||
terminal_theme: &TerminalStyle,
|
terminal_theme: &TerminalStyle,
|
||||||
text_layout_cache: &TextLayoutCache,
|
text_layout_cache: &TextLayoutCache,
|
||||||
|
modal: bool,
|
||||||
) -> Vec<LayoutCell> {
|
) -> Vec<LayoutCell> {
|
||||||
let mut line_count: i32 = 0;
|
let mut line_count: i32 = 0;
|
||||||
let lines = grid.group_by(|i| i.point.line);
|
let lines = grid.group_by(|i| i.point.line);
|
||||||
|
@ -358,7 +367,7 @@ fn layout_cells(
|
||||||
line.map(|indexed_cell| {
|
line.map(|indexed_cell| {
|
||||||
let cell_text = &indexed_cell.c.to_string();
|
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(
|
let layout_cell = text_layout_cache.layout_str(
|
||||||
cell_text,
|
cell_text,
|
||||||
|
@ -368,7 +377,7 @@ fn layout_cells(
|
||||||
LayoutCell::new(
|
LayoutCell::new(
|
||||||
Point::new(line_count - 1, indexed_cell.point.column.0 as i32),
|
Point::new(line_count - 1, indexed_cell.point.column.0 as i32),
|
||||||
layout_cell,
|
layout_cell,
|
||||||
convert_color(&indexed_cell.bg, terminal_theme),
|
convert_color(&indexed_cell.bg, &terminal_theme.colors, modal),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<LayoutCell>>()
|
.collect::<Vec<LayoutCell>>()
|
||||||
|
@ -410,9 +419,14 @@ fn get_cursor_shape(
|
||||||
}
|
}
|
||||||
|
|
||||||
///Convert the Alacritty cell styles to GPUI text styles and background color
|
///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 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
|
let underline = flags
|
||||||
.contains(Flags::UNDERLINE)
|
.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
|
///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 {
|
match alac_color {
|
||||||
//Named and theme defined colors
|
//Named and theme defined colors
|
||||||
alacritty_terminal::ansi::Color::Named(n) => match n {
|
alacritty_terminal::ansi::Color::Named(n) => match n {
|
||||||
alacritty_terminal::ansi::NamedColor::Black => style.black,
|
alacritty_terminal::ansi::NamedColor::Black => colors.black,
|
||||||
alacritty_terminal::ansi::NamedColor::Red => style.red,
|
alacritty_terminal::ansi::NamedColor::Red => colors.red,
|
||||||
alacritty_terminal::ansi::NamedColor::Green => style.green,
|
alacritty_terminal::ansi::NamedColor::Green => colors.green,
|
||||||
alacritty_terminal::ansi::NamedColor::Yellow => style.yellow,
|
alacritty_terminal::ansi::NamedColor::Yellow => colors.yellow,
|
||||||
alacritty_terminal::ansi::NamedColor::Blue => style.blue,
|
alacritty_terminal::ansi::NamedColor::Blue => colors.blue,
|
||||||
alacritty_terminal::ansi::NamedColor::Magenta => style.magenta,
|
alacritty_terminal::ansi::NamedColor::Magenta => colors.magenta,
|
||||||
alacritty_terminal::ansi::NamedColor::Cyan => style.cyan,
|
alacritty_terminal::ansi::NamedColor::Cyan => colors.cyan,
|
||||||
alacritty_terminal::ansi::NamedColor::White => style.white,
|
alacritty_terminal::ansi::NamedColor::White => colors.white,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightBlack => style.bright_black,
|
alacritty_terminal::ansi::NamedColor::BrightBlack => colors.bright_black,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightRed => style.bright_red,
|
alacritty_terminal::ansi::NamedColor::BrightRed => colors.bright_red,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightGreen => style.bright_green,
|
alacritty_terminal::ansi::NamedColor::BrightGreen => colors.bright_green,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightYellow => style.bright_yellow,
|
alacritty_terminal::ansi::NamedColor::BrightYellow => colors.bright_yellow,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightBlue => style.bright_blue,
|
alacritty_terminal::ansi::NamedColor::BrightBlue => colors.bright_blue,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightMagenta => style.bright_magenta,
|
alacritty_terminal::ansi::NamedColor::BrightMagenta => colors.bright_magenta,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightCyan => style.bright_cyan,
|
alacritty_terminal::ansi::NamedColor::BrightCyan => colors.bright_cyan,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightWhite => style.bright_white,
|
alacritty_terminal::ansi::NamedColor::BrightWhite => colors.bright_white,
|
||||||
alacritty_terminal::ansi::NamedColor::Foreground => style.foreground,
|
alacritty_terminal::ansi::NamedColor::Foreground => colors.foreground,
|
||||||
alacritty_terminal::ansi::NamedColor::Background => style.background,
|
alacritty_terminal::ansi::NamedColor::Background => background,
|
||||||
alacritty_terminal::ansi::NamedColor::Cursor => style.cursor,
|
alacritty_terminal::ansi::NamedColor::Cursor => colors.cursor,
|
||||||
alacritty_terminal::ansi::NamedColor::DimBlack => style.dim_black,
|
alacritty_terminal::ansi::NamedColor::DimBlack => colors.dim_black,
|
||||||
alacritty_terminal::ansi::NamedColor::DimRed => style.dim_red,
|
alacritty_terminal::ansi::NamedColor::DimRed => colors.dim_red,
|
||||||
alacritty_terminal::ansi::NamedColor::DimGreen => style.dim_green,
|
alacritty_terminal::ansi::NamedColor::DimGreen => colors.dim_green,
|
||||||
alacritty_terminal::ansi::NamedColor::DimYellow => style.dim_yellow,
|
alacritty_terminal::ansi::NamedColor::DimYellow => colors.dim_yellow,
|
||||||
alacritty_terminal::ansi::NamedColor::DimBlue => style.dim_blue,
|
alacritty_terminal::ansi::NamedColor::DimBlue => colors.dim_blue,
|
||||||
alacritty_terminal::ansi::NamedColor::DimMagenta => style.dim_magenta,
|
alacritty_terminal::ansi::NamedColor::DimMagenta => colors.dim_magenta,
|
||||||
alacritty_terminal::ansi::NamedColor::DimCyan => style.dim_cyan,
|
alacritty_terminal::ansi::NamedColor::DimCyan => colors.dim_cyan,
|
||||||
alacritty_terminal::ansi::NamedColor::DimWhite => style.dim_white,
|
alacritty_terminal::ansi::NamedColor::DimWhite => colors.dim_white,
|
||||||
alacritty_terminal::ansi::NamedColor::BrightForeground => style.bright_foreground,
|
alacritty_terminal::ansi::NamedColor::BrightForeground => colors.bright_foreground,
|
||||||
alacritty_terminal::ansi::NamedColor::DimForeground => style.dim_foreground,
|
alacritty_terminal::ansi::NamedColor::DimForeground => colors.dim_foreground,
|
||||||
},
|
},
|
||||||
//'True' colors
|
//'True' colors
|
||||||
alacritty_terminal::ansi::Color::Spec(rgb) => Color::new(rgb.r, rgb.g, rgb.b, u8::MAX),
|
alacritty_terminal::ansi::Color::Spec(rgb) => Color::new(rgb.r, rgb.g, rgb.b, u8::MAX),
|
||||||
//8 bit, indexed colors
|
//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.
|
///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 {
|
match index {
|
||||||
//0-15 are the same as the named colors above
|
//0-15 are the same as the named colors above
|
||||||
0 => style.black,
|
0 => colors.black,
|
||||||
1 => style.red,
|
1 => colors.red,
|
||||||
2 => style.green,
|
2 => colors.green,
|
||||||
3 => style.yellow,
|
3 => colors.yellow,
|
||||||
4 => style.blue,
|
4 => colors.blue,
|
||||||
5 => style.magenta,
|
5 => colors.magenta,
|
||||||
6 => style.cyan,
|
6 => colors.cyan,
|
||||||
7 => style.white,
|
7 => colors.white,
|
||||||
8 => style.bright_black,
|
8 => colors.bright_black,
|
||||||
9 => style.bright_red,
|
9 => colors.bright_red,
|
||||||
10 => style.bright_green,
|
10 => colors.bright_green,
|
||||||
11 => style.bright_yellow,
|
11 => colors.bright_yellow,
|
||||||
12 => style.bright_blue,
|
12 => colors.bright_blue,
|
||||||
13 => style.bright_magenta,
|
13 => colors.bright_magenta,
|
||||||
14 => style.bright_cyan,
|
14 => colors.bright_cyan,
|
||||||
15 => style.bright_white,
|
15 => colors.bright_white,
|
||||||
//16-231 are mapped to their RGB colors on a 0-5 range per channel
|
//16-231 are mapped to their RGB colors on a 0-5 range per channel
|
||||||
16..=231 => {
|
16..=231 => {
|
||||||
let (r, g, b) = rgb_for_index(index); //Split the index into it's ANSI-RGB components
|
let (r, g, b) = rgb_for_index(index); //Split the index into it's ANSI-RGB components
|
||||||
|
|
|
@ -637,6 +637,12 @@ pub struct HoverPopover {
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Default)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
pub struct TerminalStyle {
|
pub struct TerminalStyle {
|
||||||
|
pub colors: TerminalColors,
|
||||||
|
pub modal_container: ContainerStyle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Default)]
|
||||||
|
pub struct TerminalColors {
|
||||||
pub black: Color,
|
pub black: Color,
|
||||||
pub red: Color,
|
pub red: Color,
|
||||||
pub green: Color,
|
pub green: Color,
|
||||||
|
@ -655,6 +661,7 @@ pub struct TerminalStyle {
|
||||||
pub bright_white: Color,
|
pub bright_white: Color,
|
||||||
pub foreground: Color,
|
pub foreground: Color,
|
||||||
pub background: Color,
|
pub background: Color,
|
||||||
|
pub modal_background: Color,
|
||||||
pub cursor: Color,
|
pub cursor: Color,
|
||||||
pub dim_black: Color,
|
pub dim_black: Color,
|
||||||
pub dim_red: Color,
|
pub dim_red: Color,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import Theme from "../themes/common/theme";
|
import Theme from "../themes/common/theme";
|
||||||
|
import { border, modalShadow } from "./components";
|
||||||
|
|
||||||
export default function terminal(theme: Theme) {
|
export default function terminal(theme: Theme) {
|
||||||
return {
|
let colors = {
|
||||||
black: theme.ramps.neutral(0).hex(),
|
black: theme.ramps.neutral(0).hex(),
|
||||||
red: theme.ramps.red(0.5).hex(),
|
red: theme.ramps.red(0.5).hex(),
|
||||||
green: theme.ramps.green(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(),
|
brightWhite: theme.ramps.neutral(7).hex(),
|
||||||
foreground: theme.ramps.neutral(7).hex(),
|
foreground: theme.ramps.neutral(7).hex(),
|
||||||
background: theme.ramps.neutral(0).hex(),
|
background: theme.ramps.neutral(0).hex(),
|
||||||
|
modalBackground: theme.ramps.neutral(1).hex(),
|
||||||
cursor: theme.ramps.neutral(7).hex(),
|
cursor: theme.ramps.neutral(7).hex(),
|
||||||
dimBlack: theme.ramps.neutral(7).hex(),
|
dimBlack: theme.ramps.neutral(7).hex(),
|
||||||
dimRed: theme.ramps.red(0.75).hex(),
|
dimRed: theme.ramps.red(0.75).hex(),
|
||||||
|
@ -32,4 +34,16 @@ export default function terminal(theme: Theme) {
|
||||||
brightForeground: theme.ramps.neutral(7).hex(),
|
brightForeground: theme.ramps.neutral(7).hex(),
|
||||||
dimForeground: theme.ramps.neutral(0).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),
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue