Skip to content

Commit 5f21fc8

Browse files
Merge pull request #513 from Automattic/rust-doc-updates
`harper-core` Documentation Updates
2 parents e77086b + 2208d52 commit 5f21fc8

File tree

11 files changed

+96
-7
lines changed

11 files changed

+96
-7
lines changed

harper-core/src/char_string.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use smallvec::SmallVec;
44
/// Most English words are fewer than 12 characters.
55
pub type CharString = SmallVec<[char; 12]>;
66

7+
/// Extensions to character sequences that make them easier to wrangle.
78
pub trait CharStringExt {
89
fn to_lower(&self) -> CharString;
910
fn to_string(&self) -> String;

harper-core/src/linting/lint.rs

+16
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@ use serde::{Deserialize, Serialize};
55

66
use crate::Span;
77

8+
/// An error found in text.
89
#[derive(Debug, Clone, Serialize, Deserialize)]
910
pub struct Lint {
11+
/// The location in the source text the error lies.
12+
/// Important for automatic lint resolution through [`Self::suggestions`].
1013
pub span: Span,
14+
/// The general category the lint belongs to.
15+
/// Mostly used for UI elements in integrations.
1116
pub lint_kind: LintKind,
17+
/// A list of zero or more suggested edits that would resolve the underlying problem.
18+
/// See [`Suggestion`].
1219
pub suggestions: Vec<Suggestion>,
20+
/// A message to be displayed to the user describing the specific error found.
21+
///
22+
/// You may use the [`format`] macro to generate more complex messages.
1323
pub message: String,
1424
/// A numerical value for the importance of a lint.
1525
/// Lower = more important.
@@ -28,6 +38,9 @@ impl Default for Lint {
2838
}
2939
}
3040

41+
/// The general category a [`Lint`] falls into.
42+
/// There's no reason not to add a new item here if you are adding a new rule that doesn't fit
43+
/// the existing categories.
3144
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Is, Default)]
3245
pub enum LintKind {
3346
Spelling,
@@ -60,11 +73,14 @@ impl Display for LintKind {
6073
}
6174
}
6275

76+
/// A suggested edit that could resolve a [`Lint`].
6377
#[derive(Debug, Clone, Serialize, Deserialize, Is, PartialEq, Eq)]
6478
pub enum Suggestion {
79+
/// Replace the offending text with a specific character sequence.
6580
ReplaceWith(Vec<char>),
6681
/// Insert the provided characters _after_ the offending text.
6782
InsertAfter(Vec<char>),
83+
/// Remove the offending text.
6884
Remove,
6985
}
7086

harper-core/src/linting/lint_group.rs

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ macro_rules! create_lint_group_config {
5656
}
5757
}
5858

