Skip to content

Commit 4da93ac

Browse files
committed
feat(obsidian): can now ignore suggestions
1 parent 12bfe03 commit 4da93ac

File tree

8 files changed

+80
-4
lines changed

8 files changed

+80
-4
lines changed

harper-wasm/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ impl Linter {
174174

175175
Ok(())
176176
}
177+
178+
pub fn clear_ignored_lints(&mut self) {
179+
self.ignored_lints = IgnoredLints::new();
180+
}
177181
}
178182

179183
impl Default for Linter {

packages/harper.js/src/Linter.ts

+3
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,7 @@ export default interface Linter {
6060
/** Import ignored lints from a JSON list to the linter.
6161
* This function appends to the existing lints, if any. */
6262
importIgnoredLints(json: string): Promise<void>;
63+
64+
/** Clear records of all previously ignored lints. */
65+
clearIgnoredLints(): Promise<void>;
6366
}

packages/harper.js/src/LocalLinter.ts

+6
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,10 @@ export default class LocalLinter implements Linter {
115115

116116
return this.inner!.import_ignored_lints(json);
117117
}
118+
119+
async clearIgnoredLints(): Promise<void> {
120+
await this.initialize();
121+
122+
return this.inner!.clear_ignored_lints();
123+
}
118124
}

packages/harper.js/src/WorkerLinter/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ export default class WorkerLinter implements Linter {
125125
return this.rpc('importIgnoredLints', [json]);
126126
}
127127

128+
async clearIgnoredLints(): Promise<void> {
129+
return this.rpc('clearIgnoredLints', []);
130+
}
131+
128132
/** Run a procedure on the remote worker. */
129133
private async rpc(procName: string, args: any[]): Promise<any> {
130134
const promise = new Promise((resolve, reject) => {

packages/harper.js/vite.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export default defineConfig({
5555
test: {
5656
browser: {
5757
provider: 'playwright',
58-
enabled: true
58+
enabled: true,
59+
headless: true
5960
}
6061
},
6162
assetsInclude: ['**/*.wasm']

packages/obsidian-plugin/src/HarperSettingTab.ts

+10
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ export class HarperSettingTab extends PluginSettingTab {
5656
})
5757
);
5858
}
59+
60+
new Setting(containerEl).setName('The Danger Zone').addButton((button) => {
61+
button
62+
.setButtonText('Forget Ignored Suggestions')
63+
.onClick(() => {
64+
this.settings.ignoredLints = undefined;
65+
this.plugin.initializeFromSettings(this.settings);
66+
})
67+
.setWarning();
68+
});
5969
}
6070
}
6171

packages/obsidian-plugin/src/index.ts

+24-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function suggestionToLabel(sug: Suggestion) {
1717
}
1818

1919
export type Settings = {
20+
ignoredLints?: string;
2021
useWebWorker: boolean;
2122
lintSettings: LintConfig;
2223
};
@@ -36,10 +37,20 @@ export default class HarperPlugin extends Plugin {
3637
settings = { useWebWorker: true, lintSettings: {} };
3738
}
3839

39-
if (settings.useWebWorker) {
40-
this.harper = new WorkerLinter();
40+
const oldSettings = await this.getSettings();
41+
42+
if (settings.useWebWorker != oldSettings.useWebWorker) {
43+
if (settings.useWebWorker) {
44+
this.harper = new WorkerLinter();
45+
} else {
46+
this.harper = new LocalLinter();
47+
}
4148
} else {
42-
this.harper = new LocalLinter();
49+
await this.harper.clearIgnoredLints();
50+
}
51+
52+
if (settings.ignoredLints !== undefined) {
53+
await this.harper.importIgnoredLints(settings.ignoredLints);
4354
}
4455

4556
await this.harper.setLintConfig(settings.lintSettings);
@@ -54,10 +65,16 @@ export default class HarperPlugin extends Plugin {
5465
await this.saveData(settings);
5566
}
5667

68+
public async reinitialize() {
69+
const settings = await this.getSettings();
70+
await this.initializeFromSettings(settings);
71+
}
72+
5773
public async getSettings(): Promise<Settings> {
5874
const usingWebWorker = this.harper instanceof WorkerLinter;
5975

6076
return {
77+
ignoredLints: await this.harper.exportIgnoredLints(),
6178
useWebWorker: usingWebWorker,
6279
lintSettings: await this.harper.getLintConfig()
6380
};
@@ -157,6 +174,10 @@ export default class HarperPlugin extends Plugin {
157174
severity: 'error',
158175
title: lint.lint_kind(),
159176
message: lint.message(),
177+
ignore: async () => {
178+
await this.harper.ignoreLint(lint);
179+
await this.reinitialize();
180+
},
160181
actions: lint.suggestions().map((sug) => {
161182
return {
162183
name: suggestionToLabel(sug),

packages/obsidian-plugin/src/lint.ts

+27
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
RangeSet
2222
} from '@codemirror/state';
2323
import elt from 'crelt';
24+
import { Lint } from 'harper.js';
2425

2526
type Severity = 'hint' | 'info' | 'warning' | 'error';
2627

@@ -50,6 +51,8 @@ export interface Diagnostic {
5051
/// An optional array of actions that can be taken on this
5152
/// diagnostic.
5253
actions?: readonly Action[];
54+
/// A callback for when the user selects to "ignore" the diagnostic.
55+
ignore?: () => void;
5356
}
5457

5558
/// An action associated with a diagnostic.
@@ -420,6 +423,20 @@ function renderDiagnostic(view: EditorView, diagnostic: Diagnostic, inPanel: boo
420423
nameElt
421424
);
422425
}),
426+
diagnostic.ignore &&
427+
elt(
428+
'div',
429+
{
430+
class: 'cm-diagnosticIgnore',
431+
onclick: (e) => {
432+
e.preventDefault();
433+
if (diagnostic.ignore) {
434+
diagnostic.ignore();
435+
}
436+
}
437+
},
438+
'Ignore Diagnostic'
439+
),
423440
diagnostic.source && elt('div', { class: 'cm-diagnosticSource' }, diagnostic.source)
424441
);
425442
}
@@ -500,6 +517,16 @@ const baseTheme = EditorView.baseTheme({
500517
opacity: 0.7
501518
},
502519

520+
'.cm-diagnosticIgnore': {
521+
color: 'black',
522+
padding: 'var(--size-4-1) 0px',
523+
fontSize: 'var(--font-ui-small)'
524+
},
525+
526+
'.cm-diagnosticIgnore:hover': {
527+
textDecoration: 'underline'
528+
},
529+
503530
'.cm-lintRange': {
504531
backgroundPosition: 'left bottom',
505532
backgroundRepeat: 'repeat-x',

0 commit comments

Comments
 (0)