From 97146a63590fa193a4958c09202b40340e840a1f Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Wed, 3 Aug 2022 19:40:16 +0100 Subject: [PATCH] Added handling of codemirror 6 code languages --- package-lock.json | 261 +++++++++++++++++++++++++++++++++ package.json | 5 + resources/js/code/index.mjs | 49 ++----- resources/js/code/languages.js | 120 +++++++++++++++ resources/js/code/modes.js | 134 ----------------- resources/js/code/setups.js | 4 - resources/js/code/views.js | 38 +++++ 7 files changed, 437 insertions(+), 174 deletions(-) create mode 100644 resources/js/code/languages.js delete mode 100644 resources/js/code/modes.js create mode 100644 resources/js/code/views.js diff --git a/package-lock.json b/package-lock.json index c141e654a..0eca777cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,11 @@ "": { "dependencies": { "@codemirror/commands": "^6.0.1", + "@codemirror/lang-html": "^6.1.0", + "@codemirror/lang-javascript": "^6.0.2", + "@codemirror/lang-json": "^6.0.0", + "@codemirror/lang-markdown": "^6.0.1", + "@codemirror/lang-php": "^6.0.0", "@codemirror/language": "^6.2.1", "@codemirror/legacy-modes": "^6.1.0", "@codemirror/state": "^6.1.0", @@ -55,6 +60,79 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@codemirror/lang-css": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.0.tgz", + "integrity": "sha512-jBqc+BTuwhNOTlrimFghLlSrN6iFuE44HULKWoR4qKYObhOIl9Lci1iYj6zMIte1XTQmZguNvjXMyr43LUKwSw==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/css": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.1.0.tgz", + "integrity": "sha512-gA7NmJxqvnhwza05CvR7W/39Ap9r/4Vs9uiC0IeFYo1hSlJzc/8N6Evviz6vTW1x8SpHcRYyqKOf6rpl6LfWtg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/html": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz", + "integrity": "sha512-BZRJ9u/zl16hLkSpDAWm73mrfIR7HJrr0lvnhoSOCQVea5BglguWI/slxexhvUb0CB5cXgKWuo2bM+N9EhIaZw==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.0.tgz", + "integrity": "sha512-DvTcYTKLmg2viADXlTdufrT334M9jowe1qO02W28nvm+nejcvhM5vot5mE8/kPrxYw/HJHhwu1z2PyBpnMLCNQ==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-markdown": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.0.1.tgz", + "integrity": "sha512-pHPQuRwf9cUrmkmsTHRjtS9ZnGu3fA9YzAdh2++d+L9wbfnC2XbKh0Xvm/0YiUjdCnoCx9wDFEoCuAnkqKWLIw==", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/markdown": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-php": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.0.tgz", + "integrity": "sha512-96CEjq0xEgbzc6bdFPwILPfZ6m8917JRbh2oPszZJABlYxG4Y+eYjtYkUTDb4yuyjQKyigHoeGC6zoIOYA1NWA==", + "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" + } + }, "node_modules/@codemirror/language": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz", @@ -116,6 +194,15 @@ "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz", "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA==" }, + "node_modules/@lezer/css": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.0.0.tgz", + "integrity": "sha512-616VqgDKumHmYIuxs3tnX1irEQmoDHgF/TlP4O5ICWwyHwLMErq+8iKVuzTkOdBqvYAVmObqThcDEAaaMJjAdg==", + "dependencies": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/@lezer/highlight": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz", @@ -124,6 +211,34 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@lezer/html": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.0.1.tgz", + "integrity": "sha512-sC00zEt3GBh3vVO6QaGX4YZCl41S9dHWN/WGBsDixy9G+sqOC7gsa4cxA/fmRVAiBvhqYkJk+5Ul4oul92CPVw==", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz", + "integrity": "sha512-IjOVeIRhM8IuafWNnk+UzRz7p4/JSOKBNINLYLsdSGuJS9Ju7vFdc82AlTt0jgtV5D8eBZf4g0vK4d3ttBNz7A==", + "dependencies": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.0.tgz", + "integrity": "sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==", + "dependencies": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/@lezer/lr": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz", @@ -132,6 +247,24 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@lezer/markdown": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.1.tgz", + "integrity": "sha512-LlpNWLqes3XQvd8TwpJTHf9ENl4fI6H32xQkMgltUITFMMdQpOASXQtDawWR03yS6hskh4bkhATQbgjdGMoUvA==", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@lezer/php": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.0.tgz", + "integrity": "sha512-kFQu/mk/vmjpA+fjQU87d9eimqKJ9PFCa8CZCPFWGEwNnm7Ahpw32N+HYEU/YAQ0XcfmOAnW/YJCEa8WpUOMMw==", + "dependencies": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/ansi-regex": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", @@ -2053,6 +2186,79 @@ "@lezer/common": "^1.0.0" } }, + "@codemirror/lang-css": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.0.tgz", + "integrity": "sha512-jBqc+BTuwhNOTlrimFghLlSrN6iFuE44HULKWoR4qKYObhOIl9Lci1iYj6zMIte1XTQmZguNvjXMyr43LUKwSw==", + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/css": "^1.0.0" + } + }, + "@codemirror/lang-html": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.1.0.tgz", + "integrity": "sha512-gA7NmJxqvnhwza05CvR7W/39Ap9r/4Vs9uiC0IeFYo1hSlJzc/8N6Evviz6vTW1x8SpHcRYyqKOf6rpl6LfWtg==", + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/html": "^1.0.0" + } + }, + "@codemirror/lang-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz", + "integrity": "sha512-BZRJ9u/zl16hLkSpDAWm73mrfIR7HJrr0lvnhoSOCQVea5BglguWI/slxexhvUb0CB5cXgKWuo2bM+N9EhIaZw==", + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "@codemirror/lang-json": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.0.tgz", + "integrity": "sha512-DvTcYTKLmg2viADXlTdufrT334M9jowe1qO02W28nvm+nejcvhM5vot5mE8/kPrxYw/HJHhwu1z2PyBpnMLCNQ==", + "requires": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "@codemirror/lang-markdown": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.0.1.tgz", + "integrity": "sha512-pHPQuRwf9cUrmkmsTHRjtS9ZnGu3fA9YzAdh2++d+L9wbfnC2XbKh0Xvm/0YiUjdCnoCx9wDFEoCuAnkqKWLIw==", + "requires": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/markdown": "^1.0.0" + } + }, + "@codemirror/lang-php": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.0.tgz", + "integrity": "sha512-96CEjq0xEgbzc6bdFPwILPfZ6m8917JRbh2oPszZJABlYxG4Y+eYjtYkUTDb4yuyjQKyigHoeGC6zoIOYA1NWA==", + "requires": { + "@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" + } + }, "@codemirror/language": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz", @@ -2114,6 +2320,15 @@ "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.0.tgz", "integrity": "sha512-ohydQe+Hb+w4oMDvXzs8uuJd2NoA3D8YDcLiuDsLqH+yflDTPEpgCsWI3/6rH5C3BAedtH1/R51dxENldQceEA==" }, + "@lezer/css": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.0.0.tgz", + "integrity": "sha512-616VqgDKumHmYIuxs3tnX1irEQmoDHgF/TlP4O5ICWwyHwLMErq+8iKVuzTkOdBqvYAVmObqThcDEAaaMJjAdg==", + "requires": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "@lezer/highlight": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz", @@ -2122,6 +2337,34 @@ "@lezer/common": "^1.0.0" } }, + "@lezer/html": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.0.1.tgz", + "integrity": "sha512-sC00zEt3GBh3vVO6QaGX4YZCl41S9dHWN/WGBsDixy9G+sqOC7gsa4cxA/fmRVAiBvhqYkJk+5Ul4oul92CPVw==", + "requires": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@lezer/javascript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz", + "integrity": "sha512-IjOVeIRhM8IuafWNnk+UzRz7p4/JSOKBNINLYLsdSGuJS9Ju7vFdc82AlTt0jgtV5D8eBZf4g0vK4d3ttBNz7A==", + "requires": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@lezer/json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.0.tgz", + "integrity": "sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==", + "requires": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "@lezer/lr": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.0.tgz", @@ -2130,6 +2373,24 @@ "@lezer/common": "^1.0.0" } }, + "@lezer/markdown": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.1.tgz", + "integrity": "sha512-LlpNWLqes3XQvd8TwpJTHf9ENl4fI6H32xQkMgltUITFMMdQpOASXQtDawWR03yS6hskh4bkhATQbgjdGMoUvA==", + "requires": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "@lezer/php": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.0.tgz", + "integrity": "sha512-kFQu/mk/vmjpA+fjQU87d9eimqKJ9PFCa8CZCPFWGEwNnm7Ahpw32N+HYEU/YAQ0XcfmOAnW/YJCEa8WpUOMMw==", + "requires": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "ansi-regex": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", diff --git a/package.json b/package.json index 8407ffc77..4d2b70247 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,11 @@ }, "dependencies": { "@codemirror/commands": "^6.0.1", + "@codemirror/lang-html": "^6.1.0", + "@codemirror/lang-javascript": "^6.0.2", + "@codemirror/lang-json": "^6.0.0", + "@codemirror/lang-markdown": "^6.0.1", + "@codemirror/lang-php": "^6.0.0", "@codemirror/language": "^6.2.1", "@codemirror/legacy-modes": "^6.1.0", "@codemirror/state": "^6.1.0", diff --git a/resources/js/code/index.mjs b/resources/js/code/index.mjs index ff60cbff5..6ef659994 100644 --- a/resources/js/code/index.mjs +++ b/resources/js/code/index.mjs @@ -1,10 +1,9 @@ import {EditorView} from "@codemirror/view" -// import {EditorState} from "@codemirror/state" import Clipboard from "clipboard/dist/clipboard.min"; // Modes -import {modes, modeMap, modesAsStreamLanguages} from "./modes"; import {viewer} from "./setups.js"; +import {createView, updateViewLanguage} from "./views.js"; /** * Highlight pre elements on a page @@ -36,26 +35,24 @@ function highlightElem(elem) { elem.innerHTML = elem.innerHTML.replace(//gi ,'\n'); const content = elem.textContent.trimEnd(); - let mode = ''; + let langName = ''; if (innerCodeElem !== null) { - const langName = innerCodeElem.className.replace('language-', ''); - mode = getMode(langName, content); + langName = innerCodeElem.className.replace('language-', ''); } const wrapper = document.createElement('div'); elem.parentNode.insertBefore(wrapper, elem); - const cm = new EditorView({ + const ev = createView({ parent: wrapper, doc: content, extensions: viewer(), }); + setMode(ev, langName, content); elem.remove(); - // TODO - theme: getTheme(), - // TODO - mode, - addCopyIcon(cm); + addCopyIcon(ev); } /** @@ -84,28 +81,6 @@ function addCopyIcon(cmInstance) { // }); } -/** - * Search for a codemirror code based off a user suggestion - * @param {String} suggestion - * @param {String} content - * @returns {string} - */ -function getMode(suggestion, content) { - suggestion = suggestion.trim().replace(/^\./g, '').toLowerCase(); - - const modeMapType = typeof modeMap[suggestion]; - - if (modeMapType === 'undefined') { - return ''; - } - - if (modeMapType === 'function') { - return modeMap[suggestion](content); - } - - return modeMap[suggestion]; -} - /** * Ge the theme to use for CodeMirror instances. * @returns {*|string} @@ -172,12 +147,14 @@ export function inlineEditor(textArea, mode) { } /** - * Set the mode of a codemirror instance. - * @param cmInstance - * @param modeSuggestion + * Set the language mode of a codemirror EditorView. + * + * @param {EditorView} ev + * @param {string} modeSuggestion + * @param {string} content */ -export function setMode(cmInstance, modeSuggestion, content) { - cmInstance.setOption('mode', getMode(modeSuggestion, content)); +export function setMode(ev, modeSuggestion, content) { + updateViewLanguage(ev, modeSuggestion, content); } /** diff --git a/resources/js/code/languages.js b/resources/js/code/languages.js new file mode 100644 index 000000000..4b04bdb14 --- /dev/null +++ b/resources/js/code/languages.js @@ -0,0 +1,120 @@ +import {StreamLanguage} from "@codemirror/language" + +import {css} from '@codemirror/legacy-modes/mode/css'; +import {c, java, cpp, csharp, kotlin, scala} from '@codemirror/legacy-modes/mode/clike'; +import {diff} from '@codemirror/legacy-modes/mode/diff'; +import {fortran} from '@codemirror/legacy-modes/mode/fortran'; +import {go} from '@codemirror/legacy-modes/mode/go'; +import {haskell} from '@codemirror/legacy-modes/mode/haskell'; +import {html} from '@codemirror/lang-html'; +import {javascript} from '@codemirror/lang-javascript'; +import {json} from '@codemirror/lang-json'; +import {julia} from '@codemirror/legacy-modes/mode/julia'; +import {lua} from '@codemirror/legacy-modes/mode/lua'; +import {markdown} from '@codemirror/lang-markdown'; +import {oCaml, fSharp, sml} from '@codemirror/legacy-modes/mode/mllike'; +import {nginx} from '@codemirror/legacy-modes/mode/nginx'; +import {perl} from '@codemirror/legacy-modes/mode/perl'; +import {pascal} from '@codemirror/legacy-modes/mode/pascal'; +import {php} from '@codemirror/lang-php'; +import {powerShell} from '@codemirror/legacy-modes/mode/powershell'; +import {properties} from '@codemirror/legacy-modes/mode/properties'; +import {python} from '@codemirror/legacy-modes/mode/python'; +import {ruby} from '@codemirror/legacy-modes/mode/ruby'; +import {rust} from '@codemirror/legacy-modes/mode/rust'; +import {shell} from '@codemirror/legacy-modes/mode/shell'; +import {sql} from '@codemirror/legacy-modes/mode/sql'; +import {stex} from '@codemirror/legacy-modes/mode/stex'; +import {toml} from '@codemirror/legacy-modes/mode/toml'; +import {vb} from '@codemirror/legacy-modes/mode/vb'; +import {vbScript} from '@codemirror/legacy-modes/mode/vbscript'; +import {xml} from '@codemirror/legacy-modes/mode/xml'; +import {yaml} from '@codemirror/legacy-modes/mode/yaml'; + + +// Mapping of possible languages or formats from user input to their codemirror modes. +// Value can be a mode string or a function that will receive the code content & return the mode string. +// The function option is used in the event the exact mode could be dynamic depending on the code. +const modeMap = { + bash: () => StreamLanguage.define(shell), + css: () => StreamLanguage.define(css), + c: () => StreamLanguage.define(c), + java: () => StreamLanguage.define(java), + scala: () => StreamLanguage.define(scala), + kotlin: () => StreamLanguage.define(kotlin), + 'c++': () => StreamLanguage.define(cpp), + 'c#': () => StreamLanguage.define(csharp), + csharp: () => StreamLanguage.define(csharp), + diff: () => StreamLanguage.define(diff), + for: () => StreamLanguage.define(fortran), + fortran: () => StreamLanguage.define(fortran), + 'f#': () => StreamLanguage.define(fSharp), + fsharp: () => StreamLanguage.define(fSharp), + go: () => StreamLanguage.define(go), + haskell: () => StreamLanguage.define(haskell), + hs: () => StreamLanguage.define(haskell), + html: () => html(), + ini: () => StreamLanguage.define(properties), + javascript: () => javascript(), + json: () => json(), + js: () => javascript(), + jl: () => StreamLanguage.define(julia), + julia: () => StreamLanguage.define(julia), + latex: () => StreamLanguage.define(stex), + lua: () => StreamLanguage.define(lua), + md: () => StreamLanguage.define(markdown), + mdown: () => StreamLanguage.define(markdown), + markdown: () => StreamLanguage.define(markdown), + ml: () => StreamLanguage.define(sml), + nginx: () => StreamLanguage.define(nginx), + perl: () => StreamLanguage.define(perl), + pl: () => StreamLanguage.define(perl), + powershell: () => StreamLanguage.define(powerShell), + properties: () => StreamLanguage.define(properties), + ocaml: () => StreamLanguage.define(oCaml), + pascal: () => StreamLanguage.define(pascal), + pas: () => StreamLanguage.define(pascal), + php: (code) => { + const hasTags = code.includes(' StreamLanguage.define(python), + python: () => StreamLanguage.define(python), + ruby: () => StreamLanguage.define(ruby), + rust: () => StreamLanguage.define(rust), + rb: () => StreamLanguage.define(ruby), + rs: () => StreamLanguage.define(rust), + shell: () => StreamLanguage.define(shell), + sh: () => StreamLanguage.define(shell), + stext: () => StreamLanguage.define(stex), + toml: () => StreamLanguage.define(toml), + ts: () => javascript({typescript: true}), + typescript: () => javascript({typescript: true}), + sql: () => StreamLanguage.define(sql), + vbs: () => StreamLanguage.define(vbScript), + vbscript: () => StreamLanguage.define(vbScript), + 'vb.net': () => StreamLanguage.define(vb), + vbnet: () => StreamLanguage.define(vb), + xml: () => StreamLanguage.define(xml), + yaml: () => StreamLanguage.define(yaml), + yml: () => StreamLanguage.define(yaml), +}; + +/** + * Get the relevant codemirror language extension based upon the given language + * suggestion and content. + * @param {String} langSuggestion + * @param {String} content + * @returns {StreamLanguage} + */ +export function getLanguageExtension(langSuggestion, content) { + const suggestion = langSuggestion.trim().replace(/^\./g, '').toLowerCase(); + + const language = modeMap[suggestion]; + + if (typeof language === 'undefined') { + return undefined; + } + + return language(content); +} \ No newline at end of file diff --git a/resources/js/code/modes.js b/resources/js/code/modes.js deleted file mode 100644 index 5a89255a5..000000000 --- a/resources/js/code/modes.js +++ /dev/null @@ -1,134 +0,0 @@ -import {StreamLanguage} from "@codemirror/language" - -import {css as langCss} from '@codemirror/legacy-modes/mode/css'; -import {clike as langClike} from '@codemirror/legacy-modes/mode/clike'; -import {diff as langDiff} from '@codemirror/legacy-modes/mode/diff'; -import {fortran as langFortran} from '@codemirror/legacy-modes/mode/fortran'; -import {go as langGo} from '@codemirror/legacy-modes/mode/go'; -import {haskell as langHaskell} from '@codemirror/legacy-modes/mode/haskell'; -// import {htmlmixed as langHtmlmixed} from '@codemirror/legacy-modes/mode/htmlmixed'; -import {javascript as langJavascript} from '@codemirror/legacy-modes/mode/javascript'; -import {julia as langJulia} from '@codemirror/legacy-modes/mode/julia'; -import {lua as langLua} from '@codemirror/legacy-modes/mode/lua'; -// import {markdown as langMarkdown} from '@codemirror/legacy-modes/mode/markdown'; -import {oCaml as langMllike} from '@codemirror/legacy-modes/mode/mllike'; -import {nginx as langNginx} from '@codemirror/legacy-modes/mode/nginx'; -import {perl as langPerl} from '@codemirror/legacy-modes/mode/perl'; -import {pascal as langPascal} from '@codemirror/legacy-modes/mode/pascal'; -// import {php as langPhp} from '@codemirror/legacy-modes/mode/php'; -import {powerShell as langPowershell} from '@codemirror/legacy-modes/mode/powershell'; -import {properties as langProperties} from '@codemirror/legacy-modes/mode/properties'; -import {python as langPython} from '@codemirror/legacy-modes/mode/python'; -import {ruby as langRuby} from '@codemirror/legacy-modes/mode/ruby'; -import {rust as langRust} from '@codemirror/legacy-modes/mode/rust'; -import {shell as langShell} from '@codemirror/legacy-modes/mode/shell'; -import {sql as langSql} from '@codemirror/legacy-modes/mode/sql'; -import {stex as langStex} from '@codemirror/legacy-modes/mode/stex'; -import {toml as langToml} from '@codemirror/legacy-modes/mode/toml'; -import {vb as langVb} from '@codemirror/legacy-modes/mode/vb'; -import {vbScript as langVbscript} from '@codemirror/legacy-modes/mode/vbscript'; -import {xml as langXml} from '@codemirror/legacy-modes/mode/xml'; -import {yaml as langYaml} from '@codemirror/legacy-modes/mode/yaml'; - -export const modes = [ - langCss, - langClike, - langDiff, - langFortran, - langGo, - langHaskell, - // langHtmlmixed, - langJavascript, - langJulia, - langLua, - // langMarkdown, - langMllike, - langNginx, - langPerl, - langPascal, - // langPhp, - langPowershell, - langProperties, - langPython, - langRuby, - langRust, - langShell, - langSql, - langStex, - langToml, - langVb, - langVbscript, - langXml, - langYaml, -]; - -// Mapping of possible languages or formats from user input to their codemirror modes. -// Value can be a mode string or a function that will receive the code content & return the mode string. -// The function option is used in the event the exact mode could be dynamic depending on the code. -export const modeMap = { - bash: 'shell', - css: 'css', - c: 'text/x-csrc', - java: 'text/x-java', - scala: 'text/x-scala', - kotlin: 'text/x-kotlin', - 'c++': 'text/x-c++src', - 'c#': 'text/x-csharp', - csharp: 'text/x-csharp', - diff: 'diff', - for: 'fortran', - fortran: 'fortran', - 'f#': 'text/x-fsharp', - fsharp: 'text/x-fsharp', - go: 'go', - haskell: 'haskell', - hs: 'haskell', - html: 'htmlmixed', - ini: 'properties', - javascript: 'text/javascript', - json: 'application/json', - js: 'text/javascript', - jl: 'text/x-julia', - julia: 'text/x-julia', - latex: 'text/x-stex', - lua: 'lua', - md: 'markdown', - mdown: 'markdown', - markdown: 'markdown', - ml: 'mllike', - nginx: 'nginx', - perl: 'perl', - pl: 'perl', - powershell: 'powershell', - properties: 'properties', - ocaml: 'text/x-ocaml', - pascal: 'text/x-pascal', - pas: 'text/x-pascal', - php: (content) => { - return content.includes(' StreamLanguage.define(mode)); -} \ No newline at end of file diff --git a/resources/js/code/setups.js b/resources/js/code/setups.js index 768d3a35d..45cc9c317 100644 --- a/resources/js/code/setups.js +++ b/resources/js/code/setups.js @@ -6,9 +6,6 @@ import {defaultHighlightStyle, syntaxHighlighting, bracketMatching, import {defaultKeymap, history, historyKeymap} from "@codemirror/commands" import {EditorState} from "@codemirror/state" -import {modesAsStreamLanguages} from "./modes"; - - export function viewer() { return [ lineNumbers(), @@ -27,6 +24,5 @@ export function viewer() { ...foldKeymap, ]), EditorState.readOnly.of(true), - ...modesAsStreamLanguages(), ]; } \ No newline at end of file diff --git a/resources/js/code/views.js b/resources/js/code/views.js new file mode 100644 index 000000000..e87718939 --- /dev/null +++ b/resources/js/code/views.js @@ -0,0 +1,38 @@ +import {getLanguageExtension} from "./languages"; +import {Compartment} from "@codemirror/state" +import {EditorView} from "@codemirror/view" + +const viewLangCompartments = new WeakMap(); + +/** + * Create a new editor view. + * + * @param {Object} config + * @returns {EditorView} + */ +export function createView(config) { + const langCompartment = new Compartment(); + config.extensions.push(langCompartment.of([])); + + const ev = new EditorView(config); + + viewLangCompartments.set(ev, langCompartment); + + return ev; +} + +/** + * Set the language mode of an EditorView. + * + * @param {EditorView} ev + * @param {string} modeSuggestion + * @param {string} content + */ +export function updateViewLanguage(ev, modeSuggestion, content) { + const compartment = viewLangCompartments.get(ev); + const language = getLanguageExtension(modeSuggestion, content); + + ev.dispatch({ + effects: compartment.reconfigure(language ? language : []) + }) +} \ No newline at end of file