From 142b00118a52e7596cf382ef705d2b0457b205ea Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Tue, 13 Oct 2026 21:51:57 +0200 Subject: [PATCH] fix: prioritize diagnostics over repository number colors --- TODO.md | 14 -------------- docs/configuration.md | 2 ++ src/tui.rs | 43 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/TODO.md b/TODO.md index 8623df6..9e24e30 100644 --- a/TODO.md +++ b/TODO.md @@ -1,17 +1,3 @@ -- [x] noticed that `dw` also removes the newline and as such merges lines. this is not intended behavior and should be fixed. `dw` should not affect other lines (and neither should `db`). -- [x] add `cw` and `cb` actions mimicking the `d` equivalent, but also entering insert mode. -- [x] add git/jj gutter info: - - fat, vertical, colored bar on inner side of gutter closer to gutter than to text (default) - - colored symbols: - - new: `+` - - deleted: `-` - - changed: `~` - - colored line numbers (current line color overrides) - - colors: - - new: green - - deleted: red - - changed: yellow -- [ ] mark changed files in normal file picker too (jj/git). - [ ] git gutter flashes on every keystroke/change; this should be fixed. - [ ] make all buffers (including pickers) scrolls the window when the cursor reaches a certain threshold. setting could something like "distance from frame edges", and the value could be an integer or none: - "none" would mean "always keep the cursor in the center of the frame" (i.e. scroll the viewport whenever the cursor moves to a different line) diff --git a/docs/configuration.md b/docs/configuration.md index 5ed4dc9..e8fd476 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -51,6 +51,8 @@ Plugin paths resolve relative to the config file, not the shell's working direct `config.git_gutter` defaults to `"bar"`: a fat `▌` with one blank column between the line number and marker and another before the text. `"symbols"` uses `+` / `-` / `~` with the same spacing. Added, removed, and modified lines use green, red, and yellow respectively. `"line_numbers"` colors the existing numbers without adding a marker column; the current line retains its cyan/bold caret highlight. `"none"` hides line-gutter repository indicators, not line numbers or picker file statuses. Other modes retain diagnostic number colors independently of repository markers. Unsupported strings, empty strings, and non-string values reject the configuration. +In `"line_numbers"` mode, color precedence is **current-line cyan/bold → highest-severity diagnostic → repository change → default number color**. In bar/symbol modes, diagnostic number colors and repository markers remain independent. + Indicators compare the current editor text (including unsaved edits) against Git `HEAD`, or the parent `@-` in Git-backed jj repositories, rather than against the last save or Git index. Line endings use the editor's LF normalization. They refresh after edits/saves, on focus regain, and once per second for repository changes. Historical snapshots do not receive live indicators. Eligible named files not yet on disk show nonempty unsaved text as added; tracked files missing on disk still compare their buffer text against the baseline. Non-repository, ignored, binary, symlink, and unsupported files have no indicators; neither do jj working changes with multiple parents. Both colocated and non-colocated Git-backed jj repositories are supported. Files above 16 MiB report an error and clear their indicators; request batches are limited to 64 MiB or 1024 files. `config.diff_context_lines = 10` sets how many unchanged aligned lines appear above and below each diff change; it defaults to `10` and accepts nonnegative integers, including `0` for changes only. `config.diff_expand_lines = 15` sets how many additional lines each directional expansion reveals per keypress; it defaults to `15` and accepts positive integers. Both are bounded by the platform's Rust `usize` maximum (`18446744073709551615` on 64-bit systems). Floats, strings, booleans, negative or oversized values, and a zero expansion step reject the whole Ruby configuration. diff --git a/src/tui.rs b/src/tui.rs index e9fd180..b0132ee 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -1753,12 +1753,12 @@ fn draw_document( } else { Style::default().fg(Color::DarkGray) }; - let style = match editor + let diagnostic = editor .diagnostics() .filter(|diagnostic| diagnostic_on_row(diagnostic, row)) .map(|diagnostic| diagnostic_severity(diagnostic.severity)) - .min_by_key(|(severity, _, _)| *severity) - { + .min_by_key(|(severity, _, _)| *severity); + let style = match diagnostic { Some((_, color, _)) => style.fg(color), None => style, }; @@ -1780,7 +1780,9 @@ fn draw_document( .fg(Color::Cyan) .add_modifier(Modifier::BOLD) } else { - color.map_or(style, |color| style.fg(color)) + color + .filter(|_| diagnostic.is_none()) + .map_or(style, |color| style.fg(color)) } } else { style @@ -14533,6 +14535,39 @@ end } assert_eq!(buffer[(viewport.x, viewport.y)].symbol(), "a"); } + editor + .replace_diagnostics( + "fixture", + editor.buffer_id(), + editor.text_revision(), + vec![ + annotation((0, 0), (0, 1), DiagnosticSeverity::Error, "current"), + annotation((1, 0), (1, 1), DiagnosticSeverity::Warning, "warning"), + annotation((2, 0), (2, 1), DiagnosticSeverity::Error, "error"), + ], + ) + .unwrap(); + editor.set_gutter_style(GutterStyle::LineNumbers); + let mut views = BufferViewports::default(); + let mut terminal = Terminal::new(ratatui::backend::TestBackend::new(24, 6)).unwrap(); + terminal + .draw(|frame| views.draw(frame, &mut editor)) + .unwrap(); + let viewport = views.panels.caret.unwrap().0; + let buffer = terminal.backend().buffer(); + assert_eq!(buffer[(0, viewport.y)].fg, Color::Cyan); + assert!(buffer[(0, viewport.y)].modifier.contains(Modifier::BOLD)); + assert_eq!(buffer[(0, viewport.y + 1)].fg, Color::Yellow); + assert_eq!(buffer[(0, viewport.y + 2)].fg, Color::Red); + assert_eq!(buffer[(0, viewport.y + 3)].fg, Color::DarkGray); + editor + .replace_diagnostics( + "fixture", + editor.buffer_id(), + editor.text_revision(), + vec![], + ) + .unwrap(); editor.set_gutter_style(GutterStyle::Symbols); editor.handle(Input::End); let mut scrolled_views = BufferViewports::default();