mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-25 10:51:26 +01:00
JSON linting
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
}
|
||||
|
||||
/* Matching bracket */
|
||||
|
||||
.cm-matchingBracket {
|
||||
@apply bg-transparent border-b border-b-text-subtle;
|
||||
}
|
||||
@@ -76,6 +77,16 @@
|
||||
.cm-gutterElement {
|
||||
@apply cursor-default;
|
||||
}
|
||||
|
||||
.cm-lint-marker {
|
||||
@apply cursor-default opacity-80 hover:opacity-100 transition-opacity;
|
||||
@apply rounded-full w-[0.9em] h-[0.9em];
|
||||
content: '';
|
||||
|
||||
&.cm-lint-marker-error {
|
||||
@apply bg-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.template-tag {
|
||||
@@ -110,6 +121,7 @@
|
||||
@apply font-mono text-xs;
|
||||
|
||||
/* Hide scrollbars */
|
||||
|
||||
&::-webkit-scrollbar-corner,
|
||||
&::-webkit-scrollbar {
|
||||
@apply hidden !important;
|
||||
@@ -202,7 +214,7 @@
|
||||
}
|
||||
|
||||
.cm-editor .cm-activeLineGutter {
|
||||
@apply bg-transparent;
|
||||
@apply bg-transparent text-text-subtle;
|
||||
}
|
||||
|
||||
/* Cursor and mouse cursor for readonly mode */
|
||||
@@ -226,17 +238,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
.cm-tooltip-lint {
|
||||
@apply font-mono text-editor rounded overflow-hidden bg-surface-highlight border border-border shadow !important;
|
||||
|
||||
.cm-diagnostic-error {
|
||||
@apply border-l-danger px-4 py-2;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-lintPoint {
|
||||
&.cm-lintPoint-error {
|
||||
&::after {
|
||||
@apply border-b-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cm-tooltip.cm-tooltip-hover {
|
||||
@apply shadow-lg bg-surface rounded text-text-subtle border border-border-subtle z-50 pointer-events-auto text-sm;
|
||||
@apply p-1.5;
|
||||
|
||||
/* Style the tooltip for popping up "open in browser" and other stuff */
|
||||
|
||||
a, button {
|
||||
@apply text-text hover:bg-surface-highlight w-full h-sm flex items-center px-2 rounded;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply cursor-default !important;
|
||||
|
||||
&::after {
|
||||
@apply text-text bg-text h-3 w-3 ml-1;
|
||||
content: '';
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
indentOnInput,
|
||||
syntaxHighlighting,
|
||||
} from '@codemirror/language';
|
||||
import { lintKeymap } from '@codemirror/lint';
|
||||
import { linter, lintGutter, lintKeymap } from '@codemirror/lint';
|
||||
|
||||
import { search, searchKeymap } from '@codemirror/search';
|
||||
import type { Extension } from '@codemirror/state';
|
||||
@@ -45,6 +45,7 @@ import { renderMarkdown } from '../../../lib/markdown';
|
||||
import { pluralizeCount } from '../../../lib/pluralize';
|
||||
import { showGraphQLDocExplorerAtom } from '../../graphql/graphqlAtoms';
|
||||
import type { EditorProps } from './Editor';
|
||||
import { jsonParseLinter } from './json-lint';
|
||||
import { pairs } from './pairs/extension';
|
||||
import { text } from './text/extension';
|
||||
import type { TwigCompletionOption } from './twig/completion';
|
||||
@@ -153,6 +154,10 @@ export function getLanguageExtension({
|
||||
];
|
||||
}
|
||||
|
||||
if (language === 'json') {
|
||||
extraExtensions.push(linter(jsonParseLinter()), lintGutter());
|
||||
}
|
||||
|
||||
const maybeBase = language ? syntaxExtensions[language] : null;
|
||||
const base = typeof maybeBase === 'function' ? maybeBase() : null;
|
||||
if (base == null) {
|
||||
|
||||
36
src-web/components/core/Editor/json-lint.ts
Normal file
36
src-web/components/core/Editor/json-lint.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { Diagnostic } from '@codemirror/lint';
|
||||
import type { EditorView } from '@codemirror/view';
|
||||
import { parse as jsonLintParse } from '@prantlf/jsonlint';
|
||||
|
||||
const TEMPLATE_SYNTAX_REGEX = /\$\{\[[\s\S]*?]}/g;
|
||||
|
||||
export function jsonParseLinter() {
|
||||
return (view: EditorView): Diagnostic[] => {
|
||||
try {
|
||||
const doc = view.state.doc.toString();
|
||||
// We need lint to not break on stuff like {"foo:" ${[ ... ]}} so we'll replace all template
|
||||
// syntax with repeating `1` characters, so it's valid JSON and the position is still correct.
|
||||
const escapedDoc = doc.replace(TEMPLATE_SYNTAX_REGEX, '1');
|
||||
jsonLintParse(escapedDoc);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
if (!('location' in err)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// const line = location?.start?.line;
|
||||
// const column = location?.start?.column;
|
||||
if (err.location.start.offset) {
|
||||
return [
|
||||
{
|
||||
from: err.location.start.offset,
|
||||
to: err.location.start.offset,
|
||||
severity: 'error',
|
||||
message: err.message,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user