From bfd1caf9dbcdd48a340884e8cb9917584828876b Mon Sep 17 00:00:00 2001 From: merces Date: Thu, 15 Oct 2026 01:38:10 -0300 Subject: [PATCH 01/10] feat: add colorscheme command --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/commands.rs | 34 ++++++++++++ src/global/status_bar.rs | 4 +- src/themes.rs | 108 +++++++++++++++++++++++++++++++++++++-- 5 files changed, 143 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89145c7..700757a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,7 +525,7 @@ dependencies = [ [[package]] name = "dz6" -version = "0.8.1" +version = "0.9.0" dependencies = [ "arboard", "chrono", diff --git a/Cargo.toml b/Cargo.toml index da70aa7..5cc4a88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dz6" -version = "0.8.1" +version = "0.9.0" edition = "2024" description = "Fast Vim-inspired hex editor for the terminal" readme = "README.md" diff --git a/src/commands.rs b/src/commands.rs index 860b7d3..58b1a31 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -40,6 +40,9 @@ enum Command { length: String, }, Version, + Colorscheme { + scheme: String, + }, } #[derive(Parser, Debug)] @@ -372,6 +375,37 @@ pub fn parse_command(app: &mut App, cmdline: &str) { app.dialog_renderer = Some(dialog_version_draw); app.state = UIState::DialogVersion; } + Some(Command::Colorscheme { scheme }) => { + match scheme.as_str() { + "dark" => { + app.config.theme = crate::themes::DARK; + app.dialog_renderer = None; + } + "light" => { + app.config.theme = crate::themes::LIGHT; + app.dialog_renderer = None; + } + "default-light" => { + app.config.theme = crate::themes::DEFAULT_LIGHT; + app.dialog_renderer = None; + } + "default-dark" => { + app.config.theme = crate::themes::DEFAULT_DARK; + app.dialog_renderer = None; + } + "blue" => { + app.config.theme = crate::themes::BLUE; + app.dialog_renderer = None; + } + _ => { + app.last_error = Dz6Error { + message: format!("Invalid theme: {}", scheme), + }; + app.dialog_renderer = Some(command_error_draw); + } + } + app.state = UIState::Normal; + } None => { try_goto(app, cmdline); } diff --git a/src/global/status_bar.rs b/src/global/status_bar.rs index e2601a5..b9da92e 100644 --- a/src/global/status_bar.rs +++ b/src/global/status_bar.rs @@ -52,7 +52,7 @@ pub fn status_bar_draw(app: &mut App, frame: &mut Frame, area: Rect) { }; let status_bar_info_left = Paragraph::new(format!("{} {}", filename, read_only)) - .style(app.config.theme.topbar) + .style(app.config.theme.status_bar) .alignment(Alignment::Left); frame.render_widget(status_bar_info_left, area); @@ -72,7 +72,7 @@ pub fn status_bar_draw(app: &mut App, frame: &mut Frame, area: Rect) { "{} {} {} {} {:08X} {:3}%", mode, bookmarks_string, app.file_info.r#type, selected, app.hex_view.offset, percent )) - .style(app.config.theme.topbar) + .style(app.config.theme.status_bar) .alignment(Alignment::Right); frame.render_widget(status_bar_info_right, area); } diff --git a/src/themes.rs b/src/themes.rs index 812e236..6224645 100644 --- a/src/themes.rs +++ b/src/themes.rs @@ -7,7 +7,7 @@ pub struct Theme { pub changed_bytes: Style, pub highlight: Style, pub byte_highlight: Style, - pub topbar: Style, + pub status_bar: Style, pub error: Style, pub editing: Style, pub dialog: Style, @@ -37,7 +37,7 @@ pub const DARK: Theme = Theme { .fg(Color::Rgb(255, 255, 255)) .bg(Color::Rgb(38, 79, 120)), byte_highlight: Style::new().fg(Color::White).bg(Color::Red), - topbar: Style::new() + status_bar: Style::new() .fg(Color::Rgb(204, 204, 204)) .bg(Color::from_u32(0x3c3c3c)), error: Style::new() @@ -80,7 +80,7 @@ pub const LIGHT: Theme = Theme { byte_highlight: Style::new().fg(Color::Black).bg(Color::from_u32(0xffb3b3)), - topbar: Style::new() + status_bar: Style::new() .fg(Color::from_u32(0x333333)) .bg(Color::from_u32(0xf3f3f3)), @@ -93,3 +93,105 @@ pub const LIGHT: Theme = Theme { .bg(Color::from_u32(0xffcc00)) .add_modifier(Modifier::RAPID_BLINK), }; + +pub const DEFAULT_LIGHT: Theme = Theme { + offsets: Style::new() + .fg(Color::Indexed(130)) + .bg(Color::Black), + main: Style::new() + .fg(Color::White) + .bg(Color::Black), + dimmed: Style::new() + .fg(Color::DarkGray) + .bg(Color::Black), + dialog: Style::new() + .fg(Color::Rgb(204, 204, 204)), + // .bg(Color::from_u32(0x081e32)), + changed_bytes: Style::new() + .fg(Color::Yellow) + .bg(Color::Black), + highlight: Style::new() + .fg(Color::Black) + .bg(Color::White), + byte_highlight: Style::new() + .fg(Color::White) + .bg(Color::LightYellow), + status_bar: Style::new() + .fg(Color::White) + .bg(Color::Black), + error: Style::new() + .fg(Color::White) + .bg(Color::Red), + editing: Style::new() + .fg(Color::from_u32(0x1e1e1e)) + .bg(Color::Rgb(255, 215, 0)) + .add_modifier(Modifier::RAPID_BLINK), +}; + +pub const DEFAULT_DARK: Theme = Theme { + offsets: Style::new() + .fg(Color::LightYellow) + .bg(Color::Black), + main: Style::new() + .fg(Color::White) + .bg(Color::Black), + dimmed: Style::new() + .fg(Color::DarkGray) + .bg(Color::Black), + dialog: Style::new() + .fg(Color::Rgb(204, 204, 204)), + // .bg(Color::from_u32(0x081e32)), + changed_bytes: Style::new() + .fg(Color::Yellow) + .bg(Color::Black), + highlight: Style::new() + .fg(Color::Black) + .bg(Color::White), + byte_highlight: Style::new() + .fg(Color::White) + .bg(Color::LightYellow), + status_bar: Style::new() + .fg(Color::White) + .bg(Color::Black), + error: Style::new() + .fg(Color::White) + .bg(Color::Red), + editing: Style::new() + .fg(Color::from_u32(0x1e1e1e)) + .bg(Color::Rgb(255, 215, 0)) + .add_modifier(Modifier::RAPID_BLINK), +}; + +pub const BLUE: Theme = Theme { + offsets: Style::new() + .fg(Color::from_u32(0x5dffff)) + .bg(Color::from_u32(0x001686)), + main: Style::new() + .fg(Color::from_u32(0xffd404)) + .bg(Color::from_u32(0x001686)), + dimmed: Style::new() + .fg(Color::DarkGray) + .bg(Color::from_u32(0x001686)), + dialog: Style::new() + .fg(Color::Rgb(204, 204, 204)), + // .bg(Color::from_u32(0x081e32)), + changed_bytes: Style::new() + .fg(Color::Yellow) + .bg(Color::from_u32(0x001686)), + highlight: Style::new() + .fg(Color::Black) + .bg(Color::White), + byte_highlight: Style::new() + .fg(Color::from_u32(0x000000)) + .bg(Color::from_u32(0xffd404)), + status_bar: Style::new() + .fg(Color::from_u32(0xffd404)) + .bg(Color::from_u32(0x001686)), + error: Style::new() + .fg(Color::White) + .bg(Color::Red), + editing: Style::new() + .fg(Color::from_u32(0x1e1e1e)) + .bg(Color::Rgb(255, 215, 0)) + .add_modifier(Modifier::RAPID_BLINK), +}; \ No newline at end of file From ff5dded8ac4c13ccbe4971f416eea722f4fd2d5c Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 08:40:45 -0300 Subject: [PATCH 02/10] fix: colors --- src/commands.rs | 8 +- src/draw.rs | 6 ++ src/global/status_bar.rs | 4 + src/themes.rs | 163 +++++++++++++++++---------------------- 4 files changed, 86 insertions(+), 95 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 58b1a31..352f750 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -393,8 +393,8 @@ pub fn parse_command(app: &mut App, cmdline: &str) { app.config.theme = crate::themes::DEFAULT_DARK; app.dialog_renderer = None; } - "blue" => { - app.config.theme = crate::themes::BLUE; + "darkblue" => { + app.config.theme = crate::themes::DARKBLUE; app.dialog_renderer = None; } _ => { @@ -418,9 +418,9 @@ pub fn parse_command(app: &mut App, cmdline: &str) { } // command bar - pub fn command_draw(app: &mut App, frame: &mut Frame) { - let para = Paragraph::new(format!(":{}", app.command_input.input.value())); + let command = app.command_input.input.value(); + let para = Paragraph::new(format!(":{}", command)).style(app.config.theme.main); frame.render_widget(Clear, app.command_area); frame.render_widget(para, app.command_area); diff --git a/src/draw.rs b/src/draw.rs index 035159f..675731b 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -41,6 +41,8 @@ pub fn draw(frame: &mut Frame, app: &mut App) { // Draw status bar at the bottom global::status_bar::status_bar_draw(app, frame, vertical_layout[2]); + // Draw the command bar at the bottom + global::status_bar::command_bar_draw(app, frame, vertical_layout[3]); app.command_area = vertical_layout[3]; let horizontal_layout = Layout::default() @@ -72,6 +74,8 @@ pub fn draw(frame: &mut Frame, app: &mut App) { // Draw status bar at the bottom global::status_bar::status_bar_draw(app, frame, vertical_layout[1]); + // Draw the command bar at the bottom + global::status_bar::command_bar_draw(app, frame, vertical_layout[2]); app.command_area = vertical_layout[2]; let horizontal_layout = Layout::default() @@ -97,6 +101,8 @@ pub fn draw(frame: &mut Frame, app: &mut App) { // Draw status bar at the bottom global::status_bar::status_bar_draw(app, frame, vertical_layout[1]); + // Draw the command bar at the bottom + global::status_bar::command_bar_draw(app, frame, vertical_layout[2]); app.command_area = vertical_layout[2]; let horizontal_layout = Layout::default() diff --git a/src/global/status_bar.rs b/src/global/status_bar.rs index b9da92e..a4b6fd1 100644 --- a/src/global/status_bar.rs +++ b/src/global/status_bar.rs @@ -76,3 +76,7 @@ pub fn status_bar_draw(app: &mut App, frame: &mut Frame, area: Rect) { .alignment(Alignment::Right); frame.render_widget(status_bar_info_right, area); } + +pub fn command_bar_draw(app: &mut App, frame: &mut Frame, area: Rect) { + frame.render_widget(Paragraph::default().style(app.config.theme.main), area); +} diff --git a/src/themes.rs b/src/themes.rs index 6224645..ec0653a 100644 --- a/src/themes.rs +++ b/src/themes.rs @@ -13,6 +13,7 @@ pub struct Theme { pub dialog: Style, } +// "old" themes left for compatiblity pub const DARK: Theme = Theme { offsets: Style::new() .fg(Color::from_u32(0x569cd6)) @@ -94,104 +95,84 @@ pub const LIGHT: Theme = Theme { .add_modifier(Modifier::RAPID_BLINK), }; -pub const DEFAULT_LIGHT: Theme = Theme { - offsets: Style::new() - .fg(Color::Indexed(130)) - .bg(Color::Black), - main: Style::new() - .fg(Color::White) - .bg(Color::Black), - dimmed: Style::new() - .fg(Color::DarkGray) - .bg(Color::Black), - dialog: Style::new() - .fg(Color::Rgb(204, 204, 204)), - // .bg(Color::from_u32(0x081e32)), - changed_bytes: Style::new() - .fg(Color::Yellow) - .bg(Color::Black), - highlight: Style::new() - .fg(Color::Black) - .bg(Color::White), - byte_highlight: Style::new() - .fg(Color::White) - .bg(Color::LightYellow), - status_bar: Style::new() - .fg(Color::White) - .bg(Color::Black), - error: Style::new() - .fg(Color::White) - .bg(Color::Red), +// Vim themes +// to see these colors in Vim, use for example :hi LineNr +// they depend on the terminal config, which is good and bad :) +// Color::Reset means the terminal default for background or foreground +pub const DEFAULT_DARK: Theme = Theme { + // LineNr + offsets: Style::new().fg(Color::Indexed(11)).bg(Color::Reset), + // Normal + main: Style::new().fg(Color::Reset).bg(Color::Reset), + // set to DarkGray because Vim's Comment is too bright + dimmed: Style::new().fg(Color::DarkGray).bg(Color::Reset), + // Normal + dialog: Style::new().fg(Color::Indexed(11)).bg(Color::Reset), + // Constant + changed_bytes: Style::new().fg(Color::Indexed(13)).bg(Color::Reset), + // CursorColumn + highlight: Style::new().fg(Color::Reset).bg(Color::Indexed(242)), + // Search + byte_highlight: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(11)), + // Normal + status_bar: Style::new().fg(Color::Reset).bg(Color::Reset), + // ErrorMsg + error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), + // DiffChange editing: Style::new() - .fg(Color::from_u32(0x1e1e1e)) - .bg(Color::Rgb(255, 215, 0)) + .fg(Color::Reset) + .bg(Color::Indexed(5)) .add_modifier(Modifier::RAPID_BLINK), }; -pub const DEFAULT_DARK: Theme = Theme { - offsets: Style::new() - .fg(Color::LightYellow) - .bg(Color::Black), - main: Style::new() - .fg(Color::White) - .bg(Color::Black), - dimmed: Style::new() - .fg(Color::DarkGray) - .bg(Color::Black), - dialog: Style::new() - .fg(Color::Rgb(204, 204, 204)), - // .bg(Color::from_u32(0x081e32)), - changed_bytes: Style::new() - .fg(Color::Yellow) - .bg(Color::Black), - highlight: Style::new() - .fg(Color::Black) - .bg(Color::White), - byte_highlight: Style::new() - .fg(Color::White) - .bg(Color::LightYellow), - status_bar: Style::new() - .fg(Color::White) - .bg(Color::Black), - error: Style::new() - .fg(Color::White) - .bg(Color::Red), +pub const DEFAULT_LIGHT: Theme = Theme { + // LineNr = Brown + offsets: Style::new().fg(Color::Indexed(130)).bg(Color::Reset), + // Normal + main: Style::new().fg(Color::Reset).bg(Color::Reset), + // set to DarkGray because Vim's Comment is too bright + dimmed: Style::new().fg(Color::DarkGray).bg(Color::Reset), + // Normal + dialog: Style::new().fg(Color::Indexed(130)).bg(Color::Reset), + // Constant = Magenta + changed_bytes: Style::new().fg(Color::Magenta).bg(Color::Reset), + // CursorColumn + highlight: Style::new().fg(Color::Reset).bg(Color::Indexed(7)), + // Search + byte_highlight: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(11)), + // Normal + status_bar: Style::new().fg(Color::Reset).bg(Color::Reset), + // ErrorMsg + error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), + // DiffChange editing: Style::new() - .fg(Color::from_u32(0x1e1e1e)) - .bg(Color::Rgb(255, 215, 0)) + .fg(Color::Reset) + .bg(Color::LightMagenta) .add_modifier(Modifier::RAPID_BLINK), }; -pub const BLUE: Theme = Theme { - offsets: Style::new() - .fg(Color::from_u32(0x5dffff)) - .bg(Color::from_u32(0x001686)), - main: Style::new() - .fg(Color::from_u32(0xffd404)) - .bg(Color::from_u32(0x001686)), - dimmed: Style::new() - .fg(Color::DarkGray) - .bg(Color::from_u32(0x001686)), - dialog: Style::new() - .fg(Color::Rgb(204, 204, 204)), - // .bg(Color::from_u32(0x081e32)), - changed_bytes: Style::new() - .fg(Color::Yellow) - .bg(Color::from_u32(0x001686)), - highlight: Style::new() - .fg(Color::Black) - .bg(Color::White), - byte_highlight: Style::new() - .fg(Color::from_u32(0x000000)) - .bg(Color::from_u32(0xffd404)), - status_bar: Style::new() - .fg(Color::from_u32(0xffd404)) - .bg(Color::from_u32(0x001686)), - error: Style::new() - .fg(Color::White) - .bg(Color::Red), +pub const DARKBLUE: Theme = Theme { + // LineNr = Brown + offsets: Style::new().fg(Color::Indexed(118)).bg(Color::Indexed(17)), + // Normal + main: Style::new().fg(Color::Indexed(252)).bg(Color::Indexed(17)), + // set to DarkGray because Vim's Comment is too bright + dimmed: Style::new().fg(Color::Indexed(102)).bg(Color::Indexed(17)), + // Normal + dialog: Style::new().fg(Color::Indexed(118)).bg(Color::Indexed(17)), + // Constant + changed_bytes: Style::new().fg(Color::Indexed(217)).bg(Color::Indexed(17)), + // CursorColumn + highlight: Style::new().fg(Color::from_u32(0xffffff)).bg(Color::from_u32(0x8489ff)), + // Search + byte_highlight: Style::new().fg(Color::Indexed(123)).bg(Color::Indexed(27)), + // Normal + status_bar: Style::new().fg(Color::Reset).bg(Color::Indexed(17)), + // ErrorMsg + error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), + // DiffChange editing: Style::new() - .fg(Color::from_u32(0x1e1e1e)) - .bg(Color::Rgb(255, 215, 0)) + .fg(Color::Reset) + .bg(Color::LightMagenta) .add_modifier(Modifier::RAPID_BLINK), -}; \ No newline at end of file +}; From 6cbe66fd8ecafa049239ae61a25c92ee7fbc5a5c Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 11:33:44 -0300 Subject: [PATCH 03/10] feat: add terminal_light crate --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 5cc4a88..049f31d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ ratatui = "0.30.0" regex = "1.11.2" serde = { version = "1.0.228", features = ["derive"] } shell-words = "1.1.0" +terminal-light = "1.9.1" toml = "1.0.1" tui-input = "0.15.0" From 713ee666b3fdcb3b16a35f6e7b8233a176b21a5a Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 11:42:05 -0300 Subject: [PATCH 04/10] feat: automatically choose colorscheme based on terminal colors --- src/app.rs | 2 +- src/main.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 8198a61..dadc4f5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -107,7 +107,7 @@ impl App { search_wrapscan: false, search_ignorecase: false, search_smartcase: false, - theme: DARK, + theme: DEFAULT_DARK, // hex_mode_dword_separator: '-', // text_mode_tab_spaces: 4, }, diff --git a/src/main.rs b/src/main.rs index fcf2872..ce8dc71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,8 @@ use ratatui::crossterm::event; use app::App; +use crate::themes::DEFAULT_LIGHT; + /// vim-like hexadecimal editor #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -53,6 +55,13 @@ fn main() { app.list_state.select_first(); + // choose Vim-inspired colorscheme based on terminal colors + // Vim uses https://github.com/vim/vim/blob/5a9a0518b153b8571ff4d55c5727b72341080cef/src/term.c#L6098 + // but we simplify by using the terminal_light crate + if terminal_light::luma().is_ok_and(|luma| luma > 0.6) { + app.config.theme = DEFAULT_LIGHT; + } + // read init file ignoring errors let _ = app.read_initfile(); From db4b244a7675f205a23165ffb900a06feea1280e Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 11:42:40 -0300 Subject: [PATCH 05/10] feat: separate selection colors --- src/hex/draw.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hex/draw.rs b/src/hex/draw.rs index 550a4b6..cd5eda6 100644 --- a/src/hex/draw.rs +++ b/src/hex/draw.rs @@ -66,7 +66,7 @@ pub fn draw_hex_contents(app: &mut App, frame: &mut Frame, area: Rect) { let mut byte_content = format!("{byte:02X}"); byte_style = if app.state == UIState::HexSelection && app.hex_view.selection.contains(offset) { - app.config.theme.highlight + app.config.theme.selection } else if (*byte == b'\0' && app.config.dim_zeroes) || (!byte.is_ascii_graphic() && app.config.dim_control_chars) { From 69d2183d15a8ea2856514a049398e3a35997afe0 Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 11:42:59 -0300 Subject: [PATCH 06/10] feat: improve colorschemes --- src/themes.rs | 77 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/src/themes.rs b/src/themes.rs index ec0653a..e015823 100644 --- a/src/themes.rs +++ b/src/themes.rs @@ -1,4 +1,4 @@ -use ratatui::style::{Color, Modifier, Style}; +use ratatui::style::{Color, Style}; pub struct Theme { pub main: Style, @@ -11,6 +11,7 @@ pub struct Theme { pub error: Style, pub editing: Style, pub dialog: Style, + pub selection: Style, } // "old" themes left for compatiblity @@ -18,25 +19,28 @@ pub const DARK: Theme = Theme { offsets: Style::new() .fg(Color::from_u32(0x569cd6)) .bg(Color::from_u32(0x1e1e1e)) - .add_modifier(Modifier::BOLD), + .bold(), main: Style::new() .fg(Color::from_u32(0xd4d4d4)) .bg(Color::from_u32(0x1e1e1e)) - .add_modifier(Modifier::BOLD), + .bold(), dimmed: Style::new() .fg(Color::from_u32(0x949494)) .bg(Color::from_u32(0x1e1e1e)) - .add_modifier(Modifier::BOLD), + .bold(), dialog: Style::new() .fg(Color::Rgb(204, 204, 204)) .bg(Color::from_u32(0x081e32)) - .add_modifier(Modifier::BOLD), + .bold(), changed_bytes: Style::new() .fg(Color::Rgb(255, 215, 0)) .bg(Color::from_u32(0x1e1e1e)), highlight: Style::new() .fg(Color::Rgb(255, 255, 255)) .bg(Color::Rgb(38, 79, 120)), + selection: Style::new() + .fg(Color::Rgb(255, 255, 255)) + .bg(Color::Rgb(38, 79, 120)), byte_highlight: Style::new().fg(Color::White).bg(Color::Red), status_bar: Style::new() .fg(Color::Rgb(204, 204, 204)) @@ -47,58 +51,53 @@ pub const DARK: Theme = Theme { editing: Style::new() .fg(Color::from_u32(0x1e1e1e)) .bg(Color::Rgb(255, 215, 0)) - .add_modifier(Modifier::RAPID_BLINK), + .rapid_blink(), }; pub const LIGHT: Theme = Theme { offsets: Style::new() .fg(Color::from_u32(0x237893)) .bg(Color::from_u32(0xffffff)) - .add_modifier(Modifier::BOLD), - + .bold(), main: Style::new() .fg(Color::from_u32(0x000000)) .bg(Color::from_u32(0xffffff)) - .add_modifier(Modifier::BOLD), - + .bold(), dimmed: Style::new() .fg(Color::from_u32(0xa0a0a0)) .bg(Color::from_u32(0xffffff)) - .add_modifier(Modifier::BOLD), - + .bold(), dialog: Style::new() .fg(Color::from_u32(0x333333)) .bg(Color::from_u32(0xe7f3ff)) - .add_modifier(Modifier::BOLD), - + .bold(), changed_bytes: Style::new() .fg(Color::from_u32(0x795e00)) .bg(Color::from_u32(0xffffff)), - highlight: Style::new() .fg(Color::from_u32(0x000000)) .bg(Color::from_u32(0xadd6ff)), - + selection: Style::new() + .fg(Color::from_u32(0x000000)) + .bg(Color::from_u32(0xadd6ff)), byte_highlight: Style::new().fg(Color::Black).bg(Color::from_u32(0xffb3b3)), - status_bar: Style::new() .fg(Color::from_u32(0x333333)) .bg(Color::from_u32(0xf3f3f3)), - error: Style::new() .fg(Color::from_u32(0xe51400)) .bg(Color::from_u32(0xf2dede)), - editing: Style::new() .fg(Color::from_u32(0xffffff)) .bg(Color::from_u32(0xffcc00)) - .add_modifier(Modifier::RAPID_BLINK), + .rapid_blink(), }; // Vim themes // to see these colors in Vim, use for example :hi LineNr // they depend on the terminal config, which is good and bad :) // Color::Reset means the terminal default for background or foreground +// the comment before each member field refers to Vim's variable name pub const DEFAULT_DARK: Theme = Theme { // LineNr offsets: Style::new().fg(Color::Indexed(11)).bg(Color::Reset), @@ -111,18 +110,24 @@ pub const DEFAULT_DARK: Theme = Theme { // Constant changed_bytes: Style::new().fg(Color::Indexed(13)).bg(Color::Reset), // CursorColumn - highlight: Style::new().fg(Color::Reset).bg(Color::Indexed(242)), + highlight: Style::new().fg(Color::Reset).bg(Color::Reset).reversed(), + // Visual + selection: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(248)), // Search byte_highlight: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(11)), - // Normal - status_bar: Style::new().fg(Color::Reset).bg(Color::Reset), + // StatusLine + status_bar: Style::new() + .fg(Color::Reset) + .bg(Color::Reset) + .reversed() + .bold(), // ErrorMsg error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), // DiffChange editing: Style::new() .fg(Color::Reset) .bg(Color::Indexed(5)) - .add_modifier(Modifier::RAPID_BLINK), + .rapid_blink(), }; pub const DEFAULT_LIGHT: Theme = Theme { @@ -137,18 +142,24 @@ pub const DEFAULT_LIGHT: Theme = Theme { // Constant = Magenta changed_bytes: Style::new().fg(Color::Magenta).bg(Color::Reset), // CursorColumn - highlight: Style::new().fg(Color::Reset).bg(Color::Indexed(7)), + highlight: Style::new().fg(Color::Reset).bg(Color::Reset).reversed(), + // Visual + selection: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(248)), // Search byte_highlight: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(11)), - // Normal - status_bar: Style::new().fg(Color::Reset).bg(Color::Reset), + // StatusLine + status_bar: Style::new() + .fg(Color::Reset) + .bg(Color::Reset) + .reversed() + .bold(), // ErrorMsg error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), // DiffChange editing: Style::new() .fg(Color::Reset) .bg(Color::LightMagenta) - .add_modifier(Modifier::RAPID_BLINK), + .rapid_blink(), }; pub const DARKBLUE: Theme = Theme { @@ -163,7 +174,9 @@ pub const DARKBLUE: Theme = Theme { // Constant changed_bytes: Style::new().fg(Color::Indexed(217)).bg(Color::Indexed(17)), // CursorColumn - highlight: Style::new().fg(Color::from_u32(0xffffff)).bg(Color::from_u32(0x8489ff)), + highlight: Style::new() + .fg(Color::from_u32(0xffffff)) + .bg(Color::from_u32(0x8489ff)), // Search byte_highlight: Style::new().fg(Color::Indexed(123)).bg(Color::Indexed(27)), // Normal @@ -174,5 +187,9 @@ pub const DARKBLUE: Theme = Theme { editing: Style::new() .fg(Color::Reset) .bg(Color::LightMagenta) - .add_modifier(Modifier::RAPID_BLINK), + .rapid_blink(), + + selection: Style::new() + .fg(Color::from_u32(0xffffff)) + .bg(Color::from_u32(0x8489ff)), }; From bef5af57e0eb462716d6ca693dc3e67ded92dcfe Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 11:43:07 -0300 Subject: [PATCH 07/10] chore: update crates --- Cargo.lock | 126 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 700757a..6a0d1ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "arboard" -version = "3.6.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" +checksum = "aeb9553e62312c8756a5979254fc6d7da8bbeb5986a1e17037fab932f7037917" dependencies = [ "clipboard-win", "log", @@ -104,7 +104,7 @@ dependencies = [ "objc2-foundation", "parking_lot", "percent-encoding", - "windows-sys 0.60.2", + "windows-sys 0.61.2", "x11rb", ] @@ -316,6 +316,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "coolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980c2afde4af43d6a05c5be738f9eae595cff86dce1f38f88b95058a98c027f3" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -544,6 +550,7 @@ dependencies = [ "regex", "serde", "shell-words", + "terminal-light", "toml", "tui-input", ] @@ -746,17 +753,6 @@ dependencies = [ "scroll", ] -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - [[package]] name = "hashbrown" version = "0.17.1" @@ -817,7 +813,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", - "hashbrown 0.17.1", + "hashbrown", ] [[package]] @@ -876,11 +872,11 @@ dependencies = [ [[package]] name = "kasuari" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899" +checksum = "72f14c90e40a6133f4805b83542a7ed7364f56070b447f56e7f4e90297122209" dependencies = [ - "hashbrown 0.16.1", + "hashbrown", "portable-atomic", "thiserror 2.0.21", ] @@ -899,9 +895,9 @@ checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" [[package]] name = "libc" -version = "0.2.190" +version = "0.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" [[package]] name = "libm" @@ -960,7 +956,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5" dependencies = [ - "hashbrown 0.17.1", + "hashbrown", ] [[package]] @@ -1092,9 +1088,9 @@ dependencies = [ [[package]] name = "num_threads" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +checksum = "cabcc654086861f9e1bc5115258de62ef92c79b20f4615a1b0cc57c4e82027d4" dependencies = [ "libc", ] @@ -1257,9 +1253,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b568374ba38b33a6c627141f891faf16902b08d2db26b8ede1bcb0a15b1919fa" +checksum = "fd47a460a9cbc3b3429c7e22bf0d76653e779319bae45a499ca010c9a990bb23" dependencies = [ "memchr", "psm", @@ -1269,9 +1265,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66e184b924cebaaff20ab2256ca52f12332d528a39aa76553b5d96f92aacf7f" +checksum = "203e46697708f7519ab1608393cf89239cafb46b8e6d08a8ffe359359b11ef44" dependencies = [ "pest", "pest_generator", @@ -1279,9 +1275,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a87478d267e4de54a626af9754f2f0f58e927aac6ed0575fe89bc05ad6851694" +checksum = "e84ae6340a458d3d6cfc73cf328cf3cfe90b2484cd0de25eb66aa954615ed4d5" dependencies = [ "pest", "pest_meta", @@ -1292,9 +1288,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f986f248b4241ac359b831f6139aaa34e03b08a37b6caf7e201a33f95c869e1" +checksum = "b57f92f32b3dbce6598fd8f5cdf1f06a6072570b8103fa21728fa9036923e710" dependencies = [ "pest", ] @@ -1481,7 +1477,7 @@ dependencies = [ "bitflags 2.13.2", "compact_str", "critical-section", - "hashbrown 0.17.1", + "hashbrown", "itertools", "kasuari", "lru", @@ -1544,7 +1540,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66e3d19bcc9130ca376277d93b60767ff121ace3be06f5f95f81dd68956407d1" dependencies = [ "bitflags 2.13.2", - "hashbrown 0.17.1", + "hashbrown", "indoc", "instability", "itertools", @@ -1881,6 +1877,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "terminal-light" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23493cf1be461ed14d2c81bf1d39dcea17c8095d4f623b1a1292ea212f6b88ed" +dependencies = [ + "coolor", + "crossterm", + "thiserror 2.0.21", + "xterm-query", +] + [[package]] name = "terminfo" version = "0.9.0" @@ -2344,9 +2352,9 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] @@ -2362,11 +2370,10 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows-link", "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", @@ -2379,51 +2386,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.53.1" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -2454,6 +2461,17 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" +[[package]] +name = "xterm-query" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3cad17d6cbdca6eaf31f1cc8c0b624cde2266261e8b5573c13081bd8a09eb5" +dependencies = [ + "nix 0.31.3", + "thiserror 2.0.21", + "windows-sys 0.59.0", +] + [[package]] name = "yansi" version = "1.0.1" From 2925eb7f03a8659b994e7a4ae5c6c5ee6f3858a3 Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 13:01:38 -0300 Subject: [PATCH 08/10] feat: use Change for changed_bytes --- src/main.rs | 2 +- src/themes.rs | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index ce8dc71..60cff07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,7 +57,7 @@ fn main() { // choose Vim-inspired colorscheme based on terminal colors // Vim uses https://github.com/vim/vim/blob/5a9a0518b153b8571ff4d55c5727b72341080cef/src/term.c#L6098 - // but we simplify by using the terminal_light crate + // but we simplify it by using the terminal-light crate if terminal_light::luma().is_ok_and(|luma| luma > 0.6) { app.config.theme = DEFAULT_LIGHT; } diff --git a/src/themes.rs b/src/themes.rs index e015823..d7d6413 100644 --- a/src/themes.rs +++ b/src/themes.rs @@ -1,4 +1,7 @@ -use ratatui::style::{Color, Style}; +use ratatui::style::{ + Color::{self, Indexed}, + Style, +}; pub struct Theme { pub main: Style, @@ -107,8 +110,8 @@ pub const DEFAULT_DARK: Theme = Theme { dimmed: Style::new().fg(Color::DarkGray).bg(Color::Reset), // Normal dialog: Style::new().fg(Color::Indexed(11)).bg(Color::Reset), - // Constant - changed_bytes: Style::new().fg(Color::Indexed(13)).bg(Color::Reset), + // Changed + changed_bytes: Style::new().fg(Indexed(12)).bg(Color::Reset), // CursorColumn highlight: Style::new().fg(Color::Reset).bg(Color::Reset).reversed(), // Visual @@ -123,10 +126,11 @@ pub const DEFAULT_DARK: Theme = Theme { .bold(), // ErrorMsg error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), - // DiffChange + // Changed, but reversed editing: Style::new() - .fg(Color::Reset) - .bg(Color::Indexed(5)) + .fg(Indexed(12)) + .bg(Color::Reset) + .reversed() .rapid_blink(), }; @@ -139,8 +143,8 @@ pub const DEFAULT_LIGHT: Theme = Theme { dimmed: Style::new().fg(Color::DarkGray).bg(Color::Reset), // Normal dialog: Style::new().fg(Color::Indexed(130)).bg(Color::Reset), - // Constant = Magenta - changed_bytes: Style::new().fg(Color::Magenta).bg(Color::Reset), + // Changed + changed_bytes: Style::new().fg(Indexed(12)).bg(Color::Reset), // CursorColumn highlight: Style::new().fg(Color::Reset).bg(Color::Reset).reversed(), // Visual @@ -155,10 +159,11 @@ pub const DEFAULT_LIGHT: Theme = Theme { .bold(), // ErrorMsg error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), - // DiffChange + // Changed, but reversed editing: Style::new() - .fg(Color::Reset) - .bg(Color::LightMagenta) + .fg(Indexed(12)) + .bg(Color::Reset) + .reversed() .rapid_blink(), }; From a8e6060bed1c0dda5620addcdd84022de8b00d03 Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 14:16:18 -0300 Subject: [PATCH 09/10] chore: use constants for themes --- src/commands.rs | 27 +++++++++-- src/main.rs | 5 +- src/themes.rs | 120 ++++++++++++++++++++++++------------------------ 3 files changed, 85 insertions(+), 67 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 352f750..6057ed9 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -295,6 +295,25 @@ pub fn parse_command(app: &mut App, cmdline: &str) { } } } + // // background (for the default theme only for now) + // "background" | "bg" => { + // if let Some(val) = value && app.config.theme == DEFAULT_DARK { + // match val.as_str() { + // // we'll change only what matters in the default theme + // "dark" => { + // app.config.theme.offsets = DEFAULT_OFFSETS_DARK; + // app.config.theme.dialog = DEFAULT_OFFSETS_DARK; + // app.dialog_renderer = None; + // } + // "light" => { + // app.config.theme.offsets = DEFAULT_OFFSETS_LIGHT; + // app.config.theme.dialog = DEFAULT_OFFSETS_LIGHT; + // app.dialog_renderer = None; + // } + // _ => {} + // } + // } + // } // "readonly" | "ro" => { // app.file_info.is_read_only = true; // app.dialog_renderer = None; @@ -385,12 +404,12 @@ pub fn parse_command(app: &mut App, cmdline: &str) { app.config.theme = crate::themes::LIGHT; app.dialog_renderer = None; } - "default-light" => { - app.config.theme = crate::themes::DEFAULT_LIGHT; + "default" | "default-dark" => { + app.config.theme = crate::themes::DEFAULT_DARK; app.dialog_renderer = None; } - "default-dark" => { - app.config.theme = crate::themes::DEFAULT_DARK; + "default-light" => { + app.config.theme = crate::themes::DEFAULT_LIGHT; app.dialog_renderer = None; } "darkblue" => { diff --git a/src/main.rs b/src/main.rs index 60cff07..2916a47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,9 +24,6 @@ use ratatui::crossterm::event; use app::App; -use crate::themes::DEFAULT_LIGHT; - -/// vim-like hexadecimal editor #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { @@ -59,7 +56,7 @@ fn main() { // Vim uses https://github.com/vim/vim/blob/5a9a0518b153b8571ff4d55c5727b72341080cef/src/term.c#L6098 // but we simplify it by using the terminal-light crate if terminal_light::luma().is_ok_and(|luma| luma > 0.6) { - app.config.theme = DEFAULT_LIGHT; + app.config.theme = crate::themes::DEFAULT_LIGHT; } // read init file ignoring errors diff --git a/src/themes.rs b/src/themes.rs index d7d6413..ae34bff 100644 --- a/src/themes.rs +++ b/src/themes.rs @@ -17,7 +17,7 @@ pub struct Theme { pub selection: Style, } -// "old" themes left for compatiblity +// "old" themes left for compatibility pub const DARK: Theme = Theme { offsets: Style::new() .fg(Color::from_u32(0x569cd6)) @@ -101,74 +101,74 @@ pub const LIGHT: Theme = Theme { // they depend on the terminal config, which is good and bad :) // Color::Reset means the terminal default for background or foreground // the comment before each member field refers to Vim's variable name + +// these colors differ +const DEFAULT_OFFSETS_DARK: Style = Style::new().fg(Color::Indexed(11)).bg(Color::Reset); +const DEFAULT_OFFSETS_LIGHT: Style = Style::new().fg(Color::Indexed(130)).bg(Color::Reset); + +// these are common between dark and light +const DEFAULT_MAIN: Style = Style::new().fg(Color::Reset).bg(Color::Reset); +const DEFAULT_DIMMED: Style = Style::new().fg(Color::DarkGray).bg(Color::Reset); +const DEFAULT_CHANGED_BYTES: Style = Style::new().fg(Indexed(12)).bg(Color::Reset); +const DEFAULT_HIGHLIGHT: Style = DEFAULT_MAIN.reversed(); +const DEFAULT_SELECTION: Style = Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(248)); +const DEFAULT_BYTE_HIGHLIGHT: Style = Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(11)); +const DEFAULT_STATUS_BAR: Style = DEFAULT_MAIN.reversed().bold(); +const DEFAULT_ERROR: Style = Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)); +const DEFAULT_EDITING: Style = DEFAULT_CHANGED_BYTES.reversed().rapid_blink(); + pub const DEFAULT_DARK: Theme = Theme { // LineNr - offsets: Style::new().fg(Color::Indexed(11)).bg(Color::Reset), + offsets: DEFAULT_OFFSETS_DARK, // Normal - main: Style::new().fg(Color::Reset).bg(Color::Reset), + main: DEFAULT_MAIN, // set to DarkGray because Vim's Comment is too bright - dimmed: Style::new().fg(Color::DarkGray).bg(Color::Reset), + dimmed: DEFAULT_DIMMED, // Normal - dialog: Style::new().fg(Color::Indexed(11)).bg(Color::Reset), + dialog: DEFAULT_OFFSETS_DARK, // Changed - changed_bytes: Style::new().fg(Indexed(12)).bg(Color::Reset), + changed_bytes: DEFAULT_CHANGED_BYTES, // CursorColumn - highlight: Style::new().fg(Color::Reset).bg(Color::Reset).reversed(), + highlight: DEFAULT_HIGHLIGHT, // Visual - selection: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(248)), + selection: DEFAULT_SELECTION, // Search - byte_highlight: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(11)), + byte_highlight: DEFAULT_BYTE_HIGHLIGHT, // StatusLine - status_bar: Style::new() - .fg(Color::Reset) - .bg(Color::Reset) - .reversed() - .bold(), + status_bar: DEFAULT_STATUS_BAR, // ErrorMsg - error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), - // Changed, but reversed - editing: Style::new() - .fg(Indexed(12)) - .bg(Color::Reset) - .reversed() - .rapid_blink(), + error: DEFAULT_ERROR, + // changed_bytes, but reversed + editing: DEFAULT_EDITING, }; pub const DEFAULT_LIGHT: Theme = Theme { // LineNr = Brown - offsets: Style::new().fg(Color::Indexed(130)).bg(Color::Reset), + offsets: DEFAULT_OFFSETS_LIGHT, // Normal - main: Style::new().fg(Color::Reset).bg(Color::Reset), + main: DEFAULT_MAIN, // set to DarkGray because Vim's Comment is too bright - dimmed: Style::new().fg(Color::DarkGray).bg(Color::Reset), + dimmed: DEFAULT_DIMMED, // Normal - dialog: Style::new().fg(Color::Indexed(130)).bg(Color::Reset), + dialog: DEFAULT_OFFSETS_LIGHT, // Changed - changed_bytes: Style::new().fg(Indexed(12)).bg(Color::Reset), + changed_bytes: DEFAULT_CHANGED_BYTES, // CursorColumn - highlight: Style::new().fg(Color::Reset).bg(Color::Reset).reversed(), + highlight: DEFAULT_HIGHLIGHT, // Visual - selection: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(248)), + selection: DEFAULT_SELECTION, // Search - byte_highlight: Style::new().fg(Color::Indexed(0)).bg(Color::Indexed(11)), + byte_highlight: DEFAULT_BYTE_HIGHLIGHT, // StatusLine - status_bar: Style::new() - .fg(Color::Reset) - .bg(Color::Reset) - .reversed() - .bold(), + status_bar: DEFAULT_STATUS_BAR, // ErrorMsg - error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), - // Changed, but reversed - editing: Style::new() - .fg(Indexed(12)) - .bg(Color::Reset) - .reversed() - .rapid_blink(), + error: DEFAULT_ERROR, + // changed_bytes, but reversed + editing: DEFAULT_EDITING, }; pub const DARKBLUE: Theme = Theme { - // LineNr = Brown + // LineNr offsets: Style::new().fg(Color::Indexed(118)).bg(Color::Indexed(17)), // Normal main: Style::new().fg(Color::Indexed(252)).bg(Color::Indexed(17)), @@ -176,25 +176,27 @@ pub const DARKBLUE: Theme = Theme { dimmed: Style::new().fg(Color::Indexed(102)).bg(Color::Indexed(17)), // Normal dialog: Style::new().fg(Color::Indexed(118)).bg(Color::Indexed(17)), - // Constant - changed_bytes: Style::new().fg(Color::Indexed(217)).bg(Color::Indexed(17)), + // Changed + changed_bytes: Style::new().fg(Color::Indexed(12)).bg(Color::Indexed(17)), // CursorColumn - highlight: Style::new() - .fg(Color::from_u32(0xffffff)) - .bg(Color::from_u32(0x8489ff)), + highlight: Style::new().fg(Color::Indexed(252)).bg(Color::Indexed(59)), + // Visual + selection: Style::new().fg(Color::Indexed(231)).bg(Color::Indexed(105)), // Search - byte_highlight: Style::new().fg(Color::Indexed(123)).bg(Color::Indexed(27)), - // Normal - status_bar: Style::new().fg(Color::Reset).bg(Color::Indexed(17)), + byte_highlight: Style::new() + .fg(Color::Indexed(123)) + .bg(Color::Indexed(27)) + .reversed(), + // StatusLine + status_bar: Style::new() + .fg(Color::Indexed(252)) + .bg(Color::Indexed(17)) + .reversed(), // ErrorMsg - error: Style::new().fg(Color::Indexed(15)).bg(Color::Indexed(1)), - // DiffChange + error: DEFAULT_ERROR, + // changed_bytes, but reversed editing: Style::new() - .fg(Color::Reset) - .bg(Color::LightMagenta) - .rapid_blink(), - - selection: Style::new() - .fg(Color::from_u32(0xffffff)) - .bg(Color::from_u32(0x8489ff)), + .fg(Color::Indexed(12)) + .bg(Color::Indexed(17)) + .reversed(), }; From 4bab206ebe3300c362bd5749caad7a6291489fe6 Mon Sep 17 00:00:00 2001 From: merces Date: Sat, 17 Oct 2026 17:26:55 -0300 Subject: [PATCH 10/10] feat: use offsetcolor in Header view menus --- src/header/formats/elf/draw.rs | 2 +- src/header/formats/pe/draw.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/header/formats/elf/draw.rs b/src/header/formats/elf/draw.rs index 7031e51..ba3d1a2 100644 --- a/src/header/formats/elf/draw.rs +++ b/src/header/formats/elf/draw.rs @@ -607,7 +607,7 @@ fn draw_relocations(app: &mut App, frame: &mut Frame, area: Rect) { pub fn elf_draw(app: &mut App, frame: &mut Frame, area: Rect) { let tabs = Tabs::new(["ELF", "Program", "Sections", "Symbols", "Relocations"]) - .style(app.config.theme.main) + .style(app.config.theme.offsets) .highlight_style(app.config.theme.highlight) .divider("|") .padding(" ", " ") diff --git a/src/header/formats/pe/draw.rs b/src/header/formats/pe/draw.rs index c5a846c..5d3a8c2 100644 --- a/src/header/formats/pe/draw.rs +++ b/src/header/formats/pe/draw.rs @@ -752,7 +752,7 @@ pub fn pe_draw(app: &mut App, frame: &mut Frame, area: Rect) { "Exports", "Overlay", ]) - .style(app.config.theme.main) + .style(app.config.theme.offsets) .highlight_style(app.config.theme.highlight) .divider("|") .padding(" ", " ")