mirror of
https://github.com/Automattic/harper.git
synced 2025-12-05 19:26:55 -06:00
feat(obsidian): add button to disable rules from within popup
This commit is contained in:
@@ -131,77 +131,88 @@ export default class State {
|
||||
const text = view.state.doc.sliceString(-1);
|
||||
const chars = Array.from(text);
|
||||
|
||||
const lints = await this.harper.lint(text);
|
||||
const lints = await this.harper.organizedLints(text);
|
||||
|
||||
return lints.map((lint) => {
|
||||
const span = lint.span();
|
||||
return Object.entries(lints).flatMap(([linterName, lints]) =>
|
||||
lints.map((lint) => {
|
||||
const span = lint.span();
|
||||
|
||||
const actions = lint.suggestions().map((sug) => {
|
||||
return {
|
||||
name:
|
||||
sug.kind() == SuggestionKind.Replace
|
||||
? sug.get_replacement_text()
|
||||
: suggestionToLabel(sug),
|
||||
title: suggestionToLabel(sug),
|
||||
apply: (view) => {
|
||||
if (sug.kind() === SuggestionKind.Remove) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: span.start,
|
||||
to: span.end,
|
||||
insert: '',
|
||||
},
|
||||
});
|
||||
} else if (sug.kind() === SuggestionKind.Replace) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: span.start,
|
||||
to: span.end,
|
||||
insert: sug.get_replacement_text(),
|
||||
},
|
||||
});
|
||||
} else if (sug.kind() === SuggestionKind.InsertAfter) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: span.end,
|
||||
to: span.end,
|
||||
insert: sug.get_replacement_text(),
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
if (lint.lint_kind() === 'Spelling') {
|
||||
const word = lint.get_problem_text();
|
||||
|
||||
actions.push({
|
||||
name: '📖',
|
||||
title: `Add “${word}” to your dictionary`,
|
||||
apply: (_view) => {
|
||||
this.harper.importWords([word]);
|
||||
this.reinitialize();
|
||||
},
|
||||
const actions = lint.suggestions().map((sug) => {
|
||||
return {
|
||||
name:
|
||||
sug.kind() == SuggestionKind.Replace
|
||||
? sug.get_replacement_text()
|
||||
: suggestionToLabel(sug),
|
||||
title: suggestionToLabel(sug),
|
||||
apply: (view) => {
|
||||
if (sug.kind() === SuggestionKind.Remove) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: span.start,
|
||||
to: span.end,
|
||||
insert: '',
|
||||
},
|
||||
});
|
||||
} else if (sug.kind() === SuggestionKind.Replace) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: span.start,
|
||||
to: span.end,
|
||||
insert: sug.get_replacement_text(),
|
||||
},
|
||||
});
|
||||
} else if (sug.kind() === SuggestionKind.InsertAfter) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: span.end,
|
||||
to: span.end,
|
||||
insert: sug.get_replacement_text(),
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
from: span.start,
|
||||
to: span.end,
|
||||
severity: 'error',
|
||||
title: lint.lint_kind_pretty(),
|
||||
renderMessage: (_view) => {
|
||||
const node = document.createElement('template');
|
||||
node.innerHTML = lint.message_html();
|
||||
return node.content;
|
||||
},
|
||||
ignore: async () => {
|
||||
await this.ignoreLints(text, [lint]);
|
||||
},
|
||||
actions,
|
||||
};
|
||||
});
|
||||
if (lint.lint_kind() === 'Spelling') {
|
||||
const word = lint.get_problem_text();
|
||||
|
||||
actions.push({
|
||||
name: '📖',
|
||||
title: `Add “${word}” to your dictionary`,
|
||||
apply: (_view) => {
|
||||
this.harper.importWords([word]);
|
||||
this.reinitialize();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
from: span.start,
|
||||
to: span.end,
|
||||
source: linterName,
|
||||
severity: 'error',
|
||||
title: lint.lint_kind_pretty(),
|
||||
renderMessage: (_view) => {
|
||||
const node = document.createElement('template');
|
||||
node.innerHTML = lint.message_html();
|
||||
return node.content;
|
||||
},
|
||||
ignore: async () => {
|
||||
await this.ignoreLints(text, [lint]);
|
||||
},
|
||||
disable: async () => {
|
||||
const lintConfig = await this.harper.getLintConfig();
|
||||
lintConfig[linterName] = false;
|
||||
await this.harper.setLintConfig(lintConfig);
|
||||
|
||||
await this.reinitialize();
|
||||
},
|
||||
|
||||
actions,
|
||||
};
|
||||
}),
|
||||
);
|
||||
},
|
||||
{
|
||||
delay: this.delay,
|
||||
|
||||
@@ -52,6 +52,8 @@ export interface Diagnostic {
|
||||
actions?: readonly Action[];
|
||||
/// A callback for when the user selects to "ignore" the diagnostic.
|
||||
ignore?: () => void;
|
||||
/// A callback for when the user selects to "disable" the source of the diagnostic.
|
||||
disable?: () => void;
|
||||
}
|
||||
|
||||
/// An action associated with a diagnostic.
|
||||
@@ -428,21 +430,37 @@ function renderDiagnostic(view: EditorView, diagnostic: Diagnostic, inPanel: boo
|
||||
);
|
||||
}),
|
||||
),
|
||||
diagnostic.ignore &&
|
||||
elt(
|
||||
'div',
|
||||
{
|
||||
class: 'cm-diagnosticIgnore',
|
||||
onclick: (e) => {
|
||||
e.preventDefault();
|
||||
if (diagnostic.ignore) {
|
||||
diagnostic.ignore();
|
||||
}
|
||||
elt('div', { class: 'cm-diagnosticRow' }, [
|
||||
diagnostic.ignore &&
|
||||
elt(
|
||||
'div',
|
||||
{
|
||||
class: 'cm-diagnosticIgnore',
|
||||
onclick: (e) => {
|
||||
e.preventDefault();
|
||||
if (diagnostic.ignore) {
|
||||
diagnostic.ignore();
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
'Ignore Diagnostic',
|
||||
),
|
||||
diagnostic.source && elt('div', { class: 'cm-diagnosticSource' }, diagnostic.source),
|
||||
'Ignore Diagnostic',
|
||||
),
|
||||
diagnostic.disable &&
|
||||
elt(
|
||||
'div',
|
||||
{
|
||||
class: 'cm-diagnosticDisable',
|
||||
onclick: (e) => {
|
||||
e.preventDefault();
|
||||
if (diagnostic.disable) {
|
||||
diagnostic.disable();
|
||||
}
|
||||
},
|
||||
title: `Disable ${diagnostic.source}`,
|
||||
},
|
||||
'Disable Rule',
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -514,6 +532,12 @@ const baseTheme = EditorView.baseTheme({
|
||||
gap: 'var(--size-4-2)',
|
||||
},
|
||||
|
||||
'.cm-diagnosticRow': {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
|
||||
'.cm-diagnosticAction': {
|
||||
font: 'inherit',
|
||||
border: 'none',
|
||||
@@ -553,6 +577,15 @@ const baseTheme = EditorView.baseTheme({
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
|
||||
'.cm-diagnosticDisable': {
|
||||
padding: 'var(--size-4-1) 0px',
|
||||
fontSize: 'var(--font-ui-small)',
|
||||
},
|
||||
|
||||
'.cm-diagnosticDisable:hover': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
|
||||
'.cm-lintRange': {
|
||||
backgroundPosition: 'left bottom',
|
||||
backgroundRepeat: 'repeat-x',
|
||||
|
||||
Reference in New Issue
Block a user