Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed Compound Matcher Conversions #608

Merged
merged 25 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bf9e631
feat(core): create linter for "special attention"
elijah-potter Feb 5, 2025
10f8830
feat(core): extend `MergeWords` to include contractions
elijah-potter Feb 5, 2025
73dc677
feat(core): added `ThanOthers` phrase linter
elijah-potter Feb 5, 2025
8836400
feat(core): added `Whereas` rule
elijah-potter Feb 6, 2025
f2ec21a
feat(core): created rule for `it self`
elijah-potter Feb 6, 2025
7ab9fc1
refactor(core): created macro for closed compounds
elijah-potter Feb 6, 2025
c948b36
feat(core): add a bunch more closed compounds
elijah-potter Feb 6, 2025
faebc9a
feat(core): add more closed compounds from #440
elijah-potter Feb 6, 2025
09fcc79
feat(core): add more closed compounds
elijah-potter Feb 6, 2025
d8c3dc6
chore(core): fix imports
elijah-potter Feb 6, 2025
18408ba
feat(core): even more closed compounds
elijah-potter Feb 6, 2025
8faa551
feat(core): create specific linter for closed compound nouns
elijah-potter Feb 6, 2025
50d7fdf
feat(core): remove incorrect rules
elijah-potter Feb 7, 2025
1d26436
refactor(core): remove bad lints and make `Nobody` more specific.
elijah-potter Feb 7, 2025
4ff1245
refactor(core): delete macro calls and make `Likewise` stricter
elijah-potter Feb 7, 2025
f2640e4
feat(core): create special rule for `hereby`
elijah-potter Feb 7, 2025
dc7aeff
test(core): add exceptions for compound words
elijah-potter Feb 10, 2025
e4420ce
feat(core): make `overnight` a special rule
elijah-potter Feb 10, 2025
01c0fbd
refactor(core): use patterns for `CompoundNouns`
elijah-potter Feb 10, 2025
eb26cc5
fix(core): remove faulty test
elijah-potter Feb 10, 2025
207b6fd
feat(core): make possessive nouns imply compound nouns
elijah-potter Feb 10, 2025
c39a61e
Merge branch 'master' into matcher-conversions
elijah-potter Feb 10, 2025
2739f0f
docs(core): add line to new affix
elijah-potter Feb 10, 2025
fec6f47
deps(harper.js): update Vitest
elijah-potter Feb 10, 2025
3ad79a4
fix(core): ignore "you" followed by an adverb
elijah-potter Feb 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions harper-core/src/linting/closed_compounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,94 @@ create_closed_compound_linter!(Northeastern, "north eastern", "northeastern");
create_closed_compound_linter!(Upholstery, "up holstery", "upholstery");
create_closed_compound_linter!(Proofread, "proof read", "proofread");

