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!