Let a spelling or grammar issue be dismissed

Not every flag deserves a fix, so give the checkers a way to be told no:

- ✖ beside an issue in the panel, and a matching entry in the editor's
  right-click menu, wave that issue away.
- A dismissal is remembered as the offending text paired with the message
  rather than a byte range, since offsets move as soon as you type. Both
  checkers filter their fresh results against it, so a dismissed complaint
  stays gone across re-checks and repeats of the same phrase in the file.
- The panel header counts the dismissals and ↩ takes them back. The offline
  spell check then rebuilds its own list; LanguageTool's can only come from
  the server, so those are dropped with a nudge towards ✓ Check.

Dismissals belong to the open file and the session — they are cleared when
another file or workspace is opened, and never written to disk. A name or
invented term still belongs in the word list, which persists.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011CVsxwa6YukFS2YFUY8W2j
This commit is contained in:
2026-08-24 20:16:28 -05:00
parent 043cc692ac
commit 66d3f9817e
6 changed files with 188 additions and 6 deletions
+5
View File
@@ -301,6 +301,10 @@ pub struct App {
/// Index (into the currently displayed matches) of the word a right-click
/// suggestion menu is open for, if any.
spell_menu: Option<usize>,
/// Issues the user has waved away, as (offending text, message) pairs. Both
/// checkers drop matches keyed here, so a dismissed complaint stays hidden
/// when the file is checked again. Reset when a different file is opened.
dismissed: HashSet<(String, String)>,
/// Byte range in `buffer` the editor should select and scroll into view next
/// frame, set when an issue is clicked in the results panel.
issue_jump: Option<(usize, usize)>,
@@ -407,6 +411,7 @@ impl App {
diff_title: String::new(),
wordlist_input: String::new(),
spell_menu: None,
dismissed: HashSet::new(),
issue_jump: None,
show_mistral_settings: false,
show_template_settings: false,