create_closed_compound_linter!(Forever, "for ever", "forever");
create_closed_compound_linter!(Into, "in to", "into");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Everyone, "every one", "everyone");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Nobody, "no body", "nobody");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Somebody, "some body", "somebody");
create_closed_compound_linter!(Anybody, "any body", "anybody");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Nothing, "no thing", "nothing");
create_closed_compound_linter!(Anyway, "any way", "anyway");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Anytime, "any time", "anytime");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Anywhere, "any where", "anywhere");
create_closed_compound_linter!(Nowhere, "no where", "nowhere");
create_closed_compound_linter!(Everywhere, "every where", "everywhere");
create_closed_compound_linter!(Overnight, "over night", "overnight");
create_closed_compound_linter!(Instead, "in stead", "instead");
create_closed_compound_linter!(Backpack, "back pack", "backpack");
create_closed_compound_linter!(Cupboard, "cup board", "cupboard");
create_closed_compound_linter!(Keyboard, "key board", "keyboard");
create_closed_compound_linter!(Somewhere, "some where", "somewhere");
create_closed_compound_linter!(Notebook, "note book", "notebook");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Middleware, "middle ware", "middleware");
create_closed_compound_linter!(Firmware, "firm ware", "firmware");
create_closed_compound_linter!(Smartwatch, "smart watch", "smartwatch");
create_closed_compound_linter!(Touchscreen, "touch screen", "touchscreen");
create_closed_compound_linter!(Headset, "head set", "headset");
create_closed_compound_linter!(Framework, "frame work", "framework");
create_closed_compound_linter!(Touchpad, "touch pad", "touchpad");
create_closed_compound_linter!(Microprocessor, "micro processor", "microprocessor");
create_closed_compound_linter!(Datacenter, "data center", "datacenter");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Smartphone, "smart phone", "smartphone");
create_closed_compound_linter!(Webcam, "web cam", "webcam");
create_closed_compound_linter!(Headphone, "head phone", "headphone");
create_closed_compound_linter!(Desktop, "desk top", "desktop");
create_closed_compound_linter!(Laptop, "lap top", "laptop");
create_closed_compound_linter!(Overclocking, "over clocking", "overclocking");
create_closed_compound_linter!(Backplane, "back plane", "backplane");
create_closed_compound_linter!(Smartcard, "smart card", "smartcard");
create_closed_compound_linter!(Bitrate, "bit rate", "bitrate");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Overload, "over load", "overload");
create_closed_compound_linter!(Underclock, "under clock", "underclock");
create_closed_compound_linter!(Blockchain, "block chain", "blockchain");
create_closed_compound_linter!(Opensource, "open source", "opensource");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Devops, "dev ops", "devops");
create_closed_compound_linter!(Bitstream, "bit stream", "bitstream");
create_closed_compound_linter!(Firewall, "fire wall", "firewall");
create_closed_compound_linter!(Sitemap, "site map", "sitemap");
create_closed_compound_linter!(Multithreading, "multi threading", "multithreading");
create_closed_compound_linter!(Multicore, "multi core", "multicore");
create_closed_compound_linter!(Microservices, "micro services", "microservices");
create_closed_compound_linter!(Dashboard, "dash board", "dashboard");
create_closed_compound_linter!(Cyberspace, "cyber space", "cyberspace");
create_closed_compound_linter!(Multimedia, "multi media", "multimedia");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"multi-core" is also correct. Note that the hyphenated forms are not always correct. I'd consult Wiktionary when in doubt even though it's not perfect.

create_closed_compound_linter!(Ecommerce, "e commerce", "ecommerce");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Datamining, "data mining", "datamining");
create_closed_compound_linter!(Datascience, "data science", "datascience");
create_closed_compound_linter!(Cyberattack, "cyber attack", "cyberattack");
create_closed_compound_linter!(Websocket, "web socket", "websocket");
create_closed_compound_linter!(Fingerprint, "finger print", "fingerprint");
create_closed_compound_linter!(Widespread, "wide spread", "widespread");
create_closed_compound_linter!(Notwithstanding, "not with standing", "notwithstanding");
create_closed_compound_linter!(Anyhow, "any how", "anyhow");
create_closed_compound_linter!(Nonetheless, "none the less", "nonetheless");
create_closed_compound_linter!(Hereafter, "here after", "hereafter");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Otherwise, "other wise", "otherwise");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Therein, "there in", "therein");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The former is both legit and more common than the latter: "It's over there in that box". "I see him there in the window", etc. There in lies the problem.
image

create_closed_compound_linter!(Thereupon, "there upon", "thereupon");
create_closed_compound_linter!(Hereby, "here by", "hereby");
elijah-potter marked this conversation as resolved.
Show resolved Hide resolved
create_closed_compound_linter!(Hereunder, "here under", "hereunder");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"It's hidden right here under the carpet".

create_closed_compound_linter!(Forthwith, "forth with", "forthwith");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can occur in coding context: In my day we had to code in Forth with a line editor!

