diff --git a/Cargo.lock b/Cargo.lock index 89145c7..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" @@ -525,7 +531,7 @@ dependencies = [ [[package]] name = "dz6" -version = "0.8.1" +version = "0.9.0" dependencies = [ "arboard", "chrono", @@ -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" diff --git a/Cargo.toml b/Cargo.toml index da70aa7..049f31d 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" @@ -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" 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/commands.rs b/src/commands.rs index 860b7d3..6057ed9 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -40,6 +40,9 @@ enum Command { length: String, }, Version, + Colorscheme { + scheme: String, + }, } #[derive(Parser, Debug)] @@ -292,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; @@ -372,6 +394,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" | "default-dark" => { + app.config.theme = crate::themes::DEFAULT_DARK; + app.dialog_renderer = None; + } + "default-light" => { + app.config.theme = crate::themes::DEFAULT_LIGHT; + app.dialog_renderer = None; + } + "darkblue" => { + app.config.theme = crate::themes::DARKBLUE; + 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); } @@ -384,9 +437,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 e2601a5..a4b6fd1 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,11 @@ 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); } + +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/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(" ", " ") 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) { diff --git a/src/main.rs b/src/main.rs index fcf2872..2916a47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,6 @@ use ratatui::crossterm::event; use app::App; -/// vim-like hexadecimal editor #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { @@ -53,6 +52,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 it by using the terminal-light crate + if terminal_light::luma().is_ok_and(|luma| luma > 0.6) { + app.config.theme = crate::themes::DEFAULT_LIGHT; + } + // read init file ignoring errors let _ = app.read_initfile(); diff --git a/src/themes.rs b/src/themes.rs index 812e236..ae34bff 100644 --- a/src/themes.rs +++ b/src/themes.rs @@ -1,4 +1,7 @@ -use ratatui::style::{Color, Modifier, Style}; +use ratatui::style::{ + Color::{self, Indexed}, + Style, +}; pub struct Theme { pub main: Style, @@ -7,37 +10,42 @@ 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, + pub selection: Style, } +// "old" themes left for compatibility 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), - topbar: Style::new() + status_bar: Style::new() .fg(Color::Rgb(204, 204, 204)) .bg(Color::from_u32(0x3c3c3c)), error: Style::new() @@ -46,50 +54,149 @@ 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)), - - topbar: Style::new() + 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 + +// 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: DEFAULT_OFFSETS_DARK, + // Normal + main: DEFAULT_MAIN, + // set to DarkGray because Vim's Comment is too bright + dimmed: DEFAULT_DIMMED, + // Normal + dialog: DEFAULT_OFFSETS_DARK, + // Changed + changed_bytes: DEFAULT_CHANGED_BYTES, + // CursorColumn + highlight: DEFAULT_HIGHLIGHT, + // Visual + selection: DEFAULT_SELECTION, + // Search + byte_highlight: DEFAULT_BYTE_HIGHLIGHT, + // StatusLine + status_bar: DEFAULT_STATUS_BAR, + // ErrorMsg + error: DEFAULT_ERROR, + // changed_bytes, but reversed + editing: DEFAULT_EDITING, +}; + +pub const DEFAULT_LIGHT: Theme = Theme { + // LineNr = Brown + offsets: DEFAULT_OFFSETS_LIGHT, + // Normal + main: DEFAULT_MAIN, + // set to DarkGray because Vim's Comment is too bright + dimmed: DEFAULT_DIMMED, + // Normal + dialog: DEFAULT_OFFSETS_LIGHT, + // Changed + changed_bytes: DEFAULT_CHANGED_BYTES, + // CursorColumn + highlight: DEFAULT_HIGHLIGHT, + // Visual + selection: DEFAULT_SELECTION, + // Search + byte_highlight: DEFAULT_BYTE_HIGHLIGHT, + // StatusLine + status_bar: DEFAULT_STATUS_BAR, + // ErrorMsg + error: DEFAULT_ERROR, + // changed_bytes, but reversed + editing: DEFAULT_EDITING, +}; + +pub const DARKBLUE: Theme = Theme { + // LineNr + 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)), + // Changed + changed_bytes: Style::new().fg(Color::Indexed(12)).bg(Color::Indexed(17)), + // CursorColumn + 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)) + .reversed(), + // StatusLine + status_bar: Style::new() + .fg(Color::Indexed(252)) + .bg(Color::Indexed(17)) + .reversed(), + // ErrorMsg + error: DEFAULT_ERROR, + // changed_bytes, but reversed + editing: Style::new() + .fg(Color::Indexed(12)) + .bg(Color::Indexed(17)) + .reversed(), };