I have an editor component that I would like to modify to have custom variable linting for handlebars. Namely, if a variable is added to the handlebars template that is not in the known list, show an error. However, I’m not able to trigger linting at all on my component (have a test function that doesn’t do anything currently). I’m using syntax that seems identical to what I’ve seen in other examples, but I haven’t been able to figure out what configuration I’m missing to have my linting function (testLinter) trigger. This is true regardless of the preset language, but my end goal is to have the custom linting function be for handlebars. Below is the setup code for the component:
import { CodeDisplay, CodeDisplayProps } from './CodeDisplay';
import { javascript } from '@codemirror/lang-javascript';
import { json } from '@codemirror/lang-json';
import { markdown } from '@codemirror/lang-markdown';
import { python } from '@codemirror/lang-python';
import { foldGutter } from '@codemirror/language';
import { Diagnostic, linter, LintSource } from '@codemirror/lint';
import { EditorState, Extension } from '@codemirror/state';
import { handlebarsLanguage } from '@gentrace/codemirror-lang-handlebars';
import CodeMirror, { ReactCodeMirrorProps } from '@uiw/react-codemirror';
import { EditorView } from 'codemirror';
import { KeyboardEventHandler, useCallback } from 'react';
import { monoFontFamily } from '~/pages/_app';
import { styled } from '~/stitches.config';
import { githubDarkModified, handlebarsTheme } from '~/utils/utils';
export type CodeEditorProps = Pick<
ReactCodeMirrorProps,
| 'extensions'
| 'basicSetup'
| 'autoFocus'
| 'onChange'
| 'onBlur'
| 'readOnly'
| 'onCreateEditor'
> & { forceBorder?: boolean };
const presetExtensions: Record<CodeDisplayProps['preset'], Extension[]> = {
handlebars: [handlebarsLanguage],
javascript: [javascript({ jsx: true })],
json: [json()],
markdown: [markdown()],
plain: [],
python: [python()],
typescript: [javascript({ jsx: true, typescript: true })],
};
const presetThemes: Partial<Record<CodeDisplayProps['preset'], Extension>> = {
handlebars: handlebarsTheme,
};
export const testLinter: LintSource = (view) => {
// This is never called
console.log('test linter');
const diagnostics: Diagnostic[] = [];
diagnostics.push({
from: 0,
message: 'test',
severity: 'error',
to: 1,
});
return diagnostics;
};
export const CodeEditor: CodeDisplay<CodeEditorProps> = ({
placeholder,
preset,
basicSetup = {},
extensions = [],
readOnly = false,
forceBorder = false,
style,
...rest
}) => {
const languageExtensions = presetExtensions[preset];
const compoundExtensions = [
...extensions,
...languageExtensions,
readOnly
? [EditorState.readOnly.of(true), EditorView.lineWrapping]
: [EditorView.lineWrapping],
linter(testLinter),
];
const overrideBasicSetup = {
...(typeof basicSetup === 'object' ? basicSetup : {}),
highlightActiveLine: false,
// We don't want the default fold gutter since we're overriding it
foldGutter: false,
};
if (readOnly) {
overrideBasicSetup.highlightActiveLineGutter = false;
}
const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = useCallback(
(event) => {
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
event.stopPropagation();
event.preventDefault();
}
},
[],
);
return (
<CodeMirror
style={{
width: '100%',
fontFamily: monoFontFamily,
...style,
}}
placeholder={placeholder}
readOnly={readOnly}
basicSetup={overrideBasicSetup}
extensions={compoundExtensions}
theme={presetThemes[preset] ?? githubDarkModified}
{...rest}
/>
);
};
Appreciate any help!