create_closed_compound_linter!(Insofar, "in so far", "insofar");
create_closed_compound_linter!(Whereupon, "where upon", "whereupon");
create_closed_compound_linter!(Thereafter, "there after", "thereafter");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"I got there after him". "Go back there after dinner and finish it." etc. Much more common than the legalese.

create_closed_compound_linter!(Downright, "down right", "downright");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"We've gotta do down right here" etc.

create_closed_compound_linter!(Upward, "up ward", "upward");
create_closed_compound_linter!(Henceforth, "hence forth", "henceforth");
create_closed_compound_linter!(Regardless, "regard less", "regardless");
create_closed_compound_linter!(Evermore, "ever more", "evermore");

#[cfg(test)]
mod tests {
use super::{
Altogether, Asleep, However, Itself, Likewise, Misunderstood, Misuse, Misused, Myself,
Overall, Therefore, Tonight, Worldwide,
};
use super::{
Anyhow, Downright, Evermore, Forthwith, Henceforth, Hereafter, Hereby, Hereunder, Insofar,
Nonetheless, Notwithstanding, Otherwise, Regardless, Thereafter, Therein, Thereupon,
Upward, Whereupon, Widespread,
};
use crate::linting::tests::assert_suggestion_result;

#[test]
Expand Down Expand Up @@ -180,4 +262,130 @@ mod tests {
let expected = "She fell asleep.";
assert_suggestion_result(test_sentence, Asleep::default(), expected);
}

#[test]
fn wide_spread() {
let test_sentence = "The news was wide spread throughout the region.";
let expected = "The news was widespread throughout the region.";
assert_suggestion_result(test_sentence, Widespread::default(), expected);
}

#[test]
fn not_with_standing() {
let test_sentence = "They decided to proceed not with standing any further delay.";
let expected = "They decided to proceed notwithstanding any further delay.";
assert_suggestion_result(test_sentence, Notwithstanding::default(), expected);
}

#[test]
fn any_how() {
let test_sentence = "She solved the problem any how, even under pressure.";
let expected = "She solved the problem anyhow, even under pressure.";
assert_suggestion_result(test_sentence, Anyhow::default(), expected);
}

#[test]
fn none_the_less() {
let test_sentence = "The results were disappointing, none the less, they continued.";
let expected = "The results were disappointing, nonetheless, they continued.";
assert_suggestion_result(test_sentence, Nonetheless::default(), expected);
}

#[test]
fn here_after() {
let test_sentence = "He promised to abide by the rules here after the meeting.";
let expected = "He promised to abide by the rules hereafter the meeting.";
assert_suggestion_result(test_sentence, Hereafter::default(), expected);
}

#[test]
fn other_wise() {
let test_sentence = "Review the guidelines, other wise you might miss an important detail.";
let expected = "Review the guidelines, otherwise you might miss an important detail.";
assert_suggestion_result(test_sentence, Otherwise::default(), expected);
}

#[test]
fn there_in() {
let test_sentence = "All the answers can be found there in the document.";
let expected = "All the answers can be found therein the document.";
assert_suggestion_result(test_sentence, Therein::default(), expected);
}

#[test]
fn there_upon() {
let test_sentence = "A decision was made there upon reviewing the data.";
let expected = "A decision was made thereupon reviewing the data.";
assert_suggestion_result(test_sentence, Thereupon::default(), expected);
}

#[test]
fn here_by() {
let test_sentence = "The contract is here by declared null and void.";
let expected = "The contract is hereby declared null and void.";
assert_suggestion_result(test_sentence, Hereby::default(), expected);
}

#[test]
fn here_under() {
let test_sentence = "All terms are set forth here under.";
let expected = "All terms are set forth hereunder.";
assert_suggestion_result(test_sentence, Hereunder::default(), expected);
}

#[test]
fn forth_with() {
let test_sentence = "Please reply forth with to our previous inquiry.";
let expected = "Please reply forthwith to our previous inquiry.";
assert_suggestion_result(test_sentence, Forthwith::default(), expected);
}

#[test]
fn in_so_far() {
let test_sentence = "This rule applies in so far as it covers all cases.";
let expected = "This rule applies insofar as it covers all cases.";
assert_suggestion_result(test_sentence, Insofar::default(), expected);
}

#[test]
fn where_upon() {
let test_sentence = "They acted where upon the circumstances allowed.";
let expected = "They acted whereupon the circumstances allowed.";
assert_suggestion_result(test_sentence, Whereupon::default(), expected);
}

#[test]
fn there_after() {
let test_sentence = "The system shutdown occurred there after the update.";
let expected = "The system shutdown occurred thereafter the update.";
assert_suggestion_result(test_sentence, Thereafter::default(), expected);
}

#[test]
fn down_right() {
let test_sentence = "His comment was down right insulting to everyone present.";
let expected = "His comment was downright insulting to everyone present.";
assert_suggestion_result(test_sentence, Downright::default(), expected);
}

#[test]
fn up_ward() {
let test_sentence = "The temperature moved up ward during the afternoon.";
let expected = "The temperature moved upward during the afternoon.";
assert_suggestion_result(test_sentence, Upward::default(), expected);
}

#[test]
fn hence_forth() {
let test_sentence = "All new policies apply hence forth immediately.";
let expected = "All new policies apply henceforth immediately.";
assert_suggestion_result(test_sentence, Henceforth::default(), expected);
}

#[test]
fn regard_less() {
let test_sentence = "The decision was made, regard less of the opposition.";
let expected = "The decision was made, regardless of the opposition.";
assert_suggestion_result(test_sentence, Regardless::default(), expected);
}
}
92 changes: 88 additions & 4 deletions harper-core/src/linting/lint_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@ use super::avoid_curses::AvoidCurses;
use super::boring_words::BoringWords;
use super::capitalize_personal_pronouns::CapitalizePersonalPronouns;
use super::closed_compounds::{
Altogether, Asleep, Bathroom, Facewash, Handheld, However, Intact, Itself, Likewise,
Misunderstand, Misunderstood, Misuse, Misused, Myself, Northeast, Northeastern, Overall,
Playground, Postpone, Proofread, Runway, Somehow, Therefore, Thumbnail, Tonight, Upholstery,
Upset, Worldwide,
Altogether, Anybody, Anyhow, Anytime, Anyway, Anywhere, Asleep, Backpack, Backplane, Bathroom,
Bitrate, Bitstream, Blockchain, Cupboard, Cyberattack, Cyberspace, Dashboard, Datacenter,
Datamining, Datascience, Desktop, Devops, Downright, Ecommerce, Evermore, Everyone, Everywhere,
Facewash, Fingerprint, Firewall, Firmware, Forever, Forthwith, Framework, Handheld, Headphone,
Headset, Henceforth, Hereafter, Hereby, Hereunder, However, Insofar, Instead, Intact, Into,
Itself, Keyboard, Laptop, Likewise, Microprocessor, Microservices, Middleware, Misunderstand,
Misunderstood, Misuse, Misused, Multicore, Multimedia, Multithreading, Myself, Nobody,
Nonetheless, Northeast, Northeastern, Notebook, Nothing, Notwithstanding, Nowhere, Opensource,
Otherwise, Overall, Overclocking, Overload, Overnight, Playground, Postpone, Proofread,
Regardless, Runway, Sitemap, Smartcard, Smartphone, Smartwatch, Somebody, Somehow, Somewhere,
Thereafter, Therefore, Therein, Thereupon, Thumbnail, Tonight, Touchpad, Touchscreen,
Underclock, Upholstery, Upset, Upward, Webcam, Websocket, Whereupon, Widespread, Worldwide,
};
use super::correct_number_suffix::CorrectNumberSuffix;
use super::despite_of::DespiteOf;
Expand Down Expand Up @@ -167,6 +175,82 @@ macro_rules! create_lint_group_config {
}