59+
/// A collection of all officially supported
5960
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
6061
pub struct LintGroupConfig {
6162
$(

harper-core/src/linting/mod.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//! Frameworks and rules that locate errors in text.
2+
//!
3+
//! See the [`Linter`] trait and the [documentation for authoring a rule](https://writewithharper.com/docs/contributors/author-a-rule) for more information.
4+
15
mod an_a;
26
mod avoid_curses;
37
mod boring_words;
@@ -73,15 +77,33 @@ pub use wrong_quotes::WrongQuotes;
7377

7478
use crate::Document;
7579

80+
/// A __stateless__ rule that searches documents for grammatical errors.
81+
///
82+
/// Commonly implemented via [`PatternLinter`].
83+
///
84+
/// See also: [`LintGroup`].
7685
#[cfg(not(feature = "concurrent"))]
7786
pub trait Linter {
87+
/// Analyzes a document and produces zero or more [`Lint`]s.
88+
/// We pass `self` mutably for caching purposes.
7889
fn lint(&mut self, document: &Document) -> Vec<Lint>;
90+
/// A user-facing description of what kinds of grammatical errors this rule looks for.
91+
/// It is usually shown in settings menus.
7992
fn description(&self) -> &str;
8093
}
8194

95+
/// A __stateless__ rule that searches documents for grammatical errors.
96+
///
97+
/// Commonly implemented via [`PatternLinter`].
98+
///
99+
/// See also: [`LintGroup`].
82100
#[cfg(feature = "concurrent")]
83101
pub trait Linter: Send + Sync {
102+
/// Analyzes a document and produces zero or more [`Lint`]s.
103+
/// We pass `self` mutably for caching purposes.
84104
fn lint(&mut self, document: &Document) -> Vec<Lint>;
105+
/// A user-facing description of what kinds of grammatical errors this rule looks for.
106+
/// It is usually shown in settings menus.
85107
fn description(&self) -> &str;
86108
}
87109

harper-core/src/linting/pattern_linter.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,35 @@ use super::{Lint, Linter};
22
use crate::patterns::Pattern;
33
use crate::{Token, TokenStringExt};
44

5+
/// A trait that searches for [`Pattern`]s in [`Document`](crate::Document)s.
6+
///
7+
/// Makes use of [`TokenStringExt::iter_chunks`] to avoid matching across sentence or clause
8+
/// boundaries.
59
#[cfg(not(feature = "concurrent"))]
610
pub trait PatternLinter {
711
/// A simple getter for the pattern to be searched for.
812
fn pattern(&self) -> &dyn Pattern;
13+
/// If any portions of a [`Document`](crate::Document) match [`Self::pattern`], they are passed through [`PatternLinter::match_to_lint`] to be
14+
/// transformed into a [`Lint`] for editor consumption.
915
fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Lint;
10-
fn description<'a>(&'a self) -> &'a str;
16+
/// A user-facing description of what kinds of grammatical errors this rule looks for.
17+
/// It is usually shown in settings menus.
18+
fn description(&self) -> &str;
1119
}
1220

21+
/// A trait that searches for [`Pattern`]s in [`Document`](crate::Document)s.
22+
///
23+
/// Makes use of [`TokenStringExt::iter_chunks`] to avoid matching across sentence or clause
24+
/// boundaries.
1325
#[cfg(feature = "concurrent")]
1426
pub trait PatternLinter: Send + Sync {
1527
/// A simple getter for the pattern to be searched for.
1628
fn pattern(&self) -> &dyn Pattern;
29+
/// If any portions of a [`Document`](crate::Document) match [`Self::pattern`], they are passed through [`PatternLinter::match_to_lint`] to be
30+
/// transformed into a [`Lint`] for editor consumption.
1731
fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Lint;
32+
/// A user-facing description of what kinds of grammatical errors this rule looks for.
33+
/// It is usually shown in settings menus.
1834
fn description(&self) -> &str;
1935
}
2036

harper-core/src/patterns/is_not_title_case.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use crate::{make_title_case, Dictionary, Token, TokenStringExt};
22

33
use super::Pattern;
44

5-
/// Will match full length of wrapped pattern __only if the matched
6-
/// text is not already title case__.
5+
/// Will match full length of wrapped pattern only if the matched
6+
/// text is not already title case.
77
pub struct IsNotTitleCase<D: Dictionary> {
88
inner: Box<dyn Pattern>,
99
dict: D,

harper-core/src/patterns/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
//! [`Pattern`]s are one of the more powerful ways to query text inside Harper, especially for beginners.
2+
//!
3+
//! Through the [`PatternLinter`](crate::linting::PatternLinter) trait, they make it much easier to
4+
//! build Harper [rules](crate::linting::Linter).
5+
//!
6+
//! See the page about [`SequencePattern`] for a concrete example of their use.
7+
18
use std::collections::VecDeque;
29

310
use crate::{Document, Span, Token, VecExt};
@@ -127,7 +134,7 @@ where
127134
}
128135
}
129136

