New themes
This commit is contained in:
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
## [0.0.8] - 2026-06-05
|
## [0.0.8] - 2026-06-05
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- New themes: **Eden** (dark forest — black background with green-only palette, terminal aesthetic) and **Georges** (Commodore 64 palette on pure black background).
|
||||||
|
|
||||||
### Improved
|
### Improved
|
||||||
- Sample library browser: search now shows folder names only (no files) while typing, sorted by fuzzy match score. After confirming search with Enter, folders can be expanded and collapsed normally. Esc clears the search filter before closing the panel. Left arrow on a file collapses the parent folder. Cursor and scroll position stay valid after expand/collapse operations.
|
- Sample library browser: search now shows folder names only (no files) while typing, sorted by fuzzy match score. After confirming search with Enter, folders can be expanded and collapsed normally. Esc clears the search filter before closing the panel. Left arrow on a file collapses the parent folder. Cursor and scroll position stay valid after expand/collapse operations.
|
||||||
- RAM optimizations saving ~5 MB at startup plus smaller enums and fewer hot-path allocations:
|
- RAM optimizations saving ~5 MB at startup plus smaller enums and fewer hot-path allocations:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::ops::Op;
|
use super::ops::Op;
|
||||||
@@ -88,18 +89,18 @@ fn tokenize(input: &str) -> Vec<Token> {
|
|||||||
let span = SourceSpan { start: start as u32, end: end as u32 };
|
let span = SourceSpan { start: start as u32, end: end as u32 };
|
||||||
|
|
||||||
// Normalize shorthand float syntax: .25 -> 0.25, -.5 -> -0.5
|
// Normalize shorthand float syntax: .25 -> 0.25, -.5 -> -0.5
|
||||||
let word_to_parse = if word.starts_with('.')
|
let word_to_parse: Cow<str> = if word.starts_with('.')
|
||||||
&& word.len() > 1
|
&& word.len() > 1
|
||||||
&& word.as_bytes()[1].is_ascii_digit()
|
&& word.as_bytes()[1].is_ascii_digit()
|
||||||
{
|
{
|
||||||
format!("0{word}")
|
Cow::Owned(format!("0{word}"))
|
||||||
} else if word.starts_with("-.")
|
} else if word.starts_with("-.")
|
||||||
&& word.len() > 2
|
&& word.len() > 2
|
||||||
&& word.as_bytes()[2].is_ascii_digit()
|
&& word.as_bytes()[2].is_ascii_digit()
|
||||||
{
|
{
|
||||||
format!("-0{}", &word[1..])
|
Cow::Owned(format!("-0{}", &word[1..]))
|
||||||
} else {
|
} else {
|
||||||
word.clone()
|
Cow::Borrowed(&word)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(i) = word_to_parse.parse::<i64>() {
|
if let Ok(i) = word_to_parse.parse::<i64>() {
|
||||||
@@ -121,20 +122,10 @@ fn compile(tokens: &[Token], dict: &Dictionary) -> Result<Vec<Op>, String> {
|
|||||||
while i < tokens.len() {
|
while i < tokens.len() {
|
||||||
match &tokens[i] {
|
match &tokens[i] {
|
||||||
Token::Int(n, span) => {
|
Token::Int(n, span) => {
|
||||||
let key = n.to_string();
|
ops.push(Op::PushInt(*n, Some(*span)));
|
||||||
if let Some(body) = dict.lock().get(&key).cloned() {
|
|
||||||
ops.extend(body);
|
|
||||||
} else {
|
|
||||||
ops.push(Op::PushInt(*n, Some(*span)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Token::Float(f, span) => {
|
Token::Float(f, span) => {
|
||||||
let key = f.to_string();
|
ops.push(Op::PushFloat(*f, Some(*span)));
|
||||||
if let Some(body) = dict.lock().get(&key).cloned() {
|
|
||||||
ops.extend(body);
|
|
||||||
} else {
|
|
||||||
ops.push(Op::PushFloat(*f, Some(*span)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Token::Str(s, span) => ops.push(Op::PushStr(Arc::from(s.as_str()), Some(*span))),
|
Token::Str(s, span) => ops.push(Op::PushStr(Arc::from(s.as_str()), Some(*span))),
|
||||||
Token::Word(w, span) => {
|
Token::Word(w, span) => {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use tui_textarea::TextArea;
|
|||||||
|
|
||||||
pub type Highlighter<'a> = &'a dyn Fn(usize, &str) -> Vec<(Style, String)>;
|
pub type Highlighter<'a> = &'a dyn Fn(usize, &str) -> Vec<(Style, String)>;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct CompletionCandidate {
|
pub struct CompletionCandidate {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub signature: String,
|
pub signature: String,
|
||||||
|
|||||||
282
crates/ratatui/src/theme/eden.rs
Normal file
282
crates/ratatui/src/theme/eden.rs
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
use super::*;
|
||||||
|
use ratatui::style::Color;
|
||||||
|
|
||||||
|
pub fn theme() -> ThemeColors {
|
||||||
|
let bg = Color::Rgb(8, 12, 8);
|
||||||
|
let surface = Color::Rgb(16, 24, 16);
|
||||||
|
let surface2 = Color::Rgb(24, 32, 24);
|
||||||
|
let border = Color::Rgb(32, 48, 32);
|
||||||
|
let fg = Color::Rgb(200, 216, 192);
|
||||||
|
let fg_dim = Color::Rgb(122, 144, 112);
|
||||||
|
let fg_muted = Color::Rgb(64, 88, 56);
|
||||||
|
|
||||||
|
let green = Color::Rgb(64, 192, 64);
|
||||||
|
let bright_green = Color::Rgb(96, 224, 96);
|
||||||
|
let dark_green = Color::Rgb(48, 128, 48);
|
||||||
|
let cyan = Color::Rgb(80, 168, 144);
|
||||||
|
let yellow = Color::Rgb(160, 160, 64);
|
||||||
|
let red = Color::Rgb(192, 80, 64);
|
||||||
|
let orange = Color::Rgb(176, 128, 48);
|
||||||
|
let blue = Color::Rgb(80, 128, 160);
|
||||||
|
let purple = Color::Rgb(128, 104, 144);
|
||||||
|
|
||||||
|
ThemeColors {
|
||||||
|
ui: UiColors {
|
||||||
|
bg,
|
||||||
|
bg_rgb: (8, 12, 8),
|
||||||
|
text_primary: fg,
|
||||||
|
text_muted: fg_dim,
|
||||||
|
text_dim: fg_muted,
|
||||||
|
border,
|
||||||
|
header: green,
|
||||||
|
unfocused: fg_muted,
|
||||||
|
accent: green,
|
||||||
|
surface,
|
||||||
|
},
|
||||||
|
status: StatusColors {
|
||||||
|
playing_bg: Color::Rgb(14, 30, 14),
|
||||||
|
playing_fg: bright_green,
|
||||||
|
stopped_bg: Color::Rgb(36, 16, 14),
|
||||||
|
stopped_fg: red,
|
||||||
|
fill_on: green,
|
||||||
|
fill_off: dark_green,
|
||||||
|
fill_bg: surface,
|
||||||
|
},
|
||||||
|
selection: SelectionColors {
|
||||||
|
cursor_bg: green,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selected_bg: Color::Rgb(20, 40, 20),
|
||||||
|
selected_fg: bright_green,
|
||||||
|
in_range_bg: Color::Rgb(16, 30, 16),
|
||||||
|
in_range_fg: fg,
|
||||||
|
cursor: green,
|
||||||
|
selected: Color::Rgb(20, 40, 20),
|
||||||
|
in_range: Color::Rgb(16, 30, 16),
|
||||||
|
},
|
||||||
|
tile: TileColors {
|
||||||
|
playing_active_bg: Color::Rgb(16, 38, 16),
|
||||||
|
playing_active_fg: bright_green,
|
||||||
|
playing_inactive_bg: Color::Rgb(28, 36, 14),
|
||||||
|
playing_inactive_fg: yellow,
|
||||||
|
active_bg: Color::Rgb(14, 28, 26),
|
||||||
|
active_fg: cyan,
|
||||||
|
inactive_bg: surface,
|
||||||
|
inactive_fg: fg_dim,
|
||||||
|
active_selected_bg: Color::Rgb(22, 36, 28),
|
||||||
|
active_in_range_bg: Color::Rgb(16, 28, 20),
|
||||||
|
link_bright: [
|
||||||
|
(64, 192, 64),
|
||||||
|
(80, 168, 144),
|
||||||
|
(160, 160, 64),
|
||||||
|
(80, 128, 160),
|
||||||
|
(192, 80, 64),
|
||||||
|
],
|
||||||
|
link_dim: [
|
||||||
|
(14, 38, 14),
|
||||||
|
(16, 34, 28),
|
||||||
|
(32, 32, 14),
|
||||||
|
(16, 26, 32),
|
||||||
|
(38, 16, 14),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
header: HeaderColors {
|
||||||
|
tempo_bg: Color::Rgb(26, 22, 30),
|
||||||
|
tempo_fg: purple,
|
||||||
|
bank_bg: Color::Rgb(16, 26, 32),
|
||||||
|
bank_fg: blue,
|
||||||
|
pattern_bg: Color::Rgb(14, 28, 26),
|
||||||
|
pattern_fg: cyan,
|
||||||
|
stats_bg: surface,
|
||||||
|
stats_fg: fg_dim,
|
||||||
|
},
|
||||||
|
modal: ModalColors {
|
||||||
|
border: green,
|
||||||
|
border_accent: bright_green,
|
||||||
|
border_warn: yellow,
|
||||||
|
border_dim: fg_muted,
|
||||||
|
confirm: red,
|
||||||
|
rename: green,
|
||||||
|
input: cyan,
|
||||||
|
editor: green,
|
||||||
|
preview: fg_muted,
|
||||||
|
},
|
||||||
|
flash: FlashColors {
|
||||||
|
error_bg: Color::Rgb(40, 16, 14),
|
||||||
|
error_fg: red,
|
||||||
|
success_bg: Color::Rgb(14, 32, 14),
|
||||||
|
success_fg: bright_green,
|
||||||
|
info_bg: surface,
|
||||||
|
info_fg: fg,
|
||||||
|
},
|
||||||
|
list: ListColors {
|
||||||
|
playing_bg: Color::Rgb(14, 32, 14),
|
||||||
|
playing_fg: bright_green,
|
||||||
|
staged_play_bg: Color::Rgb(26, 22, 30),
|
||||||
|
staged_play_fg: purple,
|
||||||
|
staged_stop_bg: Color::Rgb(40, 16, 14),
|
||||||
|
staged_stop_fg: red,
|
||||||
|
edit_bg: Color::Rgb(14, 28, 26),
|
||||||
|
edit_fg: cyan,
|
||||||
|
hover_bg: surface2,
|
||||||
|
hover_fg: fg,
|
||||||
|
muted_bg: Color::Rgb(10, 14, 10),
|
||||||
|
muted_fg: fg_muted,
|
||||||
|
soloed_bg: Color::Rgb(30, 30, 14),
|
||||||
|
soloed_fg: yellow,
|
||||||
|
},
|
||||||
|
link_status: LinkStatusColors {
|
||||||
|
disabled: red,
|
||||||
|
connected: bright_green,
|
||||||
|
listening: yellow,
|
||||||
|
},
|
||||||
|
syntax: SyntaxColors {
|
||||||
|
gap_bg: bg,
|
||||||
|
executed_bg: Color::Rgb(14, 24, 14),
|
||||||
|
selected_bg: Color::Rgb(20, 40, 16),
|
||||||
|
emit: (fg, Color::Rgb(20, 34, 20)),
|
||||||
|
number: (yellow, Color::Rgb(30, 30, 12)),
|
||||||
|
string: (bright_green, Color::Rgb(16, 32, 16)),
|
||||||
|
comment: (fg_muted, bg),
|
||||||
|
keyword: (red, Color::Rgb(38, 18, 14)),
|
||||||
|
stack_op: (blue, Color::Rgb(16, 26, 32)),
|
||||||
|
operator: (green, Color::Rgb(14, 36, 14)),
|
||||||
|
sound: (cyan, Color::Rgb(16, 30, 28)),
|
||||||
|
param: (purple, Color::Rgb(26, 22, 28)),
|
||||||
|
context: (orange, Color::Rgb(34, 26, 12)),
|
||||||
|
note: (bright_green, Color::Rgb(16, 34, 16)),
|
||||||
|
interval: (Color::Rgb(100, 180, 100), Color::Rgb(18, 34, 18)),
|
||||||
|
variable: (purple, Color::Rgb(26, 22, 28)),
|
||||||
|
vary: (yellow, Color::Rgb(30, 30, 12)),
|
||||||
|
generator: (cyan, Color::Rgb(16, 30, 26)),
|
||||||
|
default: (fg_dim, bg),
|
||||||
|
},
|
||||||
|
table: TableColors {
|
||||||
|
row_even: bg,
|
||||||
|
row_odd: surface,
|
||||||
|
},
|
||||||
|
values: ValuesColors {
|
||||||
|
tempo: green,
|
||||||
|
value: fg_dim,
|
||||||
|
},
|
||||||
|
hint: HintColors {
|
||||||
|
key: green,
|
||||||
|
text: fg_muted,
|
||||||
|
},
|
||||||
|
view_badge: ViewBadgeColors { bg: fg, fg: bg },
|
||||||
|
nav: NavColors {
|
||||||
|
selected_bg: Color::Rgb(18, 38, 18),
|
||||||
|
selected_fg: fg,
|
||||||
|
unselected_bg: surface,
|
||||||
|
unselected_fg: fg_muted,
|
||||||
|
},
|
||||||
|
editor_widget: EditorWidgetColors {
|
||||||
|
cursor_bg: fg,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selection_bg: Color::Rgb(24, 48, 24),
|
||||||
|
completion_bg: surface,
|
||||||
|
completion_fg: fg,
|
||||||
|
completion_selected: green,
|
||||||
|
completion_example: cyan,
|
||||||
|
},
|
||||||
|
browser: BrowserColors {
|
||||||
|
directory: blue,
|
||||||
|
project_file: green,
|
||||||
|
selected: bright_green,
|
||||||
|
file: fg,
|
||||||
|
focused_border: green,
|
||||||
|
unfocused_border: fg_muted,
|
||||||
|
root: fg,
|
||||||
|
file_icon: fg_muted,
|
||||||
|
folder_icon: blue,
|
||||||
|
empty_text: fg_muted,
|
||||||
|
},
|
||||||
|
input: InputColors {
|
||||||
|
text: green,
|
||||||
|
cursor: fg,
|
||||||
|
hint: fg_muted,
|
||||||
|
},
|
||||||
|
search: SearchColors {
|
||||||
|
active: green,
|
||||||
|
inactive: fg_muted,
|
||||||
|
match_bg: yellow,
|
||||||
|
match_fg: bg,
|
||||||
|
},
|
||||||
|
markdown: MarkdownColors {
|
||||||
|
h1: green,
|
||||||
|
h2: cyan,
|
||||||
|
h3: purple,
|
||||||
|
code: bright_green,
|
||||||
|
code_border: Color::Rgb(28, 42, 28),
|
||||||
|
link: cyan,
|
||||||
|
link_url: Color::Rgb(56, 72, 52),
|
||||||
|
quote: fg_muted,
|
||||||
|
text: fg,
|
||||||
|
list: fg,
|
||||||
|
},
|
||||||
|
engine: EngineColors {
|
||||||
|
header: green,
|
||||||
|
header_focused: bright_green,
|
||||||
|
divider: Color::Rgb(24, 36, 24),
|
||||||
|
scroll_indicator: Color::Rgb(36, 52, 36),
|
||||||
|
label: Color::Rgb(100, 120, 92),
|
||||||
|
label_focused: Color::Rgb(140, 160, 130),
|
||||||
|
label_dim: Color::Rgb(68, 84, 60),
|
||||||
|
value: Color::Rgb(180, 196, 172),
|
||||||
|
focused: bright_green,
|
||||||
|
normal: fg,
|
||||||
|
dim: Color::Rgb(36, 52, 36),
|
||||||
|
path: Color::Rgb(100, 120, 92),
|
||||||
|
border_magenta: purple,
|
||||||
|
border_green: green,
|
||||||
|
border_cyan: cyan,
|
||||||
|
separator: Color::Rgb(24, 36, 24),
|
||||||
|
hint_active: green,
|
||||||
|
hint_inactive: Color::Rgb(24, 36, 24),
|
||||||
|
},
|
||||||
|
dict: DictColors {
|
||||||
|
word_name: bright_green,
|
||||||
|
word_bg: Color::Rgb(14, 24, 14),
|
||||||
|
alias: fg_muted,
|
||||||
|
stack_sig: purple,
|
||||||
|
description: fg,
|
||||||
|
example: Color::Rgb(100, 120, 92),
|
||||||
|
category_focused: bright_green,
|
||||||
|
category_selected: green,
|
||||||
|
category_normal: fg,
|
||||||
|
category_dimmed: Color::Rgb(36, 52, 36),
|
||||||
|
border_focused: bright_green,
|
||||||
|
border_normal: Color::Rgb(24, 36, 24),
|
||||||
|
header_desc: Color::Rgb(120, 140, 112),
|
||||||
|
},
|
||||||
|
title: TitleColors {
|
||||||
|
big_title: green,
|
||||||
|
author: cyan,
|
||||||
|
link: bright_green,
|
||||||
|
license: yellow,
|
||||||
|
prompt: Color::Rgb(100, 120, 92),
|
||||||
|
subtitle: fg,
|
||||||
|
},
|
||||||
|
meter: MeterColors {
|
||||||
|
low: green,
|
||||||
|
mid: yellow,
|
||||||
|
high: red,
|
||||||
|
low_rgb: (64, 192, 64),
|
||||||
|
mid_rgb: (160, 160, 64),
|
||||||
|
high_rgb: (192, 80, 64),
|
||||||
|
},
|
||||||
|
sparkle: SparkleColors {
|
||||||
|
colors: [
|
||||||
|
(64, 192, 64),
|
||||||
|
(96, 224, 96),
|
||||||
|
(80, 168, 144),
|
||||||
|
(160, 160, 64),
|
||||||
|
(48, 128, 48),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
confirm: ConfirmColors {
|
||||||
|
border: red,
|
||||||
|
button_selected_bg: green,
|
||||||
|
button_selected_fg: bg,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
280
crates/ratatui/src/theme/ember.rs
Normal file
280
crates/ratatui/src/theme/ember.rs
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
use super::*;
|
||||||
|
use ratatui::style::Color;
|
||||||
|
|
||||||
|
pub fn theme() -> ThemeColors {
|
||||||
|
let bg = Color::Rgb(10, 8, 8);
|
||||||
|
let surface = Color::Rgb(20, 16, 16);
|
||||||
|
let surface2 = Color::Rgb(26, 20, 20);
|
||||||
|
let border = Color::Rgb(42, 32, 32);
|
||||||
|
let fg = Color::Rgb(232, 221, 208);
|
||||||
|
let fg_dim = Color::Rgb(160, 144, 128);
|
||||||
|
let fg_muted = Color::Rgb(96, 80, 64);
|
||||||
|
|
||||||
|
let red = Color::Rgb(224, 80, 64);
|
||||||
|
let orange = Color::Rgb(224, 128, 48);
|
||||||
|
let yellow = Color::Rgb(208, 160, 48);
|
||||||
|
let green = Color::Rgb(128, 160, 80);
|
||||||
|
let cyan = Color::Rgb(112, 160, 160);
|
||||||
|
let purple = Color::Rgb(160, 112, 144);
|
||||||
|
let blue = Color::Rgb(96, 128, 176);
|
||||||
|
|
||||||
|
ThemeColors {
|
||||||
|
ui: UiColors {
|
||||||
|
bg,
|
||||||
|
bg_rgb: (10, 8, 8),
|
||||||
|
text_primary: fg,
|
||||||
|
text_muted: fg_dim,
|
||||||
|
text_dim: fg_muted,
|
||||||
|
border,
|
||||||
|
header: orange,
|
||||||
|
unfocused: fg_muted,
|
||||||
|
accent: orange,
|
||||||
|
surface,
|
||||||
|
},
|
||||||
|
status: StatusColors {
|
||||||
|
playing_bg: Color::Rgb(20, 28, 16),
|
||||||
|
playing_fg: green,
|
||||||
|
stopped_bg: Color::Rgb(40, 16, 14),
|
||||||
|
stopped_fg: red,
|
||||||
|
fill_on: orange,
|
||||||
|
fill_off: fg_muted,
|
||||||
|
fill_bg: surface,
|
||||||
|
},
|
||||||
|
selection: SelectionColors {
|
||||||
|
cursor_bg: orange,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selected_bg: Color::Rgb(50, 35, 20),
|
||||||
|
selected_fg: orange,
|
||||||
|
in_range_bg: Color::Rgb(35, 25, 18),
|
||||||
|
in_range_fg: fg,
|
||||||
|
cursor: orange,
|
||||||
|
selected: Color::Rgb(50, 35, 20),
|
||||||
|
in_range: Color::Rgb(35, 25, 18),
|
||||||
|
},
|
||||||
|
tile: TileColors {
|
||||||
|
playing_active_bg: Color::Rgb(45, 25, 15),
|
||||||
|
playing_active_fg: orange,
|
||||||
|
playing_inactive_bg: Color::Rgb(40, 32, 12),
|
||||||
|
playing_inactive_fg: yellow,
|
||||||
|
active_bg: Color::Rgb(20, 30, 30),
|
||||||
|
active_fg: cyan,
|
||||||
|
inactive_bg: surface,
|
||||||
|
inactive_fg: fg_dim,
|
||||||
|
active_selected_bg: Color::Rgb(40, 30, 35),
|
||||||
|
active_in_range_bg: Color::Rgb(30, 25, 25),
|
||||||
|
link_bright: [
|
||||||
|
(224, 128, 48),
|
||||||
|
(224, 80, 64),
|
||||||
|
(208, 160, 48),
|
||||||
|
(112, 160, 160),
|
||||||
|
(128, 160, 80),
|
||||||
|
],
|
||||||
|
link_dim: [
|
||||||
|
(45, 28, 14),
|
||||||
|
(45, 18, 14),
|
||||||
|
(42, 32, 12),
|
||||||
|
(22, 32, 32),
|
||||||
|
(26, 32, 18),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
header: HeaderColors {
|
||||||
|
tempo_bg: Color::Rgb(40, 28, 30),
|
||||||
|
tempo_fg: purple,
|
||||||
|
bank_bg: Color::Rgb(22, 30, 40),
|
||||||
|
bank_fg: blue,
|
||||||
|
pattern_bg: Color::Rgb(22, 34, 34),
|
||||||
|
pattern_fg: cyan,
|
||||||
|
stats_bg: surface,
|
||||||
|
stats_fg: fg_dim,
|
||||||
|
},
|
||||||
|
modal: ModalColors {
|
||||||
|
border: orange,
|
||||||
|
border_accent: red,
|
||||||
|
border_warn: yellow,
|
||||||
|
border_dim: fg_muted,
|
||||||
|
confirm: red,
|
||||||
|
rename: orange,
|
||||||
|
input: cyan,
|
||||||
|
editor: orange,
|
||||||
|
preview: fg_muted,
|
||||||
|
},
|
||||||
|
flash: FlashColors {
|
||||||
|
error_bg: Color::Rgb(50, 16, 14),
|
||||||
|
error_fg: red,
|
||||||
|
success_bg: Color::Rgb(20, 35, 18),
|
||||||
|
success_fg: green,
|
||||||
|
info_bg: surface,
|
||||||
|
info_fg: fg,
|
||||||
|
},
|
||||||
|
list: ListColors {
|
||||||
|
playing_bg: Color::Rgb(20, 35, 18),
|
||||||
|
playing_fg: green,
|
||||||
|
staged_play_bg: Color::Rgb(35, 25, 30),
|
||||||
|
staged_play_fg: purple,
|
||||||
|
staged_stop_bg: Color::Rgb(45, 18, 16),
|
||||||
|
staged_stop_fg: red,
|
||||||
|
edit_bg: Color::Rgb(20, 32, 32),
|
||||||
|
edit_fg: cyan,
|
||||||
|
hover_bg: surface2,
|
||||||
|
hover_fg: fg,
|
||||||
|
muted_bg: Color::Rgb(18, 14, 14),
|
||||||
|
muted_fg: fg_muted,
|
||||||
|
soloed_bg: Color::Rgb(40, 32, 12),
|
||||||
|
soloed_fg: yellow,
|
||||||
|
},
|
||||||
|
link_status: LinkStatusColors {
|
||||||
|
disabled: red,
|
||||||
|
connected: green,
|
||||||
|
listening: yellow,
|
||||||
|
},
|
||||||
|
syntax: SyntaxColors {
|
||||||
|
gap_bg: bg,
|
||||||
|
executed_bg: Color::Rgb(25, 18, 14),
|
||||||
|
selected_bg: Color::Rgb(45, 30, 15),
|
||||||
|
emit: (fg, Color::Rgb(45, 20, 18)),
|
||||||
|
number: (yellow, Color::Rgb(40, 30, 12)),
|
||||||
|
string: (green, Color::Rgb(25, 30, 18)),
|
||||||
|
comment: (fg_muted, bg),
|
||||||
|
keyword: (red, Color::Rgb(42, 18, 15)),
|
||||||
|
stack_op: (blue, Color::Rgb(22, 28, 38)),
|
||||||
|
operator: (orange, Color::Rgb(42, 26, 12)),
|
||||||
|
sound: (cyan, Color::Rgb(22, 32, 32)),
|
||||||
|
param: (purple, Color::Rgb(32, 24, 28)),
|
||||||
|
context: (orange, Color::Rgb(42, 26, 12)),
|
||||||
|
note: (green, Color::Rgb(25, 30, 18)),
|
||||||
|
interval: (Color::Rgb(150, 180, 100), Color::Rgb(28, 34, 20)),
|
||||||
|
variable: (purple, Color::Rgb(32, 24, 28)),
|
||||||
|
vary: (yellow, Color::Rgb(40, 30, 12)),
|
||||||
|
generator: (cyan, Color::Rgb(22, 32, 30)),
|
||||||
|
default: (fg_dim, bg),
|
||||||
|
},
|
||||||
|
table: TableColors {
|
||||||
|
row_even: bg,
|
||||||
|
row_odd: surface,
|
||||||
|
},
|
||||||
|
values: ValuesColors {
|
||||||
|
tempo: orange,
|
||||||
|
value: fg_dim,
|
||||||
|
},
|
||||||
|
hint: HintColors {
|
||||||
|
key: orange,
|
||||||
|
text: fg_muted,
|
||||||
|
},
|
||||||
|
view_badge: ViewBadgeColors { bg: fg, fg: bg },
|
||||||
|
nav: NavColors {
|
||||||
|
selected_bg: Color::Rgb(45, 30, 20),
|
||||||
|
selected_fg: fg,
|
||||||
|
unselected_bg: surface,
|
||||||
|
unselected_fg: fg_muted,
|
||||||
|
},
|
||||||
|
editor_widget: EditorWidgetColors {
|
||||||
|
cursor_bg: fg,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selection_bg: Color::Rgb(50, 35, 25),
|
||||||
|
completion_bg: surface,
|
||||||
|
completion_fg: fg,
|
||||||
|
completion_selected: orange,
|
||||||
|
completion_example: cyan,
|
||||||
|
},
|
||||||
|
browser: BrowserColors {
|
||||||
|
directory: blue,
|
||||||
|
project_file: orange,
|
||||||
|
selected: red,
|
||||||
|
file: fg,
|
||||||
|
focused_border: orange,
|
||||||
|
unfocused_border: fg_muted,
|
||||||
|
root: fg,
|
||||||
|
file_icon: fg_muted,
|
||||||
|
folder_icon: blue,
|
||||||
|
empty_text: fg_muted,
|
||||||
|
},
|
||||||
|
input: InputColors {
|
||||||
|
text: orange,
|
||||||
|
cursor: fg,
|
||||||
|
hint: fg_muted,
|
||||||
|
},
|
||||||
|
search: SearchColors {
|
||||||
|
active: orange,
|
||||||
|
inactive: fg_muted,
|
||||||
|
match_bg: yellow,
|
||||||
|
match_fg: bg,
|
||||||
|
},
|
||||||
|
markdown: MarkdownColors {
|
||||||
|
h1: orange,
|
||||||
|
h2: red,
|
||||||
|
h3: purple,
|
||||||
|
code: green,
|
||||||
|
code_border: Color::Rgb(50, 38, 38),
|
||||||
|
link: cyan,
|
||||||
|
link_url: Color::Rgb(80, 68, 56),
|
||||||
|
quote: fg_muted,
|
||||||
|
text: fg,
|
||||||
|
list: fg,
|
||||||
|
},
|
||||||
|
engine: EngineColors {
|
||||||
|
header: orange,
|
||||||
|
header_focused: yellow,
|
||||||
|
divider: Color::Rgb(38, 30, 30),
|
||||||
|
scroll_indicator: Color::Rgb(55, 42, 42),
|
||||||
|
label: Color::Rgb(130, 115, 100),
|
||||||
|
label_focused: Color::Rgb(170, 155, 140),
|
||||||
|
label_dim: Color::Rgb(90, 76, 64),
|
||||||
|
value: Color::Rgb(200, 188, 175),
|
||||||
|
focused: yellow,
|
||||||
|
normal: fg,
|
||||||
|
dim: Color::Rgb(55, 42, 42),
|
||||||
|
path: Color::Rgb(130, 115, 100),
|
||||||
|
border_magenta: purple,
|
||||||
|
border_green: green,
|
||||||
|
border_cyan: cyan,
|
||||||
|
separator: Color::Rgb(38, 30, 30),
|
||||||
|
hint_active: orange,
|
||||||
|
hint_inactive: Color::Rgb(38, 30, 30),
|
||||||
|
},
|
||||||
|
dict: DictColors {
|
||||||
|
word_name: green,
|
||||||
|
word_bg: Color::Rgb(22, 28, 22),
|
||||||
|
alias: fg_muted,
|
||||||
|
stack_sig: purple,
|
||||||
|
description: fg,
|
||||||
|
example: Color::Rgb(130, 115, 100),
|
||||||
|
category_focused: yellow,
|
||||||
|
category_selected: orange,
|
||||||
|
category_normal: fg,
|
||||||
|
category_dimmed: Color::Rgb(55, 42, 42),
|
||||||
|
border_focused: yellow,
|
||||||
|
border_normal: Color::Rgb(38, 30, 30),
|
||||||
|
header_desc: Color::Rgb(145, 130, 115),
|
||||||
|
},
|
||||||
|
title: TitleColors {
|
||||||
|
big_title: orange,
|
||||||
|
author: red,
|
||||||
|
link: cyan,
|
||||||
|
license: yellow,
|
||||||
|
prompt: Color::Rgb(130, 115, 100),
|
||||||
|
subtitle: fg,
|
||||||
|
},
|
||||||
|
meter: MeterColors {
|
||||||
|
low: green,
|
||||||
|
mid: yellow,
|
||||||
|
high: red,
|
||||||
|
low_rgb: (128, 160, 80),
|
||||||
|
mid_rgb: (208, 160, 48),
|
||||||
|
high_rgb: (224, 80, 64),
|
||||||
|
},
|
||||||
|
sparkle: SparkleColors {
|
||||||
|
colors: [
|
||||||
|
(224, 128, 48),
|
||||||
|
(224, 80, 64),
|
||||||
|
(208, 160, 48),
|
||||||
|
(112, 160, 160),
|
||||||
|
(128, 160, 80),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
confirm: ConfirmColors {
|
||||||
|
border: red,
|
||||||
|
button_selected_bg: orange,
|
||||||
|
button_selected_fg: bg,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
284
crates/ratatui/src/theme/georges.rs
Normal file
284
crates/ratatui/src/theme/georges.rs
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
use super::*;
|
||||||
|
use ratatui::style::Color;
|
||||||
|
|
||||||
|
// C64 palette on pure black
|
||||||
|
pub fn theme() -> ThemeColors {
|
||||||
|
let bg = Color::Rgb(0, 0, 0);
|
||||||
|
let surface = Color::Rgb(16, 16, 16);
|
||||||
|
let surface2 = Color::Rgb(24, 24, 24);
|
||||||
|
let border = Color::Rgb(51, 51, 51);
|
||||||
|
let fg = Color::Rgb(187, 187, 187);
|
||||||
|
let fg_dim = Color::Rgb(119, 119, 119);
|
||||||
|
let fg_muted = Color::Rgb(51, 51, 51);
|
||||||
|
|
||||||
|
let white = Color::Rgb(255, 255, 255);
|
||||||
|
let lightred = Color::Rgb(255, 119, 119);
|
||||||
|
let cyan = Color::Rgb(170, 255, 238);
|
||||||
|
let violet = Color::Rgb(204, 68, 204);
|
||||||
|
let green = Color::Rgb(0, 204, 85);
|
||||||
|
let lightgreen = Color::Rgb(170, 255, 102);
|
||||||
|
let lightblue = Color::Rgb(0, 136, 255);
|
||||||
|
let yellow = Color::Rgb(238, 238, 119);
|
||||||
|
let orange = Color::Rgb(221, 136, 85);
|
||||||
|
let brown = Color::Rgb(102, 68, 0);
|
||||||
|
|
||||||
|
ThemeColors {
|
||||||
|
ui: UiColors {
|
||||||
|
bg,
|
||||||
|
bg_rgb: (0, 0, 0),
|
||||||
|
text_primary: fg,
|
||||||
|
text_muted: fg_dim,
|
||||||
|
text_dim: fg_muted,
|
||||||
|
border,
|
||||||
|
header: lightblue,
|
||||||
|
unfocused: fg_muted,
|
||||||
|
accent: lightblue,
|
||||||
|
surface,
|
||||||
|
},
|
||||||
|
status: StatusColors {
|
||||||
|
playing_bg: Color::Rgb(0, 24, 10),
|
||||||
|
playing_fg: green,
|
||||||
|
stopped_bg: Color::Rgb(28, 0, 0),
|
||||||
|
stopped_fg: lightred,
|
||||||
|
fill_on: lightblue,
|
||||||
|
fill_off: brown,
|
||||||
|
fill_bg: surface,
|
||||||
|
},
|
||||||
|
selection: SelectionColors {
|
||||||
|
cursor_bg: lightblue,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selected_bg: Color::Rgb(0, 20, 40),
|
||||||
|
selected_fg: cyan,
|
||||||
|
in_range_bg: Color::Rgb(0, 14, 28),
|
||||||
|
in_range_fg: fg,
|
||||||
|
cursor: lightblue,
|
||||||
|
selected: Color::Rgb(0, 20, 40),
|
||||||
|
in_range: Color::Rgb(0, 14, 28),
|
||||||
|
},
|
||||||
|
tile: TileColors {
|
||||||
|
playing_active_bg: Color::Rgb(0, 30, 12),
|
||||||
|
playing_active_fg: lightgreen,
|
||||||
|
playing_inactive_bg: Color::Rgb(30, 30, 14),
|
||||||
|
playing_inactive_fg: yellow,
|
||||||
|
active_bg: Color::Rgb(0, 16, 32),
|
||||||
|
active_fg: lightblue,
|
||||||
|
inactive_bg: surface,
|
||||||
|
inactive_fg: fg_dim,
|
||||||
|
active_selected_bg: Color::Rgb(10, 20, 36),
|
||||||
|
active_in_range_bg: Color::Rgb(6, 14, 28),
|
||||||
|
link_bright: [
|
||||||
|
(0, 136, 255),
|
||||||
|
(0, 204, 85),
|
||||||
|
(238, 238, 119),
|
||||||
|
(204, 68, 204),
|
||||||
|
(170, 255, 238),
|
||||||
|
],
|
||||||
|
link_dim: [
|
||||||
|
(0, 20, 40),
|
||||||
|
(0, 30, 12),
|
||||||
|
(34, 34, 16),
|
||||||
|
(30, 10, 30),
|
||||||
|
(24, 36, 34),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
header: HeaderColors {
|
||||||
|
tempo_bg: Color::Rgb(28, 10, 28),
|
||||||
|
tempo_fg: violet,
|
||||||
|
bank_bg: Color::Rgb(0, 0, 24),
|
||||||
|
bank_fg: lightblue,
|
||||||
|
pattern_bg: Color::Rgb(0, 24, 10),
|
||||||
|
pattern_fg: green,
|
||||||
|
stats_bg: surface,
|
||||||
|
stats_fg: fg_dim,
|
||||||
|
},
|
||||||
|
modal: ModalColors {
|
||||||
|
border: lightblue,
|
||||||
|
border_accent: cyan,
|
||||||
|
border_warn: yellow,
|
||||||
|
border_dim: fg_muted,
|
||||||
|
confirm: lightred,
|
||||||
|
rename: lightblue,
|
||||||
|
input: cyan,
|
||||||
|
editor: lightblue,
|
||||||
|
preview: fg_muted,
|
||||||
|
},
|
||||||
|
flash: FlashColors {
|
||||||
|
error_bg: Color::Rgb(28, 0, 0),
|
||||||
|
error_fg: lightred,
|
||||||
|
success_bg: Color::Rgb(0, 24, 10),
|
||||||
|
success_fg: green,
|
||||||
|
info_bg: surface,
|
||||||
|
info_fg: fg,
|
||||||
|
},
|
||||||
|
list: ListColors {
|
||||||
|
playing_bg: Color::Rgb(0, 24, 10),
|
||||||
|
playing_fg: green,
|
||||||
|
staged_play_bg: Color::Rgb(28, 10, 28),
|
||||||
|
staged_play_fg: violet,
|
||||||
|
staged_stop_bg: Color::Rgb(28, 0, 0),
|
||||||
|
staged_stop_fg: lightred,
|
||||||
|
edit_bg: Color::Rgb(0, 16, 32),
|
||||||
|
edit_fg: lightblue,
|
||||||
|
hover_bg: surface2,
|
||||||
|
hover_fg: fg,
|
||||||
|
muted_bg: Color::Rgb(8, 8, 8),
|
||||||
|
muted_fg: fg_muted,
|
||||||
|
soloed_bg: Color::Rgb(30, 30, 14),
|
||||||
|
soloed_fg: yellow,
|
||||||
|
},
|
||||||
|
link_status: LinkStatusColors {
|
||||||
|
disabled: lightred,
|
||||||
|
connected: green,
|
||||||
|
listening: yellow,
|
||||||
|
},
|
||||||
|
syntax: SyntaxColors {
|
||||||
|
gap_bg: bg,
|
||||||
|
executed_bg: Color::Rgb(0, 12, 24),
|
||||||
|
selected_bg: Color::Rgb(0, 20, 40),
|
||||||
|
emit: (white, Color::Rgb(20, 20, 20)),
|
||||||
|
number: (yellow, Color::Rgb(30, 30, 14)),
|
||||||
|
string: (lightgreen, Color::Rgb(18, 30, 12)),
|
||||||
|
comment: (fg_muted, bg),
|
||||||
|
keyword: (lightred, Color::Rgb(30, 14, 14)),
|
||||||
|
stack_op: (lightblue, Color::Rgb(0, 16, 32)),
|
||||||
|
operator: (cyan, Color::Rgb(20, 30, 28)),
|
||||||
|
sound: (green, Color::Rgb(0, 24, 10)),
|
||||||
|
param: (violet, Color::Rgb(24, 8, 24)),
|
||||||
|
context: (orange, Color::Rgb(28, 16, 10)),
|
||||||
|
note: (lightgreen, Color::Rgb(18, 30, 12)),
|
||||||
|
interval: (Color::Rgb(130, 210, 80), Color::Rgb(14, 26, 8)),
|
||||||
|
variable: (violet, Color::Rgb(24, 8, 24)),
|
||||||
|
vary: (yellow, Color::Rgb(30, 30, 14)),
|
||||||
|
generator: (cyan, Color::Rgb(20, 30, 28)),
|
||||||
|
default: (fg_dim, bg),
|
||||||
|
},
|
||||||
|
table: TableColors {
|
||||||
|
row_even: bg,
|
||||||
|
row_odd: surface,
|
||||||
|
},
|
||||||
|
values: ValuesColors {
|
||||||
|
tempo: lightblue,
|
||||||
|
value: fg_dim,
|
||||||
|
},
|
||||||
|
hint: HintColors {
|
||||||
|
key: lightblue,
|
||||||
|
text: fg_muted,
|
||||||
|
},
|
||||||
|
view_badge: ViewBadgeColors { bg: fg, fg: bg },
|
||||||
|
nav: NavColors {
|
||||||
|
selected_bg: Color::Rgb(0, 20, 40),
|
||||||
|
selected_fg: fg,
|
||||||
|
unselected_bg: surface,
|
||||||
|
unselected_fg: fg_muted,
|
||||||
|
},
|
||||||
|
editor_widget: EditorWidgetColors {
|
||||||
|
cursor_bg: fg,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selection_bg: Color::Rgb(0, 24, 48),
|
||||||
|
completion_bg: surface,
|
||||||
|
completion_fg: fg,
|
||||||
|
completion_selected: lightblue,
|
||||||
|
completion_example: cyan,
|
||||||
|
},
|
||||||
|
browser: BrowserColors {
|
||||||
|
directory: lightblue,
|
||||||
|
project_file: green,
|
||||||
|
selected: cyan,
|
||||||
|
file: fg,
|
||||||
|
focused_border: lightblue,
|
||||||
|
unfocused_border: fg_muted,
|
||||||
|
root: fg,
|
||||||
|
file_icon: fg_muted,
|
||||||
|
folder_icon: lightblue,
|
||||||
|
empty_text: fg_muted,
|
||||||
|
},
|
||||||
|
input: InputColors {
|
||||||
|
text: lightblue,
|
||||||
|
cursor: fg,
|
||||||
|
hint: fg_muted,
|
||||||
|
},
|
||||||
|
search: SearchColors {
|
||||||
|
active: lightblue,
|
||||||
|
inactive: fg_muted,
|
||||||
|
match_bg: yellow,
|
||||||
|
match_fg: bg,
|
||||||
|
},
|
||||||
|
markdown: MarkdownColors {
|
||||||
|
h1: lightblue,
|
||||||
|
h2: green,
|
||||||
|
h3: violet,
|
||||||
|
code: lightgreen,
|
||||||
|
code_border: Color::Rgb(36, 36, 36),
|
||||||
|
link: cyan,
|
||||||
|
link_url: brown,
|
||||||
|
quote: fg_muted,
|
||||||
|
text: fg,
|
||||||
|
list: fg,
|
||||||
|
},
|
||||||
|
engine: EngineColors {
|
||||||
|
header: lightblue,
|
||||||
|
header_focused: cyan,
|
||||||
|
divider: Color::Rgb(28, 28, 28),
|
||||||
|
scroll_indicator: Color::Rgb(51, 51, 51),
|
||||||
|
label: fg_dim,
|
||||||
|
label_focused: fg,
|
||||||
|
label_dim: fg_muted,
|
||||||
|
value: fg,
|
||||||
|
focused: cyan,
|
||||||
|
normal: fg,
|
||||||
|
dim: Color::Rgb(36, 36, 36),
|
||||||
|
path: fg_dim,
|
||||||
|
border_magenta: violet,
|
||||||
|
border_green: green,
|
||||||
|
border_cyan: cyan,
|
||||||
|
separator: Color::Rgb(28, 28, 28),
|
||||||
|
hint_active: lightblue,
|
||||||
|
hint_inactive: Color::Rgb(28, 28, 28),
|
||||||
|
},
|
||||||
|
dict: DictColors {
|
||||||
|
word_name: lightgreen,
|
||||||
|
word_bg: Color::Rgb(10, 18, 6),
|
||||||
|
alias: fg_muted,
|
||||||
|
stack_sig: violet,
|
||||||
|
description: fg,
|
||||||
|
example: fg_dim,
|
||||||
|
category_focused: cyan,
|
||||||
|
category_selected: lightblue,
|
||||||
|
category_normal: fg,
|
||||||
|
category_dimmed: Color::Rgb(36, 36, 36),
|
||||||
|
border_focused: cyan,
|
||||||
|
border_normal: Color::Rgb(28, 28, 28),
|
||||||
|
header_desc: fg_dim,
|
||||||
|
},
|
||||||
|
title: TitleColors {
|
||||||
|
big_title: lightblue,
|
||||||
|
author: green,
|
||||||
|
link: cyan,
|
||||||
|
license: yellow,
|
||||||
|
prompt: fg_dim,
|
||||||
|
subtitle: fg,
|
||||||
|
},
|
||||||
|
meter: MeterColors {
|
||||||
|
low: green,
|
||||||
|
mid: yellow,
|
||||||
|
high: lightred,
|
||||||
|
low_rgb: (0, 204, 85),
|
||||||
|
mid_rgb: (238, 238, 119),
|
||||||
|
high_rgb: (255, 119, 119),
|
||||||
|
},
|
||||||
|
sparkle: SparkleColors {
|
||||||
|
colors: [
|
||||||
|
(0, 136, 255),
|
||||||
|
(170, 255, 238),
|
||||||
|
(0, 204, 85),
|
||||||
|
(238, 238, 119),
|
||||||
|
(204, 68, 204),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
confirm: ConfirmColors {
|
||||||
|
border: lightred,
|
||||||
|
button_selected_bg: lightblue,
|
||||||
|
button_selected_fg: bg,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
281
crates/ratatui/src/theme/letz_light.rs
Normal file
281
crates/ratatui/src/theme/letz_light.rs
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
use super::*;
|
||||||
|
use ratatui::style::Color;
|
||||||
|
|
||||||
|
pub fn theme() -> ThemeColors {
|
||||||
|
let bg = Color::Rgb(255, 255, 255);
|
||||||
|
let off_white = Color::Rgb(245, 245, 247);
|
||||||
|
let surface = Color::Rgb(235, 235, 240);
|
||||||
|
let border = Color::Rgb(210, 210, 215);
|
||||||
|
let text = Color::Rgb(29, 29, 31);
|
||||||
|
let text_dim = Color::Rgb(110, 110, 115);
|
||||||
|
let text_muted = Color::Rgb(160, 160, 165);
|
||||||
|
|
||||||
|
let keyword = Color::Rgb(173, 61, 164);
|
||||||
|
let string = Color::Rgb(209, 47, 27);
|
||||||
|
let comment = Color::Rgb(112, 127, 52);
|
||||||
|
let number = Color::Rgb(39, 42, 216);
|
||||||
|
let types = Color::Rgb(112, 61, 170);
|
||||||
|
let function = Color::Rgb(62, 128, 135);
|
||||||
|
let preproc = Color::Rgb(120, 73, 42);
|
||||||
|
let accent = Color::Rgb(0, 112, 243);
|
||||||
|
|
||||||
|
ThemeColors {
|
||||||
|
ui: UiColors {
|
||||||
|
bg,
|
||||||
|
bg_rgb: (255, 255, 255),
|
||||||
|
text_primary: text,
|
||||||
|
text_muted: text_dim,
|
||||||
|
text_dim: text_muted,
|
||||||
|
border,
|
||||||
|
header: accent,
|
||||||
|
unfocused: text_muted,
|
||||||
|
accent,
|
||||||
|
surface,
|
||||||
|
},
|
||||||
|
status: StatusColors {
|
||||||
|
playing_bg: Color::Rgb(220, 240, 220),
|
||||||
|
playing_fg: comment,
|
||||||
|
stopped_bg: Color::Rgb(245, 220, 220),
|
||||||
|
stopped_fg: string,
|
||||||
|
fill_on: comment,
|
||||||
|
fill_off: text_muted,
|
||||||
|
fill_bg: surface,
|
||||||
|
},
|
||||||
|
selection: SelectionColors {
|
||||||
|
cursor_bg: accent,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selected_bg: Color::Rgb(200, 220, 250),
|
||||||
|
selected_fg: accent,
|
||||||
|
in_range_bg: Color::Rgb(220, 233, 250),
|
||||||
|
in_range_fg: text,
|
||||||
|
cursor: accent,
|
||||||
|
selected: Color::Rgb(200, 220, 250),
|
||||||
|
in_range: Color::Rgb(220, 233, 250),
|
||||||
|
},
|
||||||
|
tile: TileColors {
|
||||||
|
playing_active_bg: Color::Rgb(250, 225, 210),
|
||||||
|
playing_active_fg: preproc,
|
||||||
|
playing_inactive_bg: Color::Rgb(250, 240, 200),
|
||||||
|
playing_inactive_fg: Color::Rgb(180, 140, 20),
|
||||||
|
active_bg: Color::Rgb(210, 235, 240),
|
||||||
|
active_fg: function,
|
||||||
|
inactive_bg: surface,
|
||||||
|
inactive_fg: text_dim,
|
||||||
|
active_selected_bg: Color::Rgb(210, 215, 245),
|
||||||
|
active_in_range_bg: Color::Rgb(220, 230, 245),
|
||||||
|
link_bright: [
|
||||||
|
(173, 61, 164),
|
||||||
|
(0, 112, 243),
|
||||||
|
(120, 73, 42),
|
||||||
|
(62, 128, 135),
|
||||||
|
(112, 127, 52),
|
||||||
|
],
|
||||||
|
link_dim: [
|
||||||
|
(235, 215, 235),
|
||||||
|
(210, 225, 250),
|
||||||
|
(240, 225, 210),
|
||||||
|
(215, 235, 240),
|
||||||
|
(225, 235, 215),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
header: HeaderColors {
|
||||||
|
tempo_bg: Color::Rgb(225, 215, 240),
|
||||||
|
tempo_fg: types,
|
||||||
|
bank_bg: Color::Rgb(210, 230, 250),
|
||||||
|
bank_fg: accent,
|
||||||
|
pattern_bg: Color::Rgb(210, 235, 235),
|
||||||
|
pattern_fg: function,
|
||||||
|
stats_bg: surface,
|
||||||
|
stats_fg: text_dim,
|
||||||
|
},
|
||||||
|
modal: ModalColors {
|
||||||
|
border: accent,
|
||||||
|
border_accent: keyword,
|
||||||
|
border_warn: preproc,
|
||||||
|
border_dim: text_muted,
|
||||||
|
confirm: preproc,
|
||||||
|
rename: keyword,
|
||||||
|
input: accent,
|
||||||
|
editor: accent,
|
||||||
|
preview: text_muted,
|
||||||
|
},
|
||||||
|
flash: FlashColors {
|
||||||
|
error_bg: Color::Rgb(250, 215, 215),
|
||||||
|
error_fg: string,
|
||||||
|
success_bg: Color::Rgb(215, 240, 215),
|
||||||
|
success_fg: comment,
|
||||||
|
info_bg: surface,
|
||||||
|
info_fg: text,
|
||||||
|
},
|
||||||
|
list: ListColors {
|
||||||
|
playing_bg: Color::Rgb(215, 240, 220),
|
||||||
|
playing_fg: comment,
|
||||||
|
staged_play_bg: Color::Rgb(230, 215, 240),
|
||||||
|
staged_play_fg: keyword,
|
||||||
|
staged_stop_bg: Color::Rgb(245, 215, 220),
|
||||||
|
staged_stop_fg: string,
|
||||||
|
edit_bg: Color::Rgb(210, 235, 240),
|
||||||
|
edit_fg: function,
|
||||||
|
hover_bg: Color::Rgb(240, 240, 242),
|
||||||
|
hover_fg: text,
|
||||||
|
muted_bg: Color::Rgb(230, 230, 235),
|
||||||
|
muted_fg: text_muted,
|
||||||
|
soloed_bg: Color::Rgb(250, 240, 200),
|
||||||
|
soloed_fg: Color::Rgb(170, 130, 10),
|
||||||
|
},
|
||||||
|
link_status: LinkStatusColors {
|
||||||
|
disabled: string,
|
||||||
|
connected: comment,
|
||||||
|
listening: Color::Rgb(180, 140, 20),
|
||||||
|
},
|
||||||
|
syntax: SyntaxColors {
|
||||||
|
gap_bg: off_white,
|
||||||
|
executed_bg: Color::Rgb(230, 225, 245),
|
||||||
|
selected_bg: Color::Rgb(250, 240, 210),
|
||||||
|
emit: (text, Color::Rgb(250, 220, 215)),
|
||||||
|
number: (number, Color::Rgb(220, 220, 250)),
|
||||||
|
string: (string, Color::Rgb(250, 225, 220)),
|
||||||
|
comment: (Color::Rgb(130, 145, 75), off_white),
|
||||||
|
keyword: (keyword, Color::Rgb(240, 225, 240)),
|
||||||
|
stack_op: (accent, Color::Rgb(220, 235, 250)),
|
||||||
|
operator: (preproc, Color::Rgb(240, 230, 215)),
|
||||||
|
sound: (function, Color::Rgb(215, 240, 240)),
|
||||||
|
param: (types, Color::Rgb(230, 220, 240)),
|
||||||
|
context: (preproc, Color::Rgb(240, 230, 215)),
|
||||||
|
note: (comment, Color::Rgb(225, 240, 220)),
|
||||||
|
interval: (Color::Rgb(90, 110, 40), Color::Rgb(225, 240, 215)),
|
||||||
|
variable: (keyword, Color::Rgb(240, 225, 240)),
|
||||||
|
vary: (Color::Rgb(180, 140, 20), Color::Rgb(250, 240, 210)),
|
||||||
|
generator: (function, Color::Rgb(215, 240, 235)),
|
||||||
|
default: (text_dim, off_white),
|
||||||
|
},
|
||||||
|
table: TableColors {
|
||||||
|
row_even: off_white,
|
||||||
|
row_odd: bg,
|
||||||
|
},
|
||||||
|
values: ValuesColors {
|
||||||
|
tempo: preproc,
|
||||||
|
value: text_dim,
|
||||||
|
},
|
||||||
|
hint: HintColors {
|
||||||
|
key: accent,
|
||||||
|
text: text_muted,
|
||||||
|
},
|
||||||
|
view_badge: ViewBadgeColors { bg: text, fg: bg },
|
||||||
|
nav: NavColors {
|
||||||
|
selected_bg: Color::Rgb(210, 225, 250),
|
||||||
|
selected_fg: text,
|
||||||
|
unselected_bg: surface,
|
||||||
|
unselected_fg: text_muted,
|
||||||
|
},
|
||||||
|
editor_widget: EditorWidgetColors {
|
||||||
|
cursor_bg: text,
|
||||||
|
cursor_fg: bg,
|
||||||
|
selection_bg: Color::Rgb(200, 220, 250),
|
||||||
|
completion_bg: surface,
|
||||||
|
completion_fg: text,
|
||||||
|
completion_selected: accent,
|
||||||
|
completion_example: function,
|
||||||
|
},
|
||||||
|
browser: BrowserColors {
|
||||||
|
directory: accent,
|
||||||
|
project_file: keyword,
|
||||||
|
selected: preproc,
|
||||||
|
file: text,
|
||||||
|
focused_border: accent,
|
||||||
|
unfocused_border: text_muted,
|
||||||
|
root: text,
|
||||||
|
file_icon: text_muted,
|
||||||
|
folder_icon: accent,
|
||||||
|
empty_text: text_muted,
|
||||||
|
},
|
||||||
|
input: InputColors {
|
||||||
|
text: accent,
|
||||||
|
cursor: text,
|
||||||
|
hint: text_muted,
|
||||||
|
},
|
||||||
|
search: SearchColors {
|
||||||
|
active: accent,
|
||||||
|
inactive: text_muted,
|
||||||
|
match_bg: Color::Rgb(255, 230, 80),
|
||||||
|
match_fg: text,
|
||||||
|
},
|
||||||
|
markdown: MarkdownColors {
|
||||||
|
h1: accent,
|
||||||
|
h2: preproc,
|
||||||
|
h3: keyword,
|
||||||
|
code: comment,
|
||||||
|
code_border: Color::Rgb(200, 200, 205),
|
||||||
|
link: function,
|
||||||
|
link_url: Color::Rgb(150, 150, 155),
|
||||||
|
quote: text_muted,
|
||||||
|
text,
|
||||||
|
list: text,
|
||||||
|
},
|
||||||
|
engine: EngineColors {
|
||||||
|
header: accent,
|
||||||
|
header_focused: preproc,
|
||||||
|
divider: Color::Rgb(200, 200, 205),
|
||||||
|
scroll_indicator: Color::Rgb(180, 180, 185),
|
||||||
|
label: Color::Rgb(120, 120, 125),
|
||||||
|
label_focused: Color::Rgb(80, 80, 85),
|
||||||
|
label_dim: Color::Rgb(150, 150, 155),
|
||||||
|
value: Color::Rgb(60, 60, 65),
|
||||||
|
focused: preproc,
|
||||||
|
normal: text,
|
||||||
|
dim: Color::Rgb(180, 180, 185),
|
||||||
|
path: Color::Rgb(120, 120, 125),
|
||||||
|
border_magenta: keyword,
|
||||||
|
border_green: comment,
|
||||||
|
border_cyan: function,
|
||||||
|
separator: Color::Rgb(200, 200, 210),
|
||||||
|
hint_active: preproc,
|
||||||
|
hint_inactive: Color::Rgb(200, 200, 210),
|
||||||
|
},
|
||||||
|
dict: DictColors {
|
||||||
|
word_name: function,
|
||||||
|
word_bg: Color::Rgb(215, 235, 240),
|
||||||
|
alias: text_muted,
|
||||||
|
stack_sig: keyword,
|
||||||
|
description: text,
|
||||||
|
example: Color::Rgb(110, 110, 120),
|
||||||
|
category_focused: preproc,
|
||||||
|
category_selected: accent,
|
||||||
|
category_normal: text,
|
||||||
|
category_dimmed: Color::Rgb(180, 180, 185),
|
||||||
|
border_focused: preproc,
|
||||||
|
border_normal: Color::Rgb(200, 200, 205),
|
||||||
|
header_desc: Color::Rgb(100, 100, 110),
|
||||||
|
},
|
||||||
|
title: TitleColors {
|
||||||
|
big_title: accent,
|
||||||
|
author: types,
|
||||||
|
link: function,
|
||||||
|
license: preproc,
|
||||||
|
prompt: Color::Rgb(100, 100, 110),
|
||||||
|
subtitle: text,
|
||||||
|
},
|
||||||
|
meter: MeterColors {
|
||||||
|
low: comment,
|
||||||
|
mid: Color::Rgb(200, 150, 20),
|
||||||
|
high: string,
|
||||||
|
low_rgb: (112, 127, 52),
|
||||||
|
mid_rgb: (200, 150, 20),
|
||||||
|
high_rgb: (209, 47, 27),
|
||||||
|
},
|
||||||
|
sparkle: SparkleColors {
|
||||||
|
colors: [
|
||||||
|
(0, 112, 243),
|
||||||
|
(173, 61, 164),
|
||||||
|
(112, 127, 52),
|
||||||
|
(62, 128, 135),
|
||||||
|
(120, 73, 42),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
confirm: ConfirmColors {
|
||||||
|
border: accent,
|
||||||
|
button_selected_bg: accent,
|
||||||
|
button_selected_fg: bg,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,10 +4,14 @@
|
|||||||
mod catppuccin_latte;
|
mod catppuccin_latte;
|
||||||
mod catppuccin_mocha;
|
mod catppuccin_mocha;
|
||||||
mod dracula;
|
mod dracula;
|
||||||
|
mod eden;
|
||||||
|
mod ember;
|
||||||
|
mod georges;
|
||||||
mod fairyfloss;
|
mod fairyfloss;
|
||||||
mod gruvbox_dark;
|
mod gruvbox_dark;
|
||||||
mod hot_dog_stand;
|
mod hot_dog_stand;
|
||||||
mod kanagawa;
|
mod kanagawa;
|
||||||
|
mod letz_light;
|
||||||
mod monochrome_black;
|
mod monochrome_black;
|
||||||
mod monochrome_white;
|
mod monochrome_white;
|
||||||
mod monokai;
|
mod monokai;
|
||||||
@@ -41,6 +45,10 @@ pub const THEMES: &[ThemeEntry] = &[
|
|||||||
ThemeEntry { id: "Kanagawa", label: "Kanagawa", colors: kanagawa::theme },
|
ThemeEntry { id: "Kanagawa", label: "Kanagawa", colors: kanagawa::theme },
|
||||||
ThemeEntry { id: "Fairyfloss", label: "Fairyfloss", colors: fairyfloss::theme },
|
ThemeEntry { id: "Fairyfloss", label: "Fairyfloss", colors: fairyfloss::theme },
|
||||||
ThemeEntry { id: "HotDogStand", label: "Hot Dog Stand", colors: hot_dog_stand::theme },
|
ThemeEntry { id: "HotDogStand", label: "Hot Dog Stand", colors: hot_dog_stand::theme },
|
||||||
|
ThemeEntry { id: "LetzLight", label: "Letz Light", colors: letz_light::theme },
|
||||||
|
ThemeEntry { id: "Ember", label: "Ember", colors: ember::theme },
|
||||||
|
ThemeEntry { id: "Eden", label: "Eden", colors: eden::theme },
|
||||||
|
ThemeEntry { id: "Georges", label: "Georges", colors: georges::theme },
|
||||||
];
|
];
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
|||||||
38
src/app.rs
38
src/app.rs
@@ -4,7 +4,9 @@ use rand::rngs::StdRng;
|
|||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, LazyLock};
|
||||||
|
|
||||||
|
use cagire_ratatui::CompletionCandidate;
|
||||||
|
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
|
|
||||||
@@ -25,6 +27,18 @@ use crate::state::{
|
|||||||
|
|
||||||
const STEPS_PER_PAGE: usize = 32;
|
const STEPS_PER_PAGE: usize = 32;
|
||||||
|
|
||||||
|
static COMPLETION_CANDIDATES: LazyLock<Vec<CompletionCandidate>> = LazyLock::new(|| {
|
||||||
|
model::WORDS
|
||||||
|
.iter()
|
||||||
|
.map(|w| CompletionCandidate {
|
||||||
|
name: w.name.to_string(),
|
||||||
|
signature: w.stack.to_string(),
|
||||||
|
description: w.desc.to_string(),
|
||||||
|
example: w.example.to_string(),
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
pub project_state: ProjectState,
|
pub project_state: ProjectState,
|
||||||
pub ui: UiState,
|
pub ui: UiState,
|
||||||
@@ -310,16 +324,7 @@ impl App {
|
|||||||
script.lines().map(String::from).collect()
|
script.lines().map(String::from).collect()
|
||||||
};
|
};
|
||||||
self.editor_ctx.editor.set_content(lines);
|
self.editor_ctx.editor.set_content(lines);
|
||||||
let candidates = model::WORDS
|
self.editor_ctx.editor.set_candidates(COMPLETION_CANDIDATES.clone());
|
||||||
.iter()
|
|
||||||
.map(|w| cagire_ratatui::CompletionCandidate {
|
|
||||||
name: w.name.to_string(),
|
|
||||||
signature: w.stack.to_string(),
|
|
||||||
description: w.desc.to_string(),
|
|
||||||
example: w.example.to_string(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
self.editor_ctx.editor.set_candidates(candidates);
|
|
||||||
self.editor_ctx
|
self.editor_ctx
|
||||||
.editor
|
.editor
|
||||||
.set_completion_enabled(self.ui.show_completion);
|
.set_completion_enabled(self.ui.show_completion);
|
||||||
@@ -350,16 +355,7 @@ impl App {
|
|||||||
prelude.lines().map(String::from).collect()
|
prelude.lines().map(String::from).collect()
|
||||||
};
|
};
|
||||||
self.editor_ctx.editor.set_content(lines);
|
self.editor_ctx.editor.set_content(lines);
|
||||||
let candidates = model::WORDS
|
self.editor_ctx.editor.set_candidates(COMPLETION_CANDIDATES.clone());
|
||||||
.iter()
|
|
||||||
.map(|w| cagire_ratatui::CompletionCandidate {
|
|
||||||
name: w.name.to_string(),
|
|
||||||
signature: w.stack.to_string(),
|
|
||||||
description: w.desc.to_string(),
|
|
||||||
example: w.example.to_string(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
self.editor_ctx.editor.set_candidates(candidates);
|
|
||||||
self.editor_ctx
|
self.editor_ctx
|
||||||
.editor
|
.editor
|
||||||
.set_completion_enabled(self.ui.show_completion);
|
.set_completion_enabled(self.ui.show_completion);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ pub struct ProjectState {
|
|||||||
pub project: Project,
|
pub project: Project,
|
||||||
pub file_path: Option<PathBuf>,
|
pub file_path: Option<PathBuf>,
|
||||||
dirty_patterns: [[bool; MAX_PATTERNS]; MAX_BANKS],
|
dirty_patterns: [[bool; MAX_PATTERNS]; MAX_BANKS],
|
||||||
|
dirty_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ProjectState {
|
impl Default for ProjectState {
|
||||||
@@ -15,6 +16,7 @@ impl Default for ProjectState {
|
|||||||
project: Project::default(),
|
project: Project::default(),
|
||||||
file_path: None,
|
file_path: None,
|
||||||
dirty_patterns: [[false; MAX_PATTERNS]; MAX_BANKS],
|
dirty_patterns: [[false; MAX_PATTERNS]; MAX_BANKS],
|
||||||
|
dirty_count: 0,
|
||||||
};
|
};
|
||||||
state.mark_all_dirty();
|
state.mark_all_dirty();
|
||||||
state
|
state
|
||||||
@@ -23,15 +25,22 @@ impl Default for ProjectState {
|
|||||||
|
|
||||||
impl ProjectState {
|
impl ProjectState {
|
||||||
pub fn mark_dirty(&mut self, bank: usize, pattern: usize) {
|
pub fn mark_dirty(&mut self, bank: usize, pattern: usize) {
|
||||||
self.dirty_patterns[bank][pattern] = true;
|
if !self.dirty_patterns[bank][pattern] {
|
||||||
|
self.dirty_patterns[bank][pattern] = true;
|
||||||
|
self.dirty_count += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_all_dirty(&mut self) {
|
pub fn mark_all_dirty(&mut self) {
|
||||||
self.dirty_patterns = [[true; MAX_PATTERNS]; MAX_BANKS];
|
self.dirty_patterns = [[true; MAX_PATTERNS]; MAX_BANKS];
|
||||||
|
self.dirty_count = MAX_BANKS * MAX_PATTERNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_dirty(&mut self) -> Vec<(usize, usize)> {
|
pub fn take_dirty(&mut self) -> Vec<(usize, usize)> {
|
||||||
let mut result = Vec::new();
|
if self.dirty_count == 0 {
|
||||||
|
return Vec::new();
|
||||||
|
}
|
||||||
|
let mut result = Vec::with_capacity(self.dirty_count);
|
||||||
for (bank, patterns) in self.dirty_patterns.iter_mut().enumerate() {
|
for (bank, patterns) in self.dirty_patterns.iter_mut().enumerate() {
|
||||||
for (pattern, dirty) in patterns.iter_mut().enumerate() {
|
for (pattern, dirty) in patterns.iter_mut().enumerate() {
|
||||||
if *dirty {
|
if *dirty {
|
||||||
@@ -40,6 +49,7 @@ impl ProjectState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.dirty_count = 0;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::time::{Duration, Instant};
|
|||||||
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::{Line, Span};
|
use ratatui::text::{Line, Span};
|
||||||
use ratatui::widgets::{Block, Borders, Cell, Padding, Paragraph, Row, Table};
|
use ratatui::widgets::{Block, Borders, Cell, Clear, Padding, Paragraph, Row, Table};
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
@@ -50,12 +50,8 @@ pub fn render(frame: &mut Frame, app: &App, link: &LinkState, snapshot: &Sequenc
|
|||||||
let theme = theme::get();
|
let theme = theme::get();
|
||||||
let bg_color = theme.ui.bg;
|
let bg_color = theme.ui.bg;
|
||||||
|
|
||||||
let blank = " ".repeat(term.width as usize);
|
frame.render_widget(Clear, term);
|
||||||
let lines: Vec<Line> = (0..term.height).map(|_| Line::raw(&blank)).collect();
|
frame.render_widget(Block::new().style(Style::default().bg(bg_color)), term);
|
||||||
frame.render_widget(
|
|
||||||
Paragraph::new(lines).style(Style::default().bg(bg_color)),
|
|
||||||
term,
|
|
||||||
);
|
|
||||||
|
|
||||||
if app.ui.show_title {
|
if app.ui.show_title {
|
||||||
title_view::render(frame, term, &app.ui);
|
title_view::render(frame, term, &app.ui);
|
||||||
|
|||||||
Reference in New Issue
Block a user