create_lint_group_config!(
Evermore => true,
Regardless => true,
Henceforth => true,
Upward => true,
Downright => true,
Thereafter => true,
Whereupon => true,
Insofar => true,
Forthwith => true,
Hereunder => true,
Hereby => true,
Thereupon => true,
Therein => true,
Otherwise => true,
Hereafter => true,
Nonetheless => true,
Anyhow => true,
Notwithstanding => true,
Widespread => true,
Fingerprint => true,
Websocket => true,
Cyberattack => true,
Datascience => true,
Datamining => true,
Ecommerce => true,
Multimedia => true,
Cyberspace => true,
Dashboard => true,
Microservices => true,
Multicore => true,
Multithreading => true,
Sitemap => true,
Firewall => true,
Bitstream => true,
Devops => true,
Opensource => true,
Blockchain => true,
Underclock => true,
Overload => true,
Bitrate => true,
Smartcard => true,
Backplane => true,
Overclocking => true,
Laptop => true,
Desktop => true,
Headphone => true,
Webcam => true,
Smartphone => true,
Datacenter => true,
Microprocessor => true,
Touchpad => true,
Framework => true,
Headset => true,
Touchscreen => true,
Smartwatch => true,
Firmware => true,
Middleware => true,
Somewhere => true,
Keyboard => true,
Cupboard => true,
Notebook => true,
Backpack => true,
Instead => true,
Overnight => true,
Everywhere => true,
Nowhere => true,
Anywhere => true,
Anytime => true,
Anyway => true,
Nothing => true,
Anybody => true,
Somebody => true,
Nobody => true,
Everyone => true,
Into => true,
Forever => true,
Proofread => true,
Upholstery => true,
Northeastern => true,
Expand Down
16 changes: 12 additions & 4 deletions harper-core/src/linting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,18 @@ pub use avoid_curses::AvoidCurses;
pub use boring_words::BoringWords;
pub use capitalize_personal_pronouns::CapitalizePersonalPronouns;
pub use closed_compounds::{
Altogether, Asleep, Bathroom, Facewash, Handheld, However, Intact, Itself, Likewise,
Misunderstand, Misunderstood, Misuse, Misused, Myself, Northeast, Northeastern, Overall,
Playground, Postpone, Proofread, Runway, Somehow, Therefore, Thumbnail, Tonight, Upholstery,
Upset, Worldwide,
Altogether, Anybody, Anyhow, Anytime, Anyway, Anywhere, Asleep, Backpack, Backplane, Bathroom,
Bitrate, Bitstream, Blockchain, Cupboard, Cyberattack, Cyberspace, Dashboard, Datacenter,
Datamining, Datascience, Desktop, Devops, Downright, Ecommerce, Evermore, Everyone, Everywhere,
Facewash, Fingerprint, Firewall, Firmware, Forever, Forthwith, Framework, Handheld, Headphone,
Headset, Henceforth, Hereafter, Hereby, Hereunder, However, Insofar, Instead, Intact, Into,
Itself, Keyboard, Laptop, Likewise, Microprocessor, Microservices, Middleware, Misunderstand,
Misunderstood, Misuse, Misused, Multicore, Multimedia, Multithreading, Myself, Nobody,
Nonetheless, Northeast, Northeastern, Notebook, Nothing, Notwithstanding, Nowhere, Opensource,
Otherwise, Overall, Overclocking, Overload, Overnight, Playground, Postpone, Proofread,
Regardless, Runway, Sitemap, Smartcard, Smartphone, Smartwatch, Somebody, Somehow, Somewhere,
Thereafter, Therefore, Therein, Thereupon, Thumbnail, Tonight, Touchpad, Touchscreen,
Underclock, Upholstery, Upset, Upward, Webcam, Websocket, Whereupon, Widespread, Worldwide,
};
pub use correct_number_suffix::CorrectNumberSuffix;
pub use currency_placement::CurrencyPlacement;
Expand Down