From 5fc3171a1ce0b918cb4a5821343275d4dccfcf76 Mon Sep 17 00:00:00 2001 From: Batyr Asadullin <33450576+Sengoku11@users.noreply.github.com> Date: Wed, 17 Dec 2025 00:20:12 +0800 Subject: [PATCH 1/8] feat: daml support (#2347) --- harper-comments/src/comment_parser.rs | 2 ++ .../web/src/routes/docs/integrations/language-server/+page.md | 1 + 2 files changed, 3 insertions(+) diff --git a/harper-comments/src/comment_parser.rs b/harper-comments/src/comment_parser.rs index 08493e07..47dbebb9 100644 --- a/harper-comments/src/comment_parser.rs +++ b/harper-comments/src/comment_parser.rs @@ -31,6 +31,7 @@ impl CommentParser { "dart" => harper_tree_sitter_dart::LANGUAGE, "go" => tree_sitter_go::LANGUAGE, "haskell" => tree_sitter_haskell::LANGUAGE, + "daml" => tree_sitter_haskell::LANGUAGE, "java" => tree_sitter_java::LANGUAGE, "javascript" => tree_sitter_javascript::LANGUAGE, "javascriptreact" => tree_sitter_typescript::LANGUAGE_TSX, @@ -89,6 +90,7 @@ impl CommentParser { "dart" => "dart", "go" => "go", "hs" => "haskell", + "daml" => "daml", "java" => "java", "js" => "javascript", "jsx" => "javascriptreact", diff --git a/packages/web/src/routes/docs/integrations/language-server/+page.md b/packages/web/src/routes/docs/integrations/language-server/+page.md index 4dfc4886..cc5e6f50 100644 --- a/packages/web/src/routes/docs/integrations/language-server/+page.md +++ b/packages/web/src/routes/docs/integrations/language-server/+page.md @@ -274,6 +274,7 @@ These configs are under the `markdown` key: | CMake | `cmake` | ✅ | | C++ | `cpp` | ✅ | | C# | `csharp` | ✅ | +| DAML | `daml` | ✅ | | Dart | `dart` | ✅ | | Git Commit | `git-commit`/`gitcommit` | | | Go | `go` | ✅ | From c9f4b7c49cc41e7151e1f66c83bc95293f8dccbe Mon Sep 17 00:00:00 2001 From: Andrew Dunbar Date: Wed, 17 Dec 2025 00:21:18 +0800 Subject: [PATCH 2/8] fix: false positive for "since N years old" (#2342) --- harper-core/src/linting/since_duration.rs | 55 +++++++++++++---------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/harper-core/src/linting/since_duration.rs b/harper-core/src/linting/since_duration.rs index b14ba954..1fbc6937 100644 --- a/harper-core/src/linting/since_duration.rs +++ b/harper-core/src/linting/since_duration.rs @@ -1,5 +1,5 @@ -use crate::expr::{DurationExpr, Expr, LongestMatchOf, SequenceExpr}; -use crate::{Lrc, Token, TokenStringExt}; +use crate::expr::{DurationExpr, Expr, SequenceExpr}; +use crate::{CharStringExt, Token, TokenStringExt}; use super::{ExprLinter, Lint, LintKind, Suggestion}; use crate::linting::expr_linter::Chunk; @@ -25,23 +25,18 @@ pub struct SinceDuration { impl Default for SinceDuration { fn default() -> Self { - let pattern_without_ago = Lrc::new( - SequenceExpr::default() - .then_any_capitalization_of("since") - .then_whitespace() - .then(DurationExpr), - ); - - let pattern_with_ago = SequenceExpr::default() - .then(pattern_without_ago.clone()) - .then_whitespace() - .then_any_capitalization_of("ago"); - Self { - expr: Box::new(LongestMatchOf::new(vec![ - Box::new(pattern_without_ago), - Box::new(pattern_with_ago), - ])), + expr: Box::new( + SequenceExpr::default() + .then_any_capitalization_of("since") + .then_whitespace() + .then(DurationExpr) + .then_optional( + SequenceExpr::default() + .t_ws() + .then_word_set(&["ago", "old"]), + ), + ), } } } @@ -55,7 +50,11 @@ impl ExprLinter for SinceDuration { fn match_to_lint(&self, toks: &[Token], src: &[char]) -> Option { let last = toks.last()?; - if last.span.get_content_string(src).to_lowercase() == "ago" { + if last + .span + .get_content(src) + .eq_any_ignore_ascii_case_chars(&[&['a', 'g', 'o'], &['o', 'l', 'd']]) + { return None; } @@ -94,7 +93,9 @@ impl ExprLinter for SinceDuration { #[cfg(test)] mod tests { use super::SinceDuration; - use crate::linting::tests::{assert_lint_count, assert_top3_suggestion_result}; + use crate::linting::tests::{ + assert_lint_count, assert_no_lints, assert_top3_suggestion_result, + }; #[test] fn catches_spelled() { @@ -107,10 +108,9 @@ mod tests { #[test] fn permits_spelled_with_ago() { - assert_lint_count( + assert_no_lints( "I have been waiting since two hours ago.", SinceDuration::default(), - 0, ); } @@ -125,10 +125,9 @@ mod tests { #[test] fn permits_numerals_with_ago() { - assert_lint_count( + assert_no_lints( "I have been waiting since 2 hours ago.", SinceDuration::default(), - 0, ); } @@ -287,4 +286,12 @@ mod tests { "I use a Wacom Cintiq 27QHDT for several years on Linux", ); } + + #[test] + fn ignore_since_years_old() { + assert_no_lints( + "I've been coding since 11 years old and I'm now 57", + SinceDuration::default(), + ); + } } From 433829f3b8e2835da26ee23cd671396b123c30f3 Mon Sep 17 00:00:00 2001 From: Andrew Dunbar Date: Wed, 17 Dec 2025 00:21:53 +0800 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20make=20senses=E2=86=92make=20sense?= =?UTF-8?q?=20(#2330)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/linting/phrase_set_corrections/mod.rs | 11 ++++++ .../linting/phrase_set_corrections/tests.rs | 38 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/harper-core/src/linting/phrase_set_corrections/mod.rs b/harper-core/src/linting/phrase_set_corrections/mod.rs index d5784194..a1811fbd 100644 --- a/harper-core/src/linting/phrase_set_corrections/mod.rs +++ b/harper-core/src/linting/phrase_set_corrections/mod.rs @@ -289,6 +289,17 @@ pub fn lint_group() -> LintGroup { "Use `do` instead of `due` when referring to a resource scarcity.", "Corrects `make due` to `make do` when followed by `with`." ), + "MakeSense" => ( + &[ + ("make senses", "make sense"), + ("made senses", "made sense"), + ("makes senses", "makes sense"), + ("making senses", "making sense") + ], + "Use `sense` instead of `senses`.", + "Corrects `make senses` to `make sense`.", + LintKind::Usage + ), "MootPoint" => ( &[ ("mute point", "moot point"), diff --git a/harper-core/src/linting/phrase_set_corrections/tests.rs b/harper-core/src/linting/phrase_set_corrections/tests.rs index 38b756c5..5310600a 100644 --- a/harper-core/src/linting/phrase_set_corrections/tests.rs +++ b/harper-core/src/linting/phrase_set_corrections/tests.rs @@ -782,6 +782,44 @@ fn corrects_making_due_with() { ); } +// MakeSense + +#[test] +fn fix_make_senses() { + assert_suggestion_result( + "some symbols make senses only if you have a certain keyboard", + lint_group(), + "some symbols make sense only if you have a certain keyboard", + ); +} + +#[test] +fn fix_made_senses() { + assert_suggestion_result( + "Usually on the examples of matlab central I have found all with positive magnitude and made senses to me.", + lint_group(), + "Usually on the examples of matlab central I have found all with positive magnitude and made sense to me.", + ); +} + +#[test] +fn fix_makes_senses() { + assert_suggestion_result( + "If it makes senses I can open a PR.", + lint_group(), + "If it makes sense I can open a PR.", + ); +} + +#[test] +fn fix_making_senses() { + assert_suggestion_result( + "I appreciate you mentioned the two use cases, which are making senses for both.", + lint_group(), + "I appreciate you mentioned the two use cases, which are making sense for both.", + ); +} + // MootPoint // -point is mute- From 639a4b153ddef441dbf340c8be7c087b9bb3e504 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 16:22:27 +0000 Subject: [PATCH 4/8] build(deps): bump uuid from 1.18.1 to 1.19.0 (#2334) Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.18.1 to 1.19.0. - [Release notes](https://github.com/uuid-rs/uuid/releases) - [Commits](https://github.com/uuid-rs/uuid/compare/v1.18.1...v1.19.0) --- updated-dependencies: - dependency-name: uuid dependency-version: 1.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- harper-stats/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80ef3e51..1b55d84d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6230,13 +6230,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", - "serde", + "serde_core", "wasm-bindgen", ] diff --git a/harper-stats/Cargo.toml b/harper-stats/Cargo.toml index 3300188b..c8eac6fc 100644 --- a/harper-stats/Cargo.toml +++ b/harper-stats/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/automattic/harper" [dependencies] serde = { version = "1.0.228", features = ["derive"] } harper-core = { path = "../harper-core", version = "1.0.0", features = ["concurrent"] } -uuid = { version = "1.18.1", features = ["serde", "v4"] } +uuid = { version = "1.19.0", features = ["serde", "v4"] } serde_json = "1.0.145" chrono = "0.4.42" From 6a97ff125cc05726bffb93ebb0e46795c71ae782 Mon Sep 17 00:00:00 2001 From: Andrew Dunbar Date: Wed, 17 Dec 2025 00:23:30 +0800 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20part=20of=20speeches=20=E2=86=92=20?= =?UTF-8?q?parts=20of=20speech=20(#2346)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: part of speeches → parts of speech * chore: points of views, rules of thumbs, parts of speeches --- .../src/linting/phrase_corrections/mod.rs | 11 ++++- .../src/linting/phrase_corrections/tests.rs | 43 ++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/harper-core/src/linting/phrase_corrections/mod.rs b/harper-core/src/linting/phrase_corrections/mod.rs index a2ad1add..7815879e 100644 --- a/harper-core/src/linting/phrase_corrections/mod.rs +++ b/harper-core/src/linting/phrase_corrections/mod.rs @@ -859,6 +859,13 @@ pub fn lint_group() -> LintGroup { "Corrects `ontop of` to `on top of`.", LintKind::BoundaryError ), + "PartsOfSpeech" => ( + ["part of speeches", "parts of speeches"], + ["parts of speech"], + "The correct plural is `parts of speech`.", + "Corrects pluralizing the wrong noun in `part of speech`.", + LintKind::Grammar + ), "PeaceOfMind" => ( ["piece of mind"], ["peace of mind"], @@ -874,7 +881,7 @@ pub fn lint_group() -> LintGroup { LintKind::Spelling ), "PointsOfView" => ( - ["point of views"], + ["point of views", "points of views"], ["points of view"], "The correct plural is `points of view`.", "Corrects pluralizing the wrong noun in `point of view`.", @@ -953,7 +960,7 @@ pub fn lint_group() -> LintGroup { LintKind::WordChoice ), "RulesOfThumb" => ( - ["rule of thumbs", "rule-of-thumbs"], + ["rule of thumbs", "rule-of-thumbs", "rules of thumbs"], ["rules of thumb"], "The correct plural is `rules of thumb`.", "Corrects pluralizing the wrong noun in `rule of thumb`.", diff --git a/harper-core/src/linting/phrase_corrections/tests.rs b/harper-core/src/linting/phrase_corrections/tests.rs index ce715d8e..2970c98c 100644 --- a/harper-core/src/linting/phrase_corrections/tests.rs +++ b/harper-core/src/linting/phrase_corrections/tests.rs @@ -1473,6 +1473,26 @@ fn correct_on_top_of() { ); } +// PartOfSpeech +#[test] +fn corrects_part_of_speeches() { + assert_suggestion_result( + "The part of speeches (POS) or as follows:", + lint_group(), + "The parts of speech (POS) or as follows:", + ) +} + +// It can connect different parts of speeches e.g noun to adjective, adjective to adverb, noun to verb etc. +#[test] +fn corrects_parts_of_speeches() { + assert_suggestion_result( + "It can connect different parts of speeches e.g noun to adjective, adjective to adverb, noun to verb etc.", + lint_group(), + "It can connect different parts of speech e.g noun to adjective, adjective to adverb, noun to verb etc.", + ) +} + // PeaceOfMind #[test] fn corrects_piece_of_mind() { @@ -1513,7 +1533,7 @@ fn corrects_per_say_hyphenated() { // PointsOfView #[test] -fn corrects_points_of_view() { +fn corrects_point_of_views() { assert_suggestion_result( "This will produce a huge amount of raw data, representing the region in multiple point of views.", lint_group(), @@ -1521,6 +1541,16 @@ fn corrects_points_of_view() { ) } +// log events, places, moods and self-reflect from various points of views +#[test] +fn corrects_points_of_views() { + assert_suggestion_result( + "log events, places, moods and self-reflect from various points of views", + lint_group(), + "log events, places, moods and self-reflect from various points of view", + ) +} + // PrayingMantis // -none- @@ -1578,7 +1608,7 @@ fn correct_iirc_correctly() { // RulesOfThumb #[test] -fn correct_rules_of_thumbs() { +fn correct_rule_of_thumbs() { assert_suggestion_result( "Thanks. 0.2 is just from my rule of thumbs.", lint_group(), @@ -1586,6 +1616,15 @@ fn correct_rules_of_thumbs() { ); } +#[test] +fn correct_rules_of_thumbs() { + assert_suggestion_result( + "But as rules of thumbs, what is said in config file should be respected whatever parameter (field or directory) is passed to php-cs-fixer.phar.", + lint_group(), + "But as rules of thumb, what is said in config file should be respected whatever parameter (field or directory) is passed to php-cs-fixer.phar.", + ); +} + #[test] fn correct_rules_of_thumbs_hyphenated() { assert_suggestion_result( From 5e5a0a473af1671f4de6b9d7639bb962fc0eb6b9 Mon Sep 17 00:00:00 2001 From: Elijah Potter Date: Tue, 16 Dec 2025 09:54:00 -0700 Subject: [PATCH 6/8] feat(chrome-ext): show Harper version string in the popup (#2348) * feat(chrome-ext): show Harper version string in the popup * feat(chrome-ext): compare to latest version and show warning if unequal * fix(chrome-ext): put the emoji on the left --- packages/chrome-plugin/src/popup/Popup.svelte | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/chrome-plugin/src/popup/Popup.svelte b/packages/chrome-plugin/src/popup/Popup.svelte index e75f7625..d09e11de 100644 --- a/packages/chrome-plugin/src/popup/Popup.svelte +++ b/packages/chrome-plugin/src/popup/Popup.svelte @@ -1,6 +1,7 @@