130-
trait DocPattern {
137+
pub trait DocPattern {
131138
fn find_all_matches_in_doc(&self, document: &Document) -> Vec<Span>;
132139
}
133140

harper-core/src/patterns/sequence_pattern.rs

+21
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@ use super::{NounPhrase, Pattern, RepeatingPattern, WordSet};
66
use crate::{CharStringExt, Lrc, Token, TokenKind};
77

88
/// A pattern that checks that a sequence of other patterns match.
9+
/// There are specific extension methods available, but you can also use [`Self::then`] to add
10+
/// arbitrary patterns.
11+
///
12+
/// ## Example
13+
///
14+
/// Let's say we wanted to locate places in a [`Document`] where an article is followed by a noun.
15+
/// We can do that with a `SequencePattern`.
16+
///
17+
/// ```rust
18+
/// use harper_core::patterns::{SequencePattern, DocPattern};
19+
/// use harper_core::{Document, Span};
20+
///
21+
/// let document = Document::new_markdown_default_curated("This is a test.");
22+
///
23+
/// let pattern = SequencePattern::default().then_article().then_whitespace().then_noun();
24+
/// let matches = pattern.find_all_matches_in_doc(&document);
25+
///
26+
/// // The pattern found that the tokens at indexes 4, 5, and 6 fit the criteria.
27+
/// assert_eq!(matches, vec![Span::new(4, 7)]);
28+
/// ```
929
#[derive(Default)]
1030
pub struct SequencePattern {
1131
token_patterns: Vec<Box<dyn Pattern>>,
@@ -60,6 +80,7 @@ impl SequencePattern {
6080
gen_then_from_is!(adjective);
6181
gen_then_from_is!(apostrophe);
6282
gen_then_from_is!(hyphen);
83+
gen_then_from_is!(article);
6384

6485
pub fn then_word_set(self, set: WordSet) -> Self {
6586
self.then(Box::new(set))

harper-core/src/spell/dictionary.rs

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ use blanket::blanket;
33
use super::FuzzyMatchResult;
44
use crate::WordMetadata;
55

6+
/// An in-memory database that contains everything necessary to parse and analyze English text.
7+
///
8+
/// See also: [`FstDictionary`](super::FstDictionary) and
9+
/// [`FullDictionary`](super::FullDictionary).
610
#[blanket(derive(Arc))]
711
pub trait Dictionary: Send + Sync {
812
/// Check if the dictionary contains a given word.

harper-core/src/token.rs

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ macro_rules! create_fns_for {
7171
};
7272
}
7373

74+
/// Extension methods for [`Token`] sequences that make them easier to wrangle and query.
7475
pub trait TokenStringExt {
7576
fn first_sentence_word(&self) -> Option<Token>;
7677
fn first_non_whitespace(&self) -> Option<Token>;

packages/web/src/routes/docs/contributors/author-a-rule/+page.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -150,18 +150,18 @@ If you need any help writing or debugging rules, don't be afraid to contact the
150150
### Using Visual Studio Code
151151

152152
First make sure you have [the extension installed from the marketplace](https://marketplace.visualstudio.com/items?itemName=elijah-potter.harper).
153-
Then, can configure the path of the `harper-ls` binary the Visual Studio Code extension uses in settings.
153+
Then, configure the path of the `harper-ls` binary the Visual Studio Code extension uses in the settings page.
154154
Set it to `<harper repo>/target/release/harper-ls`.
155155

156156
![How to change the `harper-ls` path](/images/vscode_harper_path.webp)
157157

158-
Now every time you want to test a change, you'll have to recompile `harper-ls` and reload Visual Studio Code using `Developer: Reload Window`.
158+
Every time you want to test a change, you'll have to recompile `harper-ls` and reload Visual Studio Code with the `Developer: Reload Window` command in the command palette.
159159

160160
```bash
161161
cargo build --release # Run in the monorepo to compile `harper-ls`.
162162
```
163163

164164
## Elevate Your Pull Request
165165

166-
Once you're satisfied with your rule, you can go ahead and elevate your pull requests to mark it as "ready for review."
166+
Once you're satisfied with your rule, you can go ahead and elevate your pull request to mark it as "ready for review."
167167
At that point, a maintainer on the Harper team take a look at it and (hopefully) merge it.

0 commit comments

Comments
 (0)