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
+17
View File
@@ -197,6 +197,7 @@ impl App {
.map(str::to_string)
});
let mut accept: Option<String> = None;
let mut dismiss: Option<usize> = None;
output.response.context_menu(|ui| {
match &menu {
Some((i, reps)) if !reps.is_empty() => {
@@ -215,6 +216,19 @@ impl App {
ui.label(egui::RichText::new("No spelling issue here").weak());
}
}
// Not every complaint is worth acting on — let a deliberate
// one be waved away instead of underlined for good.
if let Some((i, _)) = &menu {
ui.separator();
if ui
.button("✖ Dismiss this issue")
.on_hover_text("Stop flagging this in this file")
.clicked()
{
dismiss = Some(*i);
ui.close_menu();
}
}
// A character or place name is not a misspelling; let it be
// accepted for good rather than corrected every time.
if let Some(word) = &target_word {
@@ -234,6 +248,9 @@ impl App {
if let Some(word) = accept {
self.add_to_dictionary(&word);
}
if let Some(i) = dismiss {
self.dismiss_issue(i);
}
if let Some((i, j)) = chosen {
self.apply_current_fix(i, j);
self.spell_menu = None;