diff --git a/.eslintignore b/.eslintignore index 2b92f9ae0..95566a057 100644 --- a/.eslintignore +++ b/.eslintignore @@ -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 diff --git a/.gitignore b/.gitignore index 94c87402b..e7e6205c2 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts index f2562c922..1c4712dd1 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.ts @@ -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) => { diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.ts new file mode 100644 index 000000000..385aa9bb0 --- /dev/null +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.ts @@ -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(); + 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; diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.ts new file mode 100644 index 000000000..4b9d13bfd --- /dev/null +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.ts @@ -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; + 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; diff --git a/packages/app-mobile/components/NoteEditor/CodeMirror/theme.ts b/packages/app-mobile/components/NoteEditor/CodeMirror/theme.ts index 7a2d79dc5..7be933663 100644 --- a/packages/app-mobile/components/NoteEditor/CodeMirror/theme.ts +++ b/packages/app-mobile/components/NoteEditor/CodeMirror/theme.ts @@ -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 = { }; const baseContentStyle: Record = { }; const baseSelectionStyle: Record = { }; + const blurredSelectionStyle: Record = { }; // 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 [ diff --git a/packages/app-mobile/package.json b/packages/app-mobile/package.json index 404a0e371..268c70044 100644 --- a/packages/app-mobile/package.json +++ b/packages/app-mobile/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock index 173e1e967..002fa75ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"