From 9c162baafc5876d121dbae00019e227bb246e9fb Mon Sep 17 00:00:00 2001 From: Mauro Pereira Date: Thu, 13 Aug 2026 17:27:31 +0100 Subject: [PATCH 1/2] fix(core): add seven derived irregular verbs to the verb list Follow-up to #4036, which added "understand" and fixed #3916. `harper-core/irregular_verbs.json` carries the base verbs but is missing many of their derived forms, so `DidPast` and `HelpedPast` silently do nothing for those verbs. Adds forsake, oversee, rebuild, retake, rewrite, withhold and withstand. Only these seven were added. The curated dictionary tags their preterite forms as verbs, which is what the linters' expressions require before the lemma lookup ever happens. Another twelve derived verbs are also absent from the list, but their past forms carry no verb metadata in the dictionary, so adding them here alone would have no effect. Co-Authored-By: Claude Opus 5 (1M context) --- harper-core/irregular_verbs.json | 7 +++++++ harper-core/src/linting/did_past.rs | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/harper-core/irregular_verbs.json b/harper-core/irregular_verbs.json index 5bc13ff52e..274158091f 100644 --- a/harper-core/irregular_verbs.json +++ b/harper-core/irregular_verbs.json @@ -40,6 +40,7 @@ ["fly", "flew", "flown"], ["forget", "forgot", "forgotten"], ["forgo", "forwent", "forgone"], + ["forsake", "forsook", "forsaken"], ["freeze", "froze", "frozen"], "// get -- got -- gotten", ["get", "got", "got"], @@ -69,6 +70,7 @@ ["meet", "met", "met"], ["mistake", "mistook", "mistaken"], ["output", "output", "output"], + ["oversee", "oversaw", "overseen"], ["overtake", "overtook", "overtaken"], ["overthrow", "overthrew", "overthrown"], ["overwind", "overwound", "overwound"], @@ -78,10 +80,13 @@ "// prove -- proved -- proven/proved", ["put", "put", "put"], ["read", "read", "read"], + ["rebuild", "rebuilt", "rebuilt"], ["redo", "redid", "redone"], ["remake", "remade", "remade"], ["reread", "reread", "reread"], ["reset", "reset", "reset"], + ["retake", "retook", "retaken"], + ["rewrite", "rewrote", "rewritten"], ["ride", "rode", "ridden"], ["ring", "rang", "rung"], ["rise", "rose", "risen"], @@ -144,5 +149,7 @@ ["wet", "wet", "wet"], ["win", "won", "won"], ["wind", "wound", "wound"], + ["withhold", "withheld", "withheld"], + ["withstand", "withstood", "withstood"], ["write", "wrote", "written"] ] diff --git a/harper-core/src/linting/did_past.rs b/harper-core/src/linting/did_past.rs index 848c04ec8c..4d6e49d5ba 100644 --- a/harper-core/src/linting/did_past.rs +++ b/harper-core/src/linting/did_past.rs @@ -329,4 +329,22 @@ mod tests { DidPast::new(FstDictionary::curated()), ); } + + #[test] + fn derived_verbs_did_withstood() { + assert_suggestion_result( + "The bridge did withstood the storm.", + DidPast::new(FstDictionary::curated()), + "The bridge did withstand the storm.", + ); + } + + #[test] + fn derived_verbs_did_rewrote() { + assert_suggestion_result( + "I did rewrote the introduction.", + DidPast::new(FstDictionary::curated()), + "I did rewrite the introduction.", + ); + } } From 02a101f70f6c49bf879c8b51be8bb67da5ba1276 Mon Sep 17 00:00:00 2001 From: Elijah Potter Date: Thu, 13 Aug 2026 11:08:31 -0600 Subject: [PATCH 2/2] Release 2.8.0 harper-asciidoc@2.8.0 harper-brill@2.8.0 harper-comments@2.8.0 harper-core@2.8.0 harper-dictionary-wordlist@2.8.0 harper-git-commit@2.8.0 harper-html@2.8.0 harper-ink@2.8.0 harper-jjdescription@2.8.0 harper-literate-haskell@2.8.0 harper-ls@2.8.0 harper-pos-utils@2.8.0 harper-python@2.8.0 harper-stats@2.8.0 harper-tex@2.8.0 harper-thesaurus@2.8.0 harper-tree-sitter@2.8.0 harper-typst@2.8.0 Generated by cargo-workspaces --- Cargo.lock | 36 ++++++++++++------------ harper-asciidoc/Cargo.toml | 2 +- harper-brill/Cargo.toml | 2 +- harper-comments/Cargo.toml | 2 +- harper-core/Cargo.toml | 2 +- harper-desktop/package.json | 2 +- harper-desktop/src-tauri/Cargo.toml | 2 +- harper-desktop/src-tauri/tauri.conf.json | 2 +- harper-dictionary-wordlist/Cargo.toml | 2 +- harper-git-commit/Cargo.toml | 2 +- harper-html/Cargo.toml | 2 +- harper-ink/Cargo.toml | 2 +- harper-jjdescription/Cargo.toml | 2 +- harper-literate-haskell/Cargo.toml | 2 +- harper-ls/Cargo.toml | 2 +- harper-pos-utils/Cargo.toml | 2 +- harper-python/Cargo.toml | 2 +- harper-stats/Cargo.toml | 2 +- harper-tex/Cargo.toml | 2 +- harper-thesaurus/Cargo.toml | 2 +- harper-tree-sitter/Cargo.toml | 2 +- harper-typst/Cargo.toml | 2 +- packages/chrome-plugin/package.json | 2 +- packages/harper.js/package.json | 2 +- packages/obsidian-plugin/package.json | 2 +- packages/vscode-plugin/package.json | 34 ++++++++++++++++++++-- 26 files changed, 74 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 983c91760f..6e96b94cf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4169,7 +4169,7 @@ dependencies = [ [[package]] name = "harper-asciidoc" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "harper-tree-sitter", @@ -4180,7 +4180,7 @@ dependencies = [ [[package]] name = "harper-brill" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-pos-utils", "serde_json", @@ -4218,7 +4218,7 @@ dependencies = [ [[package]] name = "harper-comments" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "harper-html", @@ -4257,7 +4257,7 @@ dependencies = [ [[package]] name = "harper-core" -version = "2.7.0" +version = "2.8.0" dependencies = [ "ammonia", "bitflags 2.11.0", @@ -4333,7 +4333,7 @@ dependencies = [ [[package]] name = "harper-dictionary-wordlist" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "itertools 0.14.0", @@ -4342,7 +4342,7 @@ dependencies = [ [[package]] name = "harper-git-commit" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "harper-tree-sitter", @@ -4353,7 +4353,7 @@ dependencies = [ [[package]] name = "harper-html" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "harper-tree-sitter", @@ -4364,7 +4364,7 @@ dependencies = [ [[package]] name = "harper-ink" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "harper-tree-sitter", @@ -4375,7 +4375,7 @@ dependencies = [ [[package]] name = "harper-jjdescription" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "harper-tree-sitter", @@ -4386,7 +4386,7 @@ dependencies = [ [[package]] name = "harper-literate-haskell" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-comments", "harper-core", @@ -4397,7 +4397,7 @@ dependencies = [ [[package]] name = "harper-ls" -version = "2.7.0" +version = "2.8.0" dependencies = [ "anyhow", "clap", @@ -4429,7 +4429,7 @@ dependencies = [ [[package]] name = "harper-pos-utils" -version = "2.7.0" +version = "2.8.0" dependencies = [ "burn", "burn-ndarray", @@ -4447,7 +4447,7 @@ dependencies = [ [[package]] name = "harper-python" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "harper-tree-sitter", @@ -4458,7 +4458,7 @@ dependencies = [ [[package]] name = "harper-stats" -version = "2.7.0" +version = "2.8.0" dependencies = [ "chrono", "harper-core", @@ -4469,7 +4469,7 @@ dependencies = [ [[package]] name = "harper-tex" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "paste", @@ -4477,7 +4477,7 @@ dependencies = [ [[package]] name = "harper-thesaurus" -version = "2.7.0" +version = "2.8.0" dependencies = [ "hashbrown 0.16.1", "indexmap 2.14.0", @@ -4488,7 +4488,7 @@ dependencies = [ [[package]] name = "harper-tree-sitter" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "tree-sitter", @@ -4507,7 +4507,7 @@ dependencies = [ [[package]] name = "harper-typst" -version = "2.7.0" +version = "2.8.0" dependencies = [ "harper-core", "itertools 0.14.0", diff --git a/harper-asciidoc/Cargo.toml b/harper-asciidoc/Cargo.toml index 6ad9608d57..bf3c8cdd3b 100644 --- a/harper-asciidoc/Cargo.toml +++ b/harper-asciidoc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-asciidoc" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-brill/Cargo.toml b/harper-brill/Cargo.toml index d1555273b3..cf6bbc6d2b 100644 --- a/harper-brill/Cargo.toml +++ b/harper-brill/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-brill" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-comments/Cargo.toml b/harper-comments/Cargo.toml index 46cf6cf82a..e262f02274 100644 --- a/harper-comments/Cargo.toml +++ b/harper-comments/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-comments" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-core/Cargo.toml b/harper-core/Cargo.toml index dec5d9d37f..3c595f6b3d 100644 --- a/harper-core/Cargo.toml +++ b/harper-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-core" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-desktop/package.json b/harper-desktop/package.json index 5c636f5c48..091324db8b 100644 --- a/harper-desktop/package.json +++ b/harper-desktop/package.json @@ -1,6 +1,6 @@ { "name": "harper-desktop", - "version": "2.7.0", + "version": "2.8.0", "description": "", "type": "module", "scripts": { diff --git a/harper-desktop/src-tauri/Cargo.toml b/harper-desktop/src-tauri/Cargo.toml index ccc5376aa2..619710d6f3 100644 --- a/harper-desktop/src-tauri/Cargo.toml +++ b/harper-desktop/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-desktop" -version = "2.7.0" +version = "2.8.0" description = "The language checker for developers." edition = "2024" publish = false diff --git a/harper-desktop/src-tauri/tauri.conf.json b/harper-desktop/src-tauri/tauri.conf.json index 7e71d4ef8e..fc3a4d45e6 100644 --- a/harper-desktop/src-tauri/tauri.conf.json +++ b/harper-desktop/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Harper", - "version": "2.7.0", + "version": "2.8.0", "identifier": "com.elijahpotter.harper-desktop", "build": { "beforeDevCommand": "pnpm dev", diff --git a/harper-dictionary-wordlist/Cargo.toml b/harper-dictionary-wordlist/Cargo.toml index f9d3a5e4f4..eaeec72a96 100644 --- a/harper-dictionary-wordlist/Cargo.toml +++ b/harper-dictionary-wordlist/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-dictionary-wordlist" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-git-commit/Cargo.toml b/harper-git-commit/Cargo.toml index f38afd7250..31d4257744 100644 --- a/harper-git-commit/Cargo.toml +++ b/harper-git-commit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-git-commit" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-html/Cargo.toml b/harper-html/Cargo.toml index 1fda0e28ee..6f040b23d4 100644 --- a/harper-html/Cargo.toml +++ b/harper-html/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-html" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-ink/Cargo.toml b/harper-ink/Cargo.toml index cc15e1d9c8..6c4ad34173 100644 --- a/harper-ink/Cargo.toml +++ b/harper-ink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-ink" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-jjdescription/Cargo.toml b/harper-jjdescription/Cargo.toml index 2c64e79a70..60c3c8ebca 100644 --- a/harper-jjdescription/Cargo.toml +++ b/harper-jjdescription/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-jjdescription" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-literate-haskell/Cargo.toml b/harper-literate-haskell/Cargo.toml index a3f0628d12..2760cc48c4 100644 --- a/harper-literate-haskell/Cargo.toml +++ b/harper-literate-haskell/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-literate-haskell" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-ls/Cargo.toml b/harper-ls/Cargo.toml index 07621a0bc6..4af3665fb3 100644 --- a/harper-ls/Cargo.toml +++ b/harper-ls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-ls" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-pos-utils/Cargo.toml b/harper-pos-utils/Cargo.toml index 532e86943f..dd6dc2f944 100644 --- a/harper-pos-utils/Cargo.toml +++ b/harper-pos-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-pos-utils" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-python/Cargo.toml b/harper-python/Cargo.toml index 880a611237..8af740386e 100644 --- a/harper-python/Cargo.toml +++ b/harper-python/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-python" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-stats/Cargo.toml b/harper-stats/Cargo.toml index cf6bd71062..345a82c844 100644 --- a/harper-stats/Cargo.toml +++ b/harper-stats/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-stats" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-tex/Cargo.toml b/harper-tex/Cargo.toml index 7b22305654..5f5b561b73 100644 --- a/harper-tex/Cargo.toml +++ b/harper-tex/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-tex" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-thesaurus/Cargo.toml b/harper-thesaurus/Cargo.toml index 3cd08e509c..8feaed2c91 100644 --- a/harper-thesaurus/Cargo.toml +++ b/harper-thesaurus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-thesaurus" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-tree-sitter/Cargo.toml b/harper-tree-sitter/Cargo.toml index 63c0191995..f9fbc52cab 100644 --- a/harper-tree-sitter/Cargo.toml +++ b/harper-tree-sitter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-tree-sitter" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/harper-typst/Cargo.toml b/harper-typst/Cargo.toml index 38961d1a53..b03a520d38 100644 --- a/harper-typst/Cargo.toml +++ b/harper-typst/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "harper-typst" -version = "2.7.0" +version = "2.8.0" edition = "2024" description = "The language checker for developers." license = "Apache-2.0" diff --git a/packages/chrome-plugin/package.json b/packages/chrome-plugin/package.json index 6d3e188eae..09933b795f 100644 --- a/packages/chrome-plugin/package.json +++ b/packages/chrome-plugin/package.json @@ -1,7 +1,7 @@ { "name": "chrome-plugin", "displayName": "chrome-plugin", - "version": "2.7.0", + "version": "2.8.0", "author": "no one", "description": "The private grammar checker for 21st Century English", "type": "module", diff --git a/packages/harper.js/package.json b/packages/harper.js/package.json index 43e576052a..8c2b48296c 100644 --- a/packages/harper.js/package.json +++ b/packages/harper.js/package.json @@ -1,6 +1,6 @@ { "name": "harper.js", - "version": "2.7.0", + "version": "2.8.0", "license": "Apache-2.0", "author": "Elijah Potter", "description": "The grammar checker that respects your privacy.", diff --git a/packages/obsidian-plugin/package.json b/packages/obsidian-plugin/package.json index 752d3d1741..1d4d3a6c4d 100644 --- a/packages/obsidian-plugin/package.json +++ b/packages/obsidian-plugin/package.json @@ -1,7 +1,7 @@ { "name": "obsidian-plugin", "private": true, - "version": "2.7.0", + "version": "2.8.0", "main": "main.js", "devDependencies": { "@playwright/test": "1.60.0", diff --git a/packages/vscode-plugin/package.json b/packages/vscode-plugin/package.json index 7a9f0e87b3..042060db3c 100644 --- a/packages/vscode-plugin/package.json +++ b/packages/vscode-plugin/package.json @@ -2,7 +2,7 @@ "name": "harper", "displayName": "Harper - Grammar / Spell Checking", "description": "The grammar checker for developers", - "version": "2.7.0", + "version": "2.8.0", "private": true, "author": "Elijah Potter", "publisher": "elijah-potter", @@ -237,6 +237,12 @@ "default": true, "description": "Enforces `awhile` after verbs and `a while` everywhere else." }, + "harper.linters.AccuseOf": { + "scope": "resource", + "type": "boolean", + "default": true, + "description": "Corrects `accuse for` to `accuse of`." + }, "harper.linters.AdNauseam": { "scope": "resource", "type": "boolean", @@ -2325,6 +2331,12 @@ "default": true, "description": "After `imitate ...`, idiomatic phrasing points to the inspiration with `of` instead of `from`." }, + "harper.linters.ImplementIn": { + "scope": "resource", + "type": "boolean", + "default": true, + "description": "Corrects nonstandard `implement into` to `implement in`." + }, "harper.linters.Impressed": { "scope": "resource", "type": "boolean", @@ -3078,7 +3090,7 @@ "harper.linters.MoreAdjective": { "scope": "resource", "type": "boolean", - "default": true, + "default": false, "description": "Looks for comparative adjective constructions with `more` than could use inflected forms." }, "harper.linters.MoreBetter": { @@ -4317,6 +4329,12 @@ "default": true, "description": "Corrects `take a look to`/`have a look to` to correctly use `at`." }, + "harper.linters.TakeCareOf": { + "scope": "resource", + "type": "boolean", + "default": true, + "description": "Corrects `take care about` to `take care of`." + }, "harper.linters.TakeItPersonally": { "scope": "resource", "type": "boolean", @@ -4851,6 +4869,12 @@ "default": true, "description": "Corrects `very less`." }, + "harper.linters.VeryMuchSo": { + "scope": "resource", + "type": "boolean", + "default": true, + "description": "`Very much` already intensifies the verb, so the trailing `so` is redundant. `Very much so` only reads correctly when the `so` refers back to something earlier, as in the reply `Yes, very much so.`" + }, "harper.linters.VeryUnique": { "scope": "resource", "type": "boolean", @@ -5079,6 +5103,12 @@ "default": true, "description": "Corrects semicolons, acute accents, and backticks typed instead of apostrophes." }, + "harper.linters.WrongNegative": { + "scope": "resource", + "type": "boolean", + "default": true, + "description": "If an unknown word looks like it might be a negative word, suggests correct words that are in the dictionary." + }, "harper.linters.WroteToRote": { "scope": "resource", "type": "boolean",