1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-02 12:47:41 +02:00

Mobile: Improve syntax highlighting on mobile beta editor (#6684)

This commit is contained in:
Henry Heino 2022-07-28 09:01:34 -07:00 committed by GitHub
parent b32a341700
commit fb372723a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 626 additions and 4 deletions

View File

@ -856,12 +856,18 @@ packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
@ -883,6 +889,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
packages/app-mobile/components/screens/encryption-config.d.ts
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/encryption-config.js.map
packages/app-mobile/gulpfile.d.ts
packages/app-mobile/gulpfile.js
packages/app-mobile/gulpfile.js.map
packages/app-mobile/root.d.ts
packages/app-mobile/root.js
packages/app-mobile/root.js.map

9
.gitignore vendored
View File

@ -846,12 +846,18 @@ packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
@ -873,6 +879,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
packages/app-mobile/components/screens/encryption-config.d.ts
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/encryption-config.js.map
packages/app-mobile/gulpfile.d.ts
packages/app-mobile/gulpfile.js
packages/app-mobile/gulpfile.js.map
packages/app-mobile/root.d.ts
packages/app-mobile/root.js
packages/app-mobile/root.js.map

View File

@ -10,6 +10,7 @@
// from NoteEditor.tsx.
import createTheme from './theme';
import decoratorExtension from './decoratorExtension';
import { EditorState } from '@codemirror/state';
import { markdown } from '@codemirror/lang-markdown';
@ -23,6 +24,7 @@ import { searchKeymap } from '@codemirror/search';
import { historyKeymap, defaultKeymap } from '@codemirror/commands';
import { MarkdownMathExtension } from './markdownMathParser';
import { GFM as GitHubFlavoredMarkdownExtension } from '@lezer/markdown';
import syntaxHighlightingLanguages from './syntaxHighlightingLanguages';
interface CodeMirrorResult {
editor: EditorView;
@ -76,6 +78,7 @@ export function initCodeMirror(parentElement: any, initialText: string, theme: a
MarkdownMathExtension,
GitHubFlavoredMarkdownExtension,
],
codeLanguages: syntaxHighlightingLanguages,
}),
...createTheme(theme),
history(),
@ -85,6 +88,7 @@ export function initCodeMirror(parentElement: any, initialText: string, theme: a
highlightSelectionMatches(),
indentOnInput(),
decoratorExtension,
EditorView.lineWrapping,
EditorView.contentAttributes.of({ autocapitalize: 'sentence' }),
EditorView.updateListener.of((viewUpdate: ViewUpdate) => {

View File

@ -0,0 +1,170 @@
//
// Exports an editor plugin that creates multi-line decorations based on the
// editor's syntax tree (assumes markdown).
//
// For more about creating decorations, see https://codemirror.net/examples/zebra/
//
import { Decoration, EditorView } from '@codemirror/view';
import { ViewPlugin, DecorationSet, ViewUpdate } from '@codemirror/view';
import { ensureSyntaxTree } from '@codemirror/language';
import { RangeSetBuilder } from '@codemirror/state';
const regionStartDecoration = Decoration.line({
attributes: { class: 'cm-regionFirstLine' },
});
const regionStopDecoration = Decoration.line({
attributes: { class: 'cm-regionLastLine' },
});
const codeBlockDecoration = Decoration.line({
attributes: { class: 'cm-codeBlock', spellcheck: 'false' },
});
const inlineCodeDecoration = Decoration.mark({
attributes: { class: 'cm-inlineCode', spellcheck: 'false' },
});
const mathBlockDecoration = Decoration.line({
attributes: { class: 'cm-mathBlock', spellcheck: 'false' },
});
const inlineMathDecoration = Decoration.mark({
attributes: { class: 'cm-inlineMath', spellcheck: 'false' },
});
const urlDecoration = Decoration.mark({
attributes: { class: 'cm-url', spellcheck: 'false' },
});
const blockQuoteDecoration = Decoration.line({
attributes: { class: 'cm-blockQuote' },
});
const headerLineDecoration = Decoration.line({
attributes: { class: 'cm-headerLine' },
});
type DecorationDescription = { pos: number; length?: number; decoration: Decoration };
// Returns a set of [Decoration]s, associated with block syntax groups that require
// full-line styling.
const computeDecorations = (view: EditorView) => {
const decorations: DecorationDescription[] = [];
// Add a decoration to all lines between the document position [from] up to
// and includeing the position [to].
const addDecorationToLines = (from: number, to: number, decoration: Decoration) => {
let pos = from;
while (pos <= to) {
const line = view.state.doc.lineAt(pos);
decorations.push({
pos: line.from,
decoration,
});
// Move to the next line
pos = line.to + 1;
}
};
const addDecorationToRange = (from: number, to: number, decoration: Decoration) => {
decorations.push({
pos: from,
length: to - from,
decoration,
});
};
for (const { from, to } of view.visibleRanges) {
ensureSyntaxTree(
view.state,
to
)?.iterate({
from, to,
enter: node => {
let blockDecorated = false;
// Compute the visible region of the node.
const viewFrom = Math.max(from, node.from);
const viewTo = Math.min(to, node.to);
switch (node.name) {
case 'FencedCode':
case 'CodeBlock':
addDecorationToLines(viewFrom, viewTo, codeBlockDecoration);
blockDecorated = true;
break;
case 'BlockMath':
addDecorationToLines(viewFrom, viewTo, mathBlockDecoration);
blockDecorated = true;
break;
case 'Blockquote':
addDecorationToLines(viewFrom, viewTo, blockQuoteDecoration);
blockDecorated = true;
break;
case 'InlineMath':
addDecorationToRange(viewFrom, viewTo, inlineMathDecoration);
break;
case 'InlineCode':
addDecorationToRange(viewFrom, viewTo, inlineCodeDecoration);
break;
case 'URL':
addDecorationToRange(viewFrom, viewTo, urlDecoration);
break;
case 'SetextHeading1':
case 'SetextHeading2':
case 'ATXHeading1':
case 'ATXHeading2':
case 'ATXHeading3':
case 'ATXHeading4':
case 'ATXHeading5':
case 'ATXHeading6':
addDecorationToLines(viewFrom, viewTo, headerLineDecoration);
break;
}
// Only block decorations will have differing first and last lines
if (blockDecorated) {
// Allow different styles for the first, last lines in a block.
if (viewFrom == node.from) {
addDecorationToLines(viewFrom, viewFrom, regionStartDecoration);
}
if (viewTo == node.to) {
addDecorationToLines(viewTo, viewTo, regionStopDecoration);
}
}
},
});
}
decorations.sort((a, b) => a.pos - b.pos);
// Items need to be added to a RangeSetBuilder in ascending order
const decorationBuilder = new RangeSetBuilder<Decoration>();
for (const { pos, length, decoration } of decorations) {
// Null length => entire line
decorationBuilder.add(pos, pos + (length ?? 0), decoration);
}
return decorationBuilder.finish();
};
const decoratorExtension = ViewPlugin.fromClass(class {
public decorations: DecorationSet;
public constructor(view: EditorView) {
this.decorations = computeDecorations(view);
}
public update(viewUpdate: ViewUpdate) {
if (viewUpdate.docChanged || viewUpdate.viewportChanged) {
this.decorations = computeDecorations(viewUpdate.view);
}
}
}, {
decorations: pluginVal => pluginVal.decorations,
});
export default decoratorExtension;

View File

@ -0,0 +1,236 @@
//
// Exports a list of languages that can be used in fenced code blocks.
//
import { LanguageDescription, LanguageSupport, StreamParser } from '@codemirror/language';
import { StreamLanguage } from '@codemirror/language';
import { python } from '@codemirror/legacy-modes/mode/python';
import { c, dart } from '@codemirror/legacy-modes/mode/clike';
import { lua } from '@codemirror/legacy-modes/mode/lua';
import { r } from '@codemirror/legacy-modes/mode/r';
import { ruby } from '@codemirror/legacy-modes/mode/ruby';
import { swift } from '@codemirror/legacy-modes/mode/swift';
import { go } from '@codemirror/legacy-modes/mode/go';
import { vb } from '@codemirror/legacy-modes/mode/vb';
import { vbScript } from '@codemirror/legacy-modes/mode/vbscript';
import { css } from '@codemirror/legacy-modes/mode/css';
import { stex } from '@codemirror/legacy-modes/mode/stex';
import { groovy } from '@codemirror/legacy-modes/mode/groovy';
import { perl } from '@codemirror/legacy-modes/mode/perl';
import { cobol } from '@codemirror/legacy-modes/mode/cobol';
import { julia } from '@codemirror/legacy-modes/mode/julia';
import { haskell } from '@codemirror/legacy-modes/mode/haskell';
import { pascal } from '@codemirror/legacy-modes/mode/pascal';
import { yaml } from '@codemirror/legacy-modes/mode/yaml';
import { xml } from '@codemirror/legacy-modes/mode/xml';
import { shell } from '@codemirror/legacy-modes/mode/shell';
import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile';
import { diff } from '@codemirror/legacy-modes/mode/diff';
import { erlang } from '@codemirror/legacy-modes/mode/erlang';
import { sqlite, standardSQL, mySQL } from '@codemirror/legacy-modes/mode/sql';
import { javascript } from '@codemirror/lang-javascript';
import { markdown } from '@codemirror/lang-markdown';
import { html } from '@codemirror/lang-html';
import { cpp } from '@codemirror/lang-cpp';
import { php } from '@codemirror/lang-php';
import { java } from '@codemirror/lang-java';
import { rust } from '@codemirror/lang-rust';
const supportedLanguages: {
name: string;
aliases?: string[];
// Either support or parser must be given
parser?: StreamParser<any>;
support?: LanguageSupport;
}[] = [
// Based on @joplin/desktop/CodeMirror/Editor.tsx
{
name: 'LaTeX',
aliases: ['tex', 'latex', 'luatex'],
parser: stex,
},
{
name: 'python',
aliases: ['py'],
parser: python,
},
{
name: 'clike',
aliases: ['c', 'h'],
parser: c,
},
{
name: 'C++',
aliases: ['cpp', 'hpp', 'cxx', 'hxx', 'c++'],
support: cpp(),
},
{
name: 'java',
support: java(),
},
{
name: 'javascript',
aliases: ['js', 'mjs'],
support: javascript(),
},
{
name: 'typescript',
aliases: ['ts'],
support: javascript({ jsx: false, typescript: true }),
},
{
name: 'react javascript',
aliases: ['jsx'],
support: javascript({ jsx: true, typescript: false }),
},
{
name: 'react typescript',
aliases: ['tsx'],
support: javascript({ jsx: true, typescript: true }),
},
{
name: 'lua',
parser: lua,
},
{
name: 'php',
support: php(),
},
{
name: 'r',
parser: r,
},
{
name: 'swift',
parser: swift,
},
{
name: 'go',
parser: go,
},
{
name: 'visualbasic',
aliases: ['vb'],
parser: vb,
},
{
name: 'visualbasicscript',
aliases: ['vbscript', 'vbs'],
parser: vbScript,
},
{
name: 'ruby',
aliases: ['rb'],
parser: ruby,
},
{
name: 'rust',
aliases: ['rs'],
support: rust(),
},
{
name: 'dart',
parser: dart,
},
{
name: 'groovy',
parser: groovy,
},
{
name: 'perl',
aliases: ['pl'],
parser: perl,
},
{
name: 'cobol',
aliases: ['cbl', 'cob'],
parser: cobol,
},
{
name: 'julia',
aliases: ['jl'],
parser: julia,
},
{
name: 'haskell',
aliases: ['hs'],
parser: haskell,
},
{
name: 'pascal',
parser: pascal,
},
{
name: 'css',
parser: css,
},
{
name: 'xml',
aliases: ['xhtml'],
parser: xml,
},
{
name: 'html',
aliases: ['html', 'htm'],
support: html(),
},
{
name: 'markdown',
support: markdown(),
},
{
name: 'yaml',
parser: yaml,
},
{
name: 'shell',
aliases: ['bash', 'sh', 'zsh', 'dash'],
parser: shell,
},
{
name: 'dockerfile',
parser: dockerFile,
},
{
name: 'diff',
parser: diff,
},
{
name: 'erlang',
parser: erlang,
},
{
name: 'sql',
parser: standardSQL,
},
{
name: 'sqlite',
parser: sqlite,
},
{
name: 'mysql',
parser: mySQL,
},
];
// Convert supportedLanguages to a CodeMirror-readable list
// of LanguageDescriptions
const syntaxHighlightingLanguages: LanguageDescription[] = [];
for (const language of supportedLanguages) {
// Convert from parsers to LanguageSupport objects as necessary
const support = language.support ?? new LanguageSupport(StreamLanguage.define(language.parser));
syntaxHighlightingLanguages.push(
LanguageDescription.of({
name: language.name,
alias: language.aliases,
support,
})
);
}
export default syntaxHighlightingLanguages;

View File

@ -1,6 +1,6 @@
/**
* Create a set of Extensions that provide syntax highlighting.
*/
//
// Create a set of Extensions that provide syntax highlighting.
//
import { defaultHighlightStyle, syntaxHighlighting, HighlightStyle } from '@codemirror/language';
@ -8,6 +8,8 @@ import { tags } from '@lezer/highlight';
import { EditorView } from '@codemirror/view';
import { Extension } from '@codemirror/state';
import { inlineMathTag, mathTag } from './markdownMathParser';
// For an example on how to customize the theme, see:
//
// https://github.com/codemirror/theme-one-dark/blob/main/src/one-dark.ts
@ -20,6 +22,8 @@ import { Extension } from '@codemirror/state';
// the app is running. It seems that what appears as ".ͼ1" in the CSS is the
// equivalent of "&" in the theme object. So to target ".ͼ1.cm-focused", you'd
// use '&.cm-focused' in the theme.
//
// [theme] should be a joplin theme (see @joplin/lib/theme)
const createTheme = (theme: any): Extension[] => {
const isDarkTheme = theme.appearance === 'dark';
@ -32,6 +36,7 @@ const createTheme = (theme: any): Extension[] => {
const baseCursorStyle: Record<string, string> = { };
const baseContentStyle: Record<string, string> = { };
const baseSelectionStyle: Record<string, string> = { };
const blurredSelectionStyle: Record<string, string> = { };
// If we're in dark mode, the caret and selection are difficult to see.
// Adjust them appropriately
@ -43,19 +48,77 @@ const createTheme = (theme: any): Extension[] => {
baseCursorStyle.borderLeftColor = 'white';
baseSelectionStyle.backgroundColor = '#6b6b6b';
blurredSelectionStyle.backgroundColor = '#444';
}
const baseTheme = EditorView.baseTheme({
'&': baseGlobalStyle,
// These must be !important or more specific than CodeMirror's built-ins
'.cm-content': baseContentStyle,
'.cm-content': {
fontFamily: theme.fontFamily,
...baseContentStyle,
},
'&.cm-focused .cm-cursor': baseCursorStyle,
'&.cm-focused .cm-selectionBackground, ::selection': baseSelectionStyle,
'.cm-selectionBackground': blurredSelectionStyle,
'&.cm-focused': {
outline: 'none',
},
'& .cm-blockQuote': {
borderLeft: `4px solid ${theme.colorFaded}`,
opacity: theme.blockQuoteOpacity,
paddingLeft: '4px',
},
'& .cm-codeBlock': {
'&.cm-regionFirstLine, &.cm-regionLastLine': {
borderRadius: '3px',
},
'&:not(.cm-regionFirstLine)': {
borderTop: 'none',
borderTopLeftRadius: 0,
borderTopRightRadius: 0,
},
'&:not(.cm-regionLastLine)': {
borderBottom: 'none',
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
},
borderWidth: '1px',
borderStyle: 'solid',
borderColor: theme.colorFaded,
backgroundColor: 'rgba(155, 155, 155, 0.1)',
},
// CodeMirror wraps the existing inline span in an additional element.
// Due to a Chrome rendering bug, because the .cm-inlineCode wraps a
// span with a larger font-size, the .cm-inlineCode's bounding box won't
// be big enough for its content.
// As such, we need to style whichever element directly wraps its content.
'& .cm-headerLine > .cm-inlineCode > *, & :not(.cm-headerLine) > .cm-inlineCode': {
borderWidth: '1px',
borderStyle: 'solid',
borderColor: isDarkTheme ? 'rgba(200, 200, 200, 0.5)' : 'rgba(100, 100, 100, 0.5)',
borderRadius: '4px',
},
'& .cm-mathBlock, & .cm-inlineMath': {
color: isDarkTheme ? '#9fa' : '#276',
},
// Style the search widget. Use ':root' to increase the selector's precedence
// (override the existing preset styles).
':root & .cm-panel.cm-search': {
'& label, & button, & input': {
fontSize: '1em',
color: isDarkTheme ? 'white' : 'black',
},
},
});
const appearanceTheme = EditorView.theme({}, { dark: isDarkTheme });
@ -109,6 +172,42 @@ const createTheme = (theme: any): Extension[] => {
tag: tags.list,
fontFamily: theme.fontFamily,
},
{
tag: tags.comment,
opacity: 0.9,
fontStyle: 'italic',
},
{
tag: tags.link,
color: theme.urlColor,
textDecoration: 'underline',
},
{
tag: [mathTag, inlineMathTag],
fontStyle: 'italic',
},
// Content of code blocks
{
tag: tags.keyword,
color: isDarkTheme ? '#ff7' : '#740',
},
{
tag: tags.operator,
color: isDarkTheme ? '#f7f' : '#805',
},
{
tag: tags.literal,
color: isDarkTheme ? '#aaf' : '#037',
},
{
tag: tags.operator,
color: isDarkTheme ? '#fa9' : '#490',
},
{
tag: tags.typeName,
color: isDarkTheme ? '#7ff' : '#a00',
},
]);
return [

View File

@ -75,7 +75,13 @@
"@babel/core": "^7.12.9",
"@babel/runtime": "^7.12.5",
"@codemirror/commands": "^6.0.0",
"@codemirror/lang-cpp": "^6.0.0",
"@codemirror/lang-html": "^6.0.0",
"@codemirror/lang-java": "^6.0.0",
"@codemirror/lang-javascript": "^6.0.0",
"@codemirror/lang-markdown": "^6.0.0",
"@codemirror/lang-php": "^6.0.0",
"@codemirror/lang-rust": "^6.0.0",
"@codemirror/language": "^6.0.0",
"@codemirror/legacy-modes": "^6.1.0",
"@codemirror/search": "^6.0.0",

View File

@ -2353,6 +2353,16 @@ __metadata:
languageName: node
linkType: hard
"@codemirror/lang-cpp@npm:^6.0.0":
version: 6.0.1
resolution: "@codemirror/lang-cpp@npm:6.0.1"
dependencies:
"@codemirror/language": ^6.0.0
"@lezer/cpp": ^1.0.0
checksum: 082e8570db58cf2ffa1f509c72f0df72a9fea7174e46a858ec8b11e7a01ac6ecb5479f18140f2e4131abce51aeae5cacbc79dc8e71840ffdd404ede67e61cb4c
languageName: node
linkType: hard
"@codemirror/lang-css@npm:^6.0.0":
version: 6.0.0
resolution: "@codemirror/lang-css@npm:6.0.0"
@ -2380,6 +2390,16 @@ __metadata:
languageName: node
linkType: hard
"@codemirror/lang-java@npm:^6.0.0":
version: 6.0.0
resolution: "@codemirror/lang-java@npm:6.0.0"
dependencies:
"@codemirror/language": ^6.0.0
"@lezer/java": ^1.0.0
checksum: 27750c463490c71fd0781d9c729621edda2e73d1be316d49146b5876121557dabe58e069c8dfb6ee6fc902ab82ae46647f798a10f66cd4992a312e0b3b5775f2
languageName: node
linkType: hard
"@codemirror/lang-javascript@npm:^6.0.0":
version: 6.0.0
resolution: "@codemirror/lang-javascript@npm:6.0.0"
@ -2409,6 +2429,29 @@ __metadata:
languageName: node
linkType: hard
"@codemirror/lang-php@npm:^6.0.0":
version: 6.0.0
resolution: "@codemirror/lang-php@npm:6.0.0"
dependencies:
"@codemirror/lang-html": ^6.0.0
"@codemirror/language": ^6.0.0
"@codemirror/state": ^6.0.0
"@lezer/common": ^1.0.0
"@lezer/php": ^1.0.0
checksum: c602530ef766e94b2824791348702dc67d08ca35b1366f5e5f5e2a6c015a040a12508d39e9a907aab9f915caba06b087fd26ec2a614b5acc92b7661583490334
languageName: node
linkType: hard
"@codemirror/lang-rust@npm:^6.0.0":
version: 6.0.0
resolution: "@codemirror/lang-rust@npm:6.0.0"
dependencies:
"@codemirror/language": ^6.0.0
"@lezer/rust": ^1.0.0
checksum: 77f19ea1d9d956a54061864b26ce251f344cf38b822fa455759262f861b1d29fce9aa7dd9c5ff4399532d144e15eb53e9a5d947e3172ccf27e7a5c84c578c58e
languageName: node
linkType: hard
"@codemirror/language@npm:^6.0.0":
version: 6.0.0
resolution: "@codemirror/language@npm:6.0.0"
@ -3755,7 +3798,13 @@ __metadata:
"@babel/core": ^7.12.9
"@babel/runtime": ^7.12.5
"@codemirror/commands": ^6.0.0
"@codemirror/lang-cpp": ^6.0.0
"@codemirror/lang-html": ^6.0.0
"@codemirror/lang-java": ^6.0.0
"@codemirror/lang-javascript": ^6.0.0
"@codemirror/lang-markdown": ^6.0.0
"@codemirror/lang-php": ^6.0.0
"@codemirror/lang-rust": ^6.0.0
"@codemirror/language": ^6.0.0
"@codemirror/legacy-modes": ^6.1.0
"@codemirror/search": ^6.0.0
@ -5050,6 +5099,16 @@ __metadata:
languageName: node
linkType: hard
"@lezer/cpp@npm:^1.0.0":
version: 1.0.0
resolution: "@lezer/cpp@npm:1.0.0"
dependencies:
"@lezer/highlight": ^1.0.0
"@lezer/lr": ^1.0.0
checksum: 6829550db06ea9ce149fbcd50db3c8988e69bb8e2ce557ecde8f711222b902c5c64453fa77c502c6ab13381d041f5f8e8d3cb80049b2e9e963d76294533e5e83
languageName: node
linkType: hard
"@lezer/css@npm:^1.0.0":
version: 1.0.0
resolution: "@lezer/css@npm:1.0.0"
@ -5079,6 +5138,16 @@ __metadata:
languageName: node
linkType: hard
"@lezer/java@npm:^1.0.0":
version: 1.0.0
resolution: "@lezer/java@npm:1.0.0"
dependencies:
"@lezer/highlight": ^1.0.0
"@lezer/lr": ^1.0.0
checksum: 0dcd3ea2aa431bc352ed1ca1e92c61a1d60e10d1c0e730200ef1f1dda4b42421e67d56e7808e2102f16b6ffd534f246b82249922998663e9099bd52c141ef1d9
languageName: node
linkType: hard
"@lezer/javascript@npm:^1.0.0":
version: 1.0.0
resolution: "@lezer/javascript@npm:1.0.0"
@ -5108,6 +5177,26 @@ __metadata:
languageName: node
linkType: hard
"@lezer/php@npm:^1.0.0":
version: 1.0.0
resolution: "@lezer/php@npm:1.0.0"
dependencies:
"@lezer/highlight": ^1.0.0
"@lezer/lr": ^1.0.0
checksum: 06d20c423011119363ccd4dd30d0bdec56ddbdddda05888a6b5890fc090a6338740a310a77d367d3d69a958925fad73e0c7f9b62953eb3f189ec513bd71d9f59
languageName: node
linkType: hard
"@lezer/rust@npm:^1.0.0":
version: 1.0.0
resolution: "@lezer/rust@npm:1.0.0"
dependencies:
"@lezer/highlight": ^1.0.0
"@lezer/lr": ^1.0.0
checksum: 0c42f415674f60ca2ef4274b446577621cdeec8f31168b1c3b90888a4377c513f02a89ee346421c264ec3a77fe2fa3e134996be6463ed506dbbc79b4b4505375
languageName: node
linkType: hard
"@malept/cross-spawn-promise@npm:^1.1.0":
version: 1.1.1
resolution: "@malept/cross-spawn-promise@npm:1.1.1"