ui: update codemirror editor
This commit is contained in:
parent
d2d62b7463
commit
3b1a0e22a7
8 changed files with 529 additions and 478 deletions
12
package.json
12
package.json
|
@ -19,7 +19,16 @@
|
||||||
"@codemirror/gutter": "^0.18.4",
|
"@codemirror/gutter": "^0.18.4",
|
||||||
"@codemirror/highlight": "^0.18.4",
|
"@codemirror/highlight": "^0.18.4",
|
||||||
"@codemirror/history": "^0.18.1",
|
"@codemirror/history": "^0.18.1",
|
||||||
|
"@codemirror/lang-cpp": "^0.18.0",
|
||||||
|
"@codemirror/lang-css": "^0.18.0",
|
||||||
|
"@codemirror/lang-html": "^0.18.1",
|
||||||
|
"@codemirror/lang-java": "^0.18.0",
|
||||||
|
"@codemirror/lang-javascript": "^0.18.0",
|
||||||
"@codemirror/lang-json": "^0.18.0",
|
"@codemirror/lang-json": "^0.18.0",
|
||||||
|
"@codemirror/lang-markdown": "^0.18.4",
|
||||||
|
"@codemirror/lang-rust": "^0.18.0",
|
||||||
|
"@codemirror/lang-sql": "^0.18.0",
|
||||||
|
"@codemirror/lang-xml": "^0.18.0",
|
||||||
"@codemirror/language": "^0.18.2",
|
"@codemirror/language": "^0.18.2",
|
||||||
"@codemirror/legacy-modes": "^0.18.1",
|
"@codemirror/legacy-modes": "^0.18.1",
|
||||||
"@codemirror/lint": "^0.18.4",
|
"@codemirror/lint": "^0.18.4",
|
||||||
|
@ -36,7 +45,6 @@
|
||||||
"@hot-loader/react-dom": "^16.14.0",
|
"@hot-loader/react-dom": "^16.14.0",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"chart.js": "^2.9.3",
|
"chart.js": "^2.9.3",
|
||||||
"codemirror": "^5.62.0",
|
|
||||||
"date-fns": "^2.22.1",
|
"date-fns": "^2.22.1",
|
||||||
"debounce": "^1.2.1",
|
"debounce": "^1.2.1",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
|
@ -96,7 +104,7 @@
|
||||||
"@types/debounce": "^1.2.0",
|
"@types/debounce": "^1.2.0",
|
||||||
"@types/events": "^3.0.0",
|
"@types/events": "^3.0.0",
|
||||||
"@types/history": "^4.7.9",
|
"@types/history": "^4.7.9",
|
||||||
"@types/node": "^16.3.0",
|
"@types/node": "^16.4.0",
|
||||||
"@types/qrcode.react": "^1.0.2",
|
"@types/qrcode.react": "^1.0.2",
|
||||||
"@types/query-string": "^6.3.0",
|
"@types/query-string": "^6.3.0",
|
||||||
"@types/react": "^16.14.11",
|
"@types/react": "^16.14.11",
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
import { shell } from '@codemirror/legacy-modes/mode/shell';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
import AdminBox from '@/components/admin/AdminBox';
|
import AdminBox from '@/components/admin/AdminBox';
|
||||||
import { Context } from '@/components/admin/nests/eggs/EggRouter';
|
import { Context } from '@/components/admin/nests/eggs/EggRouter';
|
||||||
import Editor2 from '@/components/elements/Editor2';
|
|
||||||
import { shell } from '@codemirror/legacy-modes/mode/shell';
|
|
||||||
import Button from '@/components/elements/Button';
|
import Button from '@/components/elements/Button';
|
||||||
|
import Editor from '@/components/elements/Editor';
|
||||||
import Input from '@/components/elements/Input';
|
import Input from '@/components/elements/Input';
|
||||||
import Label from '@/components/elements/Label';
|
import Label from '@/components/elements/Label';
|
||||||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
||||||
|
@ -28,7 +28,7 @@ export default () => {
|
||||||
<div css={tw`relative pb-4`}>
|
<div css={tw`relative pb-4`}>
|
||||||
<SpinnerOverlay visible={false}/>
|
<SpinnerOverlay visible={false}/>
|
||||||
|
|
||||||
<Editor2 overrides={tw`h-96 mb-4`} mode={shell} initialContent={initialContent}/>
|
<Editor overrides={tw`h-96 mb-4`} initialContent={initialContent} mode={shell}/>
|
||||||
|
|
||||||
<div css={tw`mx-6 mb-4`}>
|
<div css={tw`mx-6 mb-4`}>
|
||||||
<div css={tw`grid grid-cols-3 gap-x-8 gap-y-6`}>
|
<div css={tw`grid grid-cols-3 gap-x-8 gap-y-6`}>
|
||||||
|
|
|
@ -1,216 +0,0 @@
|
||||||
import React, { useCallback, useEffect, useState } from 'react';
|
|
||||||
import CodeMirror from 'codemirror';
|
|
||||||
import styled from 'styled-components/macro';
|
|
||||||
import tw from 'twin.macro';
|
|
||||||
import modes from '@/modes';
|
|
||||||
|
|
||||||
require('codemirror/lib/codemirror.css');
|
|
||||||
require('codemirror/theme/ayu-mirage.css');
|
|
||||||
require('codemirror/addon/edit/closebrackets');
|
|
||||||
require('codemirror/addon/edit/closetag');
|
|
||||||
require('codemirror/addon/edit/matchbrackets');
|
|
||||||
require('codemirror/addon/edit/matchtags');
|
|
||||||
require('codemirror/addon/edit/trailingspace');
|
|
||||||
require('codemirror/addon/fold/foldcode');
|
|
||||||
require('codemirror/addon/fold/foldgutter.css');
|
|
||||||
require('codemirror/addon/fold/foldgutter');
|
|
||||||
require('codemirror/addon/fold/brace-fold');
|
|
||||||
require('codemirror/addon/fold/comment-fold');
|
|
||||||
require('codemirror/addon/fold/indent-fold');
|
|
||||||
require('codemirror/addon/fold/markdown-fold');
|
|
||||||
require('codemirror/addon/fold/xml-fold');
|
|
||||||
require('codemirror/addon/hint/css-hint');
|
|
||||||
require('codemirror/addon/hint/html-hint');
|
|
||||||
require('codemirror/addon/hint/javascript-hint');
|
|
||||||
require('codemirror/addon/hint/show-hint.css');
|
|
||||||
require('codemirror/addon/hint/show-hint');
|
|
||||||
require('codemirror/addon/hint/sql-hint');
|
|
||||||
require('codemirror/addon/hint/xml-hint');
|
|
||||||
require('codemirror/addon/mode/simple');
|
|
||||||
require('codemirror/addon/dialog/dialog.css');
|
|
||||||
require('codemirror/addon/dialog/dialog');
|
|
||||||
require('codemirror/addon/scroll/annotatescrollbar');
|
|
||||||
require('codemirror/addon/scroll/scrollpastend');
|
|
||||||
require('codemirror/addon/scroll/simplescrollbars.css');
|
|
||||||
require('codemirror/addon/scroll/simplescrollbars');
|
|
||||||
require('codemirror/addon/search/jump-to-line');
|
|
||||||
require('codemirror/addon/search/match-highlighter');
|
|
||||||
require('codemirror/addon/search/matchesonscrollbar.css');
|
|
||||||
require('codemirror/addon/search/matchesonscrollbar');
|
|
||||||
require('codemirror/addon/search/search');
|
|
||||||
require('codemirror/addon/search/searchcursor');
|
|
||||||
|
|
||||||
require('codemirror/mode/brainfuck/brainfuck');
|
|
||||||
require('codemirror/mode/clike/clike');
|
|
||||||
require('codemirror/mode/css/css');
|
|
||||||
require('codemirror/mode/dart/dart');
|
|
||||||
require('codemirror/mode/diff/diff');
|
|
||||||
require('codemirror/mode/dockerfile/dockerfile');
|
|
||||||
require('codemirror/mode/erlang/erlang');
|
|
||||||
require('codemirror/mode/gfm/gfm');
|
|
||||||
require('codemirror/mode/go/go');
|
|
||||||
require('codemirror/mode/handlebars/handlebars');
|
|
||||||
require('codemirror/mode/htmlembedded/htmlembedded');
|
|
||||||
require('codemirror/mode/htmlmixed/htmlmixed');
|
|
||||||
require('codemirror/mode/http/http');
|
|
||||||
require('codemirror/mode/javascript/javascript');
|
|
||||||
require('codemirror/mode/jsx/jsx');
|
|
||||||
require('codemirror/mode/julia/julia');
|
|
||||||
require('codemirror/mode/lua/lua');
|
|
||||||
require('codemirror/mode/markdown/markdown');
|
|
||||||
require('codemirror/mode/nginx/nginx');
|
|
||||||
require('codemirror/mode/perl/perl');
|
|
||||||
require('codemirror/mode/php/php');
|
|
||||||
require('codemirror/mode/properties/properties');
|
|
||||||
require('codemirror/mode/protobuf/protobuf');
|
|
||||||
require('codemirror/mode/pug/pug');
|
|
||||||
require('codemirror/mode/python/python');
|
|
||||||
require('codemirror/mode/rpm/rpm');
|
|
||||||
require('codemirror/mode/ruby/ruby');
|
|
||||||
require('codemirror/mode/rust/rust');
|
|
||||||
require('codemirror/mode/sass/sass');
|
|
||||||
require('codemirror/mode/shell/shell');
|
|
||||||
require('codemirror/mode/smarty/smarty');
|
|
||||||
require('codemirror/mode/sql/sql');
|
|
||||||
require('codemirror/mode/swift/swift');
|
|
||||||
require('codemirror/mode/toml/toml');
|
|
||||||
require('codemirror/mode/twig/twig');
|
|
||||||
require('codemirror/mode/vue/vue');
|
|
||||||
require('codemirror/mode/xml/xml');
|
|
||||||
require('codemirror/mode/yaml/yaml');
|
|
||||||
|
|
||||||
const EditorContainer = styled.div`
|
|
||||||
min-height: 16rem;
|
|
||||||
height: calc(100vh - 20rem);
|
|
||||||
${tw`relative`};
|
|
||||||
|
|
||||||
> div {
|
|
||||||
${tw`rounded h-full`};
|
|
||||||
}
|
|
||||||
|
|
||||||
.CodeMirror {
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CodeMirror-linenumber {
|
|
||||||
padding: 1px 12px 0 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CodeMirror-foldmarker {
|
|
||||||
color: #CBCCC6;
|
|
||||||
text-shadow: none;
|
|
||||||
margin-left: 0.25rem;
|
|
||||||
margin-right: 0.25rem;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
style?: React.CSSProperties;
|
|
||||||
initialContent?: string;
|
|
||||||
mode: string;
|
|
||||||
filename?: string;
|
|
||||||
onModeChanged: (mode: string) => void;
|
|
||||||
fetchContent: (callback: () => Promise<string>) => void;
|
|
||||||
onContentSaved: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const findModeByFilename = (filename: string) => {
|
|
||||||
for (let i = 0; i < modes.length; i++) {
|
|
||||||
const info = modes[i];
|
|
||||||
|
|
||||||
if (info.file && info.file.test(filename)) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const dot = filename.lastIndexOf('.');
|
|
||||||
const ext = dot > -1 && filename.substring(dot + 1, filename.length);
|
|
||||||
|
|
||||||
if (ext) {
|
|
||||||
for (let i = 0; i < modes.length; i++) {
|
|
||||||
const info = modes[i];
|
|
||||||
if (info.ext) {
|
|
||||||
for (let j = 0; j < info.ext.length; j++) {
|
|
||||||
if (info.ext[j] === ext) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ({ style, initialContent, filename, mode, fetchContent, onContentSaved, onModeChanged }: Props) => {
|
|
||||||
const [ editor, setEditor ] = useState<CodeMirror.Editor>();
|
|
||||||
|
|
||||||
const ref = useCallback((node) => {
|
|
||||||
if (!node) return;
|
|
||||||
|
|
||||||
const e = CodeMirror.fromTextArea(node, {
|
|
||||||
mode: 'text/plain',
|
|
||||||
theme: 'ayu-mirage',
|
|
||||||
indentUnit: 4,
|
|
||||||
smartIndent: true,
|
|
||||||
tabSize: 4,
|
|
||||||
indentWithTabs: false,
|
|
||||||
lineWrapping: true,
|
|
||||||
lineNumbers: true,
|
|
||||||
// @ts-ignore
|
|
||||||
foldGutter: true,
|
|
||||||
fixedGutter: true,
|
|
||||||
scrollbarStyle: 'native',
|
|
||||||
coverGutterNextToScrollbar: false,
|
|
||||||
readOnly: false,
|
|
||||||
showCursorWhenSelecting: false,
|
|
||||||
autofocus: false,
|
|
||||||
spellcheck: true,
|
|
||||||
autocorrect: false,
|
|
||||||
autocapitalize: false,
|
|
||||||
lint: false,
|
|
||||||
autoCloseBrackets: true,
|
|
||||||
matchBrackets: true,
|
|
||||||
gutters: [ 'CodeMirror-linenumbers', 'CodeMirror-foldgutter' ],
|
|
||||||
});
|
|
||||||
|
|
||||||
setEditor(e);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (filename === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
onModeChanged(findModeByFilename(filename)?.mime || 'text/plain');
|
|
||||||
}, [ filename ]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
editor && editor.setOption('mode', mode);
|
|
||||||
}, [ editor, mode ]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
editor && editor.setValue(initialContent || '');
|
|
||||||
}, [ editor, initialContent ]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!editor) {
|
|
||||||
fetchContent(() => Promise.reject(new Error('no editor session has been configured')));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.addKeyMap({
|
|
||||||
'Ctrl-S': () => onContentSaved(),
|
|
||||||
'Cmd-S': () => onContentSaved(),
|
|
||||||
});
|
|
||||||
|
|
||||||
fetchContent(() => Promise.resolve(editor.getValue()));
|
|
||||||
}, [ editor, fetchContent, onContentSaved ]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EditorContainer style={style}>
|
|
||||||
<textarea ref={ref}/>
|
|
||||||
</EditorContainer>
|
|
||||||
);
|
|
||||||
};
|
|
287
resources/scripts/components/elements/Editor.tsx
Normal file
287
resources/scripts/components/elements/Editor.tsx
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
import { autocompletion, completionKeymap } from '@codemirror/autocomplete';
|
||||||
|
import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets';
|
||||||
|
import { defaultKeymap, defaultTabBinding } from '@codemirror/commands';
|
||||||
|
import { commentKeymap } from '@codemirror/comment';
|
||||||
|
import { foldGutter, foldKeymap } from '@codemirror/fold';
|
||||||
|
import { lineNumbers, highlightActiveLineGutter } from '@codemirror/gutter';
|
||||||
|
import { defaultHighlightStyle } from '@codemirror/highlight';
|
||||||
|
import { history, historyKeymap } from '@codemirror/history';
|
||||||
|
import { indentOnInput, LanguageSupport, LezerLanguage } from '@codemirror/language';
|
||||||
|
import { lintKeymap } from '@codemirror/lint';
|
||||||
|
import { bracketMatching } from '@codemirror/matchbrackets';
|
||||||
|
import { rectangularSelection } from '@codemirror/rectangular-selection';
|
||||||
|
import { searchKeymap, highlightSelectionMatches } from '@codemirror/search';
|
||||||
|
import { Compartment, Extension, EditorState } from '@codemirror/state';
|
||||||
|
import { StreamLanguage, StreamParser } from '@codemirror/stream-parser';
|
||||||
|
import { keymap, highlightSpecialChars, drawSelection, highlightActiveLine, EditorView } from '@codemirror/view';
|
||||||
|
import { clike } from '@codemirror/legacy-modes/mode/clike';
|
||||||
|
import { cppLanguage } from '@codemirror/lang-cpp';
|
||||||
|
import { cssLanguage } from '@codemirror/lang-css';
|
||||||
|
import { Cassandra, MariaSQL, MSSQL, MySQL, PostgreSQL, sql, SQLite, StandardSQL } from '@codemirror/lang-sql';
|
||||||
|
import { diff } from '@codemirror/legacy-modes/mode/diff';
|
||||||
|
import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile';
|
||||||
|
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
|
||||||
|
import { go } from '@codemirror/legacy-modes/mode/go';
|
||||||
|
import { htmlLanguage } from '@codemirror/lang-html';
|
||||||
|
import { http } from '@codemirror/legacy-modes/mode/http';
|
||||||
|
import { javascriptLanguage, typescriptLanguage } from '@codemirror/lang-javascript';
|
||||||
|
import { jsonLanguage } from '@codemirror/lang-json';
|
||||||
|
import { lua } from '@codemirror/legacy-modes/mode/lua';
|
||||||
|
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 { rustLanguage } from '@codemirror/lang-rust';
|
||||||
|
import { shell } from '@codemirror/legacy-modes/mode/shell';
|
||||||
|
import { toml } from '@codemirror/legacy-modes/mode/toml';
|
||||||
|
import { xmlLanguage } from '@codemirror/lang-xml';
|
||||||
|
import { yaml } from '@codemirror/legacy-modes/mode/yaml';
|
||||||
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
import styled from 'styled-components/macro';
|
||||||
|
import tw, { TwStyle } from 'twin.macro';
|
||||||
|
import { ayuMirage } from '@/components/elements/EditorTheme';
|
||||||
|
|
||||||
|
type EditorMode = LanguageSupport | LezerLanguage | StreamParser<any>;
|
||||||
|
|
||||||
|
export interface Mode {
|
||||||
|
name: string,
|
||||||
|
mime: string,
|
||||||
|
mimes?: string[],
|
||||||
|
mode?: EditorMode,
|
||||||
|
ext?: string[],
|
||||||
|
alias?: string[],
|
||||||
|
file?: RegExp,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const modes: Mode[] = [
|
||||||
|
{ name: 'C', mime: 'text/x-csrc', mode: clike({}), ext: [ 'c', 'h', 'ino' ] },
|
||||||
|
{ name: 'C++', mime: 'text/x-c++src', mode: cppLanguage, ext: [ 'cpp', 'c++', 'cc', 'cxx', 'hpp', 'h++', 'hh', 'hxx' ], alias: [ 'cpp' ] },
|
||||||
|
{ name: 'C#', mime: 'text/x-csharp', mode: clike({}), ext: [ 'cs' ], alias: [ 'csharp', 'cs' ] },
|
||||||
|
{ name: 'CSS', mime: 'text/css', mode: cssLanguage, ext: [ 'css' ] },
|
||||||
|
{ name: 'CQL', mime: 'text/x-cassandra', mode: sql({ dialect: Cassandra }), ext: [ 'cql' ] },
|
||||||
|
{ name: 'Diff', mime: 'text/x-diff', mode: diff, ext: [ 'diff', 'patch' ] },
|
||||||
|
{ name: 'Dockerfile', mime: 'text/x-dockerfile', mode: dockerFile, file: /^Dockerfile$/ },
|
||||||
|
{ name: 'Git Markdown', mime: 'text/x-gfm', mode: markdown({ defaultCodeLanguage: markdownLanguage }), file: /^(readme|contributing|history|license).md$/i },
|
||||||
|
{ name: 'Golang', mime: 'text/x-go', mode: go, ext: [ 'go' ] },
|
||||||
|
{ name: 'HTML', mime: 'text/html', mode: htmlLanguage, ext: [ 'html', 'htm', 'handlebars', 'hbs' ], alias: [ 'xhtml' ] },
|
||||||
|
{ name: 'HTTP', mime: 'message/http', mode: http },
|
||||||
|
{ name: 'JavaScript', mime: 'text/javascript', mimes: [ 'text/javascript', 'text/ecmascript', 'application/javascript', 'application/x-javascript', 'application/ecmascript' ], mode: javascriptLanguage, ext: [ 'js' ], alias: [ 'ecmascript', 'js', 'node' ] },
|
||||||
|
{ name: 'JSON', mime: 'application/json', mimes: [ 'application/json', 'application/x-json' ], mode: jsonLanguage, ext: [ 'json', 'map' ], alias: [ 'json5' ] },
|
||||||
|
{ name: 'Lua', mime: 'text/x-lua', mode: lua, ext: [ 'lua' ] },
|
||||||
|
{ name: 'Markdown', mime: 'text/x-markdown', mode: markdown({ defaultCodeLanguage: markdownLanguage }), ext: [ 'markdown', 'md', 'mkd' ] },
|
||||||
|
{ name: 'MariaDB', mime: 'text/x-mariadb', mode: sql({ dialect: MariaSQL }) },
|
||||||
|
{ name: 'MS SQL', mime: 'text/x-mssql', mode: sql({ dialect: MSSQL }) },
|
||||||
|
{ name: 'MySQL', mime: 'text/x-mysql', mode: sql({ dialect: MySQL }) },
|
||||||
|
{ name: 'Plain Text', mime: 'text/plain', mode: undefined, ext: [ 'txt', 'text', 'conf', 'def', 'list', 'log' ] },
|
||||||
|
{ name: 'PostgreSQL', mime: 'text/x-pgsql', mode: sql({ dialect: PostgreSQL }) },
|
||||||
|
{ name: 'Properties', mime: 'text/x-properties', mode: properties, ext: [ 'properties', 'ini', 'in' ], alias: [ 'ini', 'properties' ] },
|
||||||
|
{ name: 'Python', mime: 'text/x-python', mode: python, ext: [ 'BUILD', 'bzl', 'py', 'pyw' ], file: /^(BUCK|BUILD)$/ },
|
||||||
|
{ name: 'Ruby', mime: 'text/x-ruby', mode: ruby, ext: [ 'rb' ], alias: [ 'jruby', 'macruby', 'rake', 'rb', 'rbx' ] },
|
||||||
|
{ name: 'Rust', mime: 'text/x-rustsrc', mode: rustLanguage, ext: [ 'rs' ] },
|
||||||
|
{ name: 'Sass', mime: 'text/x-sass', mode: cssLanguage, ext: [ 'sass' ] },
|
||||||
|
{ name: 'SCSS', mime: 'text/x-scss', mode: cssLanguage, ext: [ 'scss' ] },
|
||||||
|
{ name: 'Shell', mime: 'text/x-sh', mimes: [ 'text/x-sh', 'application/x-sh' ], mode: shell, ext: [ 'sh', 'ksh', 'bash' ], alias: [ 'bash', 'sh', 'zsh' ], file: /^PKGBUILD$/ },
|
||||||
|
{ name: 'SQL', mime: 'text/x-sql', mode: sql({ dialect: StandardSQL }), ext: [ 'sql' ] },
|
||||||
|
{ name: 'SQLite', mime: 'text/x-sqlite', mode: sql({ dialect: SQLite }) },
|
||||||
|
{ name: 'TOML', mime: 'text/x-toml', mode: toml, ext: [ 'toml' ] },
|
||||||
|
{ name: 'TypeScript', mime: 'application/typescript', mode: typescriptLanguage, ext: [ 'ts' ], alias: [ 'ts' ] },
|
||||||
|
{ name: 'XML', mime: 'application/xml', mimes: [ 'application/xml', 'text/xml' ], mode: xmlLanguage, ext: [ 'xml', 'xsl', 'xsd', 'svg' ], alias: [ 'rss', 'wsdl', 'xsd' ] },
|
||||||
|
{ name: 'YAML', mime: 'text/x-yaml', mimes: [ 'text/x-yaml', 'text/yaml' ], mode: yaml, ext: [ 'yaml', 'yml' ], alias: [ 'yml' ] },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const modeToExtension = (m: EditorMode): Extension => {
|
||||||
|
if (m instanceof LanguageSupport) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m instanceof LezerLanguage) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StreamLanguage.define(m);
|
||||||
|
};
|
||||||
|
|
||||||
|
const findModeByFilename = (filename: string): Mode => {
|
||||||
|
for (let i = 0; i < modes.length; i++) {
|
||||||
|
const info = modes[i];
|
||||||
|
|
||||||
|
if (info.file && info.file.test(filename)) {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dot = filename.lastIndexOf('.');
|
||||||
|
const ext = dot > -1 && filename.substring(dot + 1, filename.length);
|
||||||
|
|
||||||
|
if (ext) {
|
||||||
|
for (let i = 0; i < modes.length; i++) {
|
||||||
|
const info = modes[i];
|
||||||
|
if (info.ext) {
|
||||||
|
for (let j = 0; j < info.ext.length; j++) {
|
||||||
|
if (info.ext[j] === ext) {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const plainText = modes.find(m => m.mime === 'text/plain');
|
||||||
|
if (plainText === undefined) {
|
||||||
|
throw new Error('failed to find \'text/plain\' mode');
|
||||||
|
}
|
||||||
|
return plainText;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findLanguageExtensionByMode = (mode: Mode): Extension => {
|
||||||
|
if (mode.mode === undefined) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return modeToExtension(mode.mode);
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultExtensions: Extension = [
|
||||||
|
ayuMirage,
|
||||||
|
|
||||||
|
lineNumbers(),
|
||||||
|
highlightActiveLineGutter(),
|
||||||
|
highlightSpecialChars(),
|
||||||
|
history(),
|
||||||
|
foldGutter(),
|
||||||
|
drawSelection(),
|
||||||
|
EditorState.allowMultipleSelections.of(true),
|
||||||
|
indentOnInput(),
|
||||||
|
defaultHighlightStyle.fallback,
|
||||||
|
bracketMatching(),
|
||||||
|
closeBrackets(),
|
||||||
|
autocompletion(),
|
||||||
|
rectangularSelection(),
|
||||||
|
highlightActiveLine(),
|
||||||
|
highlightSelectionMatches(),
|
||||||
|
keymap.of([
|
||||||
|
...closeBracketsKeymap,
|
||||||
|
...defaultKeymap,
|
||||||
|
...searchKeymap,
|
||||||
|
...historyKeymap,
|
||||||
|
...foldKeymap,
|
||||||
|
...commentKeymap,
|
||||||
|
...completionKeymap,
|
||||||
|
...lintKeymap,
|
||||||
|
defaultTabBinding,
|
||||||
|
]),
|
||||||
|
|
||||||
|
EditorState.tabSize.of(4),
|
||||||
|
];
|
||||||
|
|
||||||
|
const EditorContainer = styled.div<{ overrides?: TwStyle }>`
|
||||||
|
min-height: 12rem;
|
||||||
|
${tw`relative`};
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
${props => props.overrides};
|
||||||
|
|
||||||
|
&.cm-focused {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
className?: string;
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
overrides?: TwStyle;
|
||||||
|
|
||||||
|
initialContent?: string;
|
||||||
|
extensions?: Extension[];
|
||||||
|
mode?: EditorMode;
|
||||||
|
|
||||||
|
filename?: string;
|
||||||
|
onModeChanged?: (mode: Mode) => void;
|
||||||
|
fetchContent?: (callback: () => Promise<string>) => void;
|
||||||
|
onContentSaved?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ({ className, style, overrides, initialContent, extensions, mode, filename, onModeChanged }: Props) => {
|
||||||
|
const [ languageConfig ] = useState<Compartment>(new Compartment());
|
||||||
|
const [ state ] = useState<EditorState>(EditorState.create({
|
||||||
|
doc: initialContent,
|
||||||
|
extensions: [
|
||||||
|
...defaultExtensions,
|
||||||
|
...(extensions !== undefined ? extensions : []),
|
||||||
|
languageConfig.of(mode !== undefined ? modeToExtension(mode) : findLanguageExtensionByMode(findModeByFilename(filename || ''))),
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
const [ view, setView ] = useState<EditorView>();
|
||||||
|
|
||||||
|
const ref = useCallback((node) => {
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const view = new EditorView({
|
||||||
|
state: state,
|
||||||
|
parent: node,
|
||||||
|
});
|
||||||
|
setView(view);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// This useEffect is required to send the proper mode back to the parent element
|
||||||
|
// due to the initial language being set with EditorState#create, rather than in
|
||||||
|
// an useEffect like this one, or one watching `filename`.
|
||||||
|
useEffect(() => {
|
||||||
|
if (onModeChanged === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onModeChanged(findModeByFilename(filename || ''));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (view === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
view.dispatch({
|
||||||
|
effects: languageConfig.reconfigure(modeToExtension(mode)),
|
||||||
|
});
|
||||||
|
}, [ mode ]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (view === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mode = findModeByFilename(filename || '');
|
||||||
|
|
||||||
|
view.dispatch({
|
||||||
|
effects: languageConfig.reconfigure(findLanguageExtensionByMode(mode)),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(mode);
|
||||||
|
if (onModeChanged !== undefined) {
|
||||||
|
console.log(mode);
|
||||||
|
onModeChanged(mode);
|
||||||
|
}
|
||||||
|
}, [ filename ]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (view === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
view.dispatch({
|
||||||
|
changes: { from: 0, insert: initialContent },
|
||||||
|
});
|
||||||
|
}, [ initialContent ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EditorContainer className={className} style={style} overrides={overrides} ref={ref}/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,99 +0,0 @@
|
||||||
import React, { useCallback, useState } from 'react';
|
|
||||||
import styled from 'styled-components/macro';
|
|
||||||
import tw, { TwStyle } from 'twin.macro';
|
|
||||||
import { autocompletion, completionKeymap } from '@codemirror/autocomplete';
|
|
||||||
import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets';
|
|
||||||
import { defaultKeymap, defaultTabBinding } from '@codemirror/commands';
|
|
||||||
import { commentKeymap } from '@codemirror/comment';
|
|
||||||
import { foldGutter, foldKeymap } from '@codemirror/fold';
|
|
||||||
import { lineNumbers, highlightActiveLineGutter } from '@codemirror/gutter';
|
|
||||||
import { defaultHighlightStyle } from '@codemirror/highlight';
|
|
||||||
import { history, historyKeymap } from '@codemirror/history';
|
|
||||||
import { indentOnInput, LezerLanguage } from '@codemirror/language';
|
|
||||||
import { lintKeymap } from '@codemirror/lint';
|
|
||||||
import { bracketMatching } from '@codemirror/matchbrackets';
|
|
||||||
import { rectangularSelection } from '@codemirror/rectangular-selection';
|
|
||||||
import { searchKeymap, highlightSelectionMatches } from '@codemirror/search';
|
|
||||||
import { Extension, EditorState } from '@codemirror/state';
|
|
||||||
import { StreamLanguage, StreamParser } from '@codemirror/stream-parser';
|
|
||||||
import { keymap, highlightSpecialChars, drawSelection, highlightActiveLine, EditorView } from '@codemirror/view';
|
|
||||||
|
|
||||||
import { ayuMirage } from '@/components/elements/EditorTheme';
|
|
||||||
|
|
||||||
const extensions: Extension = [
|
|
||||||
ayuMirage,
|
|
||||||
|
|
||||||
lineNumbers(),
|
|
||||||
highlightActiveLineGutter(),
|
|
||||||
highlightSpecialChars(),
|
|
||||||
history(),
|
|
||||||
foldGutter(),
|
|
||||||
drawSelection(),
|
|
||||||
EditorState.allowMultipleSelections.of(true),
|
|
||||||
indentOnInput(),
|
|
||||||
defaultHighlightStyle.fallback,
|
|
||||||
bracketMatching(),
|
|
||||||
closeBrackets(),
|
|
||||||
autocompletion(),
|
|
||||||
rectangularSelection(),
|
|
||||||
highlightActiveLine(),
|
|
||||||
highlightSelectionMatches(),
|
|
||||||
keymap.of([
|
|
||||||
...closeBracketsKeymap,
|
|
||||||
...defaultKeymap,
|
|
||||||
...searchKeymap,
|
|
||||||
...historyKeymap,
|
|
||||||
...foldKeymap,
|
|
||||||
...commentKeymap,
|
|
||||||
...completionKeymap,
|
|
||||||
...lintKeymap,
|
|
||||||
defaultTabBinding,
|
|
||||||
]),
|
|
||||||
|
|
||||||
EditorState.tabSize.of(4),
|
|
||||||
];
|
|
||||||
|
|
||||||
const EditorContainer = styled.div<{ overrides?: TwStyle }>`
|
|
||||||
min-height: 12rem;
|
|
||||||
${tw`relative`};
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
${props => props.overrides};
|
|
||||||
|
|
||||||
&.cm-focused {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
className?: string;
|
|
||||||
overrides?: TwStyle;
|
|
||||||
mode: LezerLanguage | StreamParser<any>;
|
|
||||||
initialContent?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ({ className, overrides, mode, initialContent }: Props) => {
|
|
||||||
const [ state ] = useState<EditorState>(EditorState.create({
|
|
||||||
doc: initialContent,
|
|
||||||
extensions: [ ...extensions, (mode instanceof LezerLanguage) ? mode : StreamLanguage.define(mode) ],
|
|
||||||
}));
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const [ view, setView ] = useState<EditorView>();
|
|
||||||
|
|
||||||
const ref = useCallback((node) => {
|
|
||||||
if (!node) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const view = new EditorView({
|
|
||||||
state: state,
|
|
||||||
parent: node,
|
|
||||||
});
|
|
||||||
setView(view);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EditorContainer className={className} overrides={overrides} ref={ref}/>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,26 +1,24 @@
|
||||||
import React, { lazy, useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import getFileContents from '@/api/server/files/getFileContents';
|
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
|
||||||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
|
||||||
import saveFileContents from '@/api/server/files/saveFileContents';
|
|
||||||
import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcrumbs';
|
|
||||||
import { useHistory, useLocation, useParams } from 'react-router';
|
import { useHistory, useLocation, useParams } from 'react-router';
|
||||||
import FileNameModal from '@/components/server/files/FileNameModal';
|
import { dirname } from 'path';
|
||||||
|
import tw from 'twin.macro';
|
||||||
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
|
import getFileContents from '@/api/server/files/getFileContents';
|
||||||
|
import saveFileContents from '@/api/server/files/saveFileContents';
|
||||||
import Can from '@/components/elements/Can';
|
import Can from '@/components/elements/Can';
|
||||||
|
import Editor, { modes } from '@/components/elements/Editor';
|
||||||
|
import ErrorBoundary from '@/components/elements/ErrorBoundary';
|
||||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
|
import Button from '@/components/elements/Button';
|
||||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||||
import { ServerError } from '@/components/elements/ScreenBlock';
|
import { ServerError } from '@/components/elements/ScreenBlock';
|
||||||
import tw from 'twin.macro';
|
|
||||||
import Button from '@/components/elements/Button';
|
|
||||||
import Select from '@/components/elements/Select';
|
import Select from '@/components/elements/Select';
|
||||||
import modes from '@/modes';
|
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
||||||
|
import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcrumbs';
|
||||||
|
import FileNameModal from '@/components/server/files/FileNameModal';
|
||||||
import useFlash from '@/plugins/useFlash';
|
import useFlash from '@/plugins/useFlash';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import ErrorBoundary from '@/components/elements/ErrorBoundary';
|
|
||||||
import { encodePathSegments, hashToPath } from '@/helpers';
|
import { encodePathSegments, hashToPath } from '@/helpers';
|
||||||
import { dirname } from 'path';
|
|
||||||
|
|
||||||
const LazyCodemirrorEditor = lazy(() => import(/* webpackChunkName: "editor" */'@/components/elements/CodemirrorEditor'));
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [ error, setError ] = useState('');
|
const [ error, setError ] = useState('');
|
||||||
|
@ -28,7 +26,7 @@ export default () => {
|
||||||
const [ loading, setLoading ] = useState(action === 'edit');
|
const [ loading, setLoading ] = useState(action === 'edit');
|
||||||
const [ content, setContent ] = useState('');
|
const [ content, setContent ] = useState('');
|
||||||
const [ modalVisible, setModalVisible ] = useState(false);
|
const [ modalVisible, setModalVisible ] = useState(false);
|
||||||
const [ mode, setMode ] = useState('text/plain');
|
const [ mode, setMode ] = useState<string>('text/plain');
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { hash } = useLocation();
|
const { hash } = useLocation();
|
||||||
|
@ -38,6 +36,7 @@ export default () => {
|
||||||
const setDirectory = ServerContext.useStoreActions(actions => actions.files.setDirectory);
|
const setDirectory = ServerContext.useStoreActions(actions => actions.files.setDirectory);
|
||||||
const { addError, clearFlashes } = useFlash();
|
const { addError, clearFlashes } = useFlash();
|
||||||
|
|
||||||
|
// eslint-disable-next-line prefer-const
|
||||||
let fetchFileContent: null | (() => Promise<string>) = null;
|
let fetchFileContent: null | (() => Promise<string>) = null;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -116,11 +115,12 @@ export default () => {
|
||||||
/>
|
/>
|
||||||
<div css={tw`relative`}>
|
<div css={tw`relative`}>
|
||||||
<SpinnerOverlay visible={loading}/>
|
<SpinnerOverlay visible={loading}/>
|
||||||
<LazyCodemirrorEditor
|
<Editor
|
||||||
mode={mode}
|
style={{ height: 'calc(100vh - 20rem)' }}
|
||||||
filename={hash.replace(/^#/, '')}
|
overrides={tw`rounded h-full`}
|
||||||
onModeChanged={setMode}
|
|
||||||
initialContent={content}
|
initialContent={content}
|
||||||
|
filename={hash.replace(/^#/, '')}
|
||||||
|
onModeChanged={m => setMode(m.mime)}
|
||||||
fetchContent={value => {
|
fetchContent={value => {
|
||||||
fetchFileContent = value;
|
fetchFileContent = value;
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
export interface Mode {
|
|
||||||
name: string,
|
|
||||||
mime: string,
|
|
||||||
mimes?: string[],
|
|
||||||
mode: string,
|
|
||||||
ext?: string[],
|
|
||||||
alias?: string[],
|
|
||||||
file?: RegExp,
|
|
||||||
}
|
|
||||||
|
|
||||||
const modes: Mode[] = [
|
|
||||||
{ name: 'C', mime: 'text/x-csrc', mode: 'clike', ext: [ 'c', 'h', 'ino' ] },
|
|
||||||
{
|
|
||||||
name: 'C++',
|
|
||||||
mime: 'text/x-c++src',
|
|
||||||
mode: 'clike',
|
|
||||||
ext: [ 'cpp', 'c++', 'cc', 'cxx', 'hpp', 'h++', 'hh', 'hxx' ],
|
|
||||||
alias: [ 'cpp' ],
|
|
||||||
},
|
|
||||||
{ name: 'C#', mime: 'text/x-csharp', mode: 'clike', ext: [ 'cs' ], alias: [ 'csharp', 'cs' ] },
|
|
||||||
{ name: 'CSS', mime: 'text/css', mode: 'css', ext: [ 'css' ] },
|
|
||||||
{ name: 'CQL', mime: 'text/x-cassandra', mode: 'sql', ext: [ 'cql' ] },
|
|
||||||
{ name: 'Diff', mime: 'text/x-diff', mode: 'diff', ext: [ 'diff', 'patch' ] },
|
|
||||||
{ name: 'Dockerfile', mime: 'text/x-dockerfile', mode: 'dockerfile', file: /^Dockerfile$/ },
|
|
||||||
{ name: 'Git Markdown', mime: 'text/x-gfm', mode: 'gfm', file: /^(readme|contributing|history|license).md$/i },
|
|
||||||
{ name: 'Golang', mime: 'text/x-go', mode: 'go', ext: [ 'go' ] },
|
|
||||||
{
|
|
||||||
name: 'HTML',
|
|
||||||
mime: 'text/html',
|
|
||||||
mode: 'htmlmixed',
|
|
||||||
ext: [ 'html', 'htm', 'handlebars', 'hbs' ],
|
|
||||||
alias: [ 'xhtml' ],
|
|
||||||
},
|
|
||||||
{ name: 'HTTP', mime: 'message/http', mode: 'http' },
|
|
||||||
{
|
|
||||||
name: 'JavaScript',
|
|
||||||
mime: 'text/javascript',
|
|
||||||
mimes: [ 'text/javascript', 'text/ecmascript', 'application/javascript', 'application/x-javascript', 'application/ecmascript' ],
|
|
||||||
mode: 'javascript',
|
|
||||||
ext: [ 'js' ],
|
|
||||||
alias: [ 'ecmascript', 'js', 'node' ],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'JSON',
|
|
||||||
mime: 'application/json',
|
|
||||||
mimes: [ 'application/json', 'application/x-json' ],
|
|
||||||
mode: 'javascript',
|
|
||||||
ext: [ 'json', 'map' ],
|
|
||||||
alias: [ 'json5' ],
|
|
||||||
},
|
|
||||||
{ name: 'Lua', mime: 'text/x-lua', mode: 'lua', ext: [ 'lua' ] },
|
|
||||||
{ name: 'Markdown', mime: 'text/x-markdown', mode: 'markdown', ext: [ 'markdown', 'md', 'mkd' ] },
|
|
||||||
{ name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql' },
|
|
||||||
{ name: 'MS SQL', mime: 'text/x-mssql', mode: 'sql' },
|
|
||||||
{ name: 'MySQL', mime: 'text/x-mysql', mode: 'sql' },
|
|
||||||
{ name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx', file: /nginx.*\.conf$/i },
|
|
||||||
{
|
|
||||||
name: 'PHP',
|
|
||||||
mime: 'text/x-php',
|
|
||||||
mimes: [ 'text/x-php', 'application/x-httpd-php', 'application/x-httpd-php-open' ],
|
|
||||||
mode: 'php',
|
|
||||||
ext: [ 'php', 'php3', 'php4', 'php5', 'php7', 'phtml' ],
|
|
||||||
},
|
|
||||||
{ name: 'Plain Text', mime: 'text/plain', mode: 'null', ext: [ 'txt', 'text', 'conf', 'def', 'list', 'log' ] },
|
|
||||||
{ name: 'PostgreSQL', mime: 'text/x-pgsql', mode: 'sql' },
|
|
||||||
{
|
|
||||||
name: 'Properties',
|
|
||||||
mime: 'text/x-properties',
|
|
||||||
mode: 'properties',
|
|
||||||
ext: [ 'properties', 'ini', 'in' ],
|
|
||||||
alias: [ 'ini', 'properties' ],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Python',
|
|
||||||
mime: 'text/x-python',
|
|
||||||
mode: 'python',
|
|
||||||
ext: [ 'BUILD', 'bzl', 'py', 'pyw' ],
|
|
||||||
file: /^(BUCK|BUILD)$/,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Ruby',
|
|
||||||
mime: 'text/x-ruby',
|
|
||||||
mode: 'ruby',
|
|
||||||
ext: [ 'rb' ],
|
|
||||||
alias: [ 'jruby', 'macruby', 'rake', 'rb', 'rbx' ],
|
|
||||||
},
|
|
||||||
{ name: 'Rust', mime: 'text/x-rustsrc', mode: 'rust', ext: [ 'rs' ] },
|
|
||||||
{ name: 'Sass', mime: 'text/x-sass', mode: 'sass', ext: [ 'sass' ] },
|
|
||||||
{ name: 'SCSS', mime: 'text/x-scss', mode: 'css', ext: [ 'scss' ] },
|
|
||||||
{
|
|
||||||
name: 'Shell',
|
|
||||||
mime: 'text/x-sh',
|
|
||||||
mimes: [ 'text/x-sh', 'application/x-sh' ],
|
|
||||||
mode: 'shell',
|
|
||||||
ext: [ 'sh', 'ksh', 'bash' ],
|
|
||||||
alias: [ 'bash', 'sh', 'zsh' ],
|
|
||||||
file: /^PKGBUILD$/,
|
|
||||||
},
|
|
||||||
{ name: 'SQL', mime: 'text/x-sql', mode: 'sql', ext: [ 'sql' ] },
|
|
||||||
{ name: 'SQLite', mime: 'text/x-sqlite', mode: 'sql' },
|
|
||||||
{ name: 'TOML', mime: 'text/x-toml', mode: 'toml', ext: [ 'toml' ] },
|
|
||||||
{ name: 'TypeScript', mime: 'application/typescript', mode: 'javascript', ext: [ 'ts' ], alias: [ 'ts' ] },
|
|
||||||
{ name: 'Vue', mime: 'script/x-vue', mimes: [ 'script/x-vue', 'text/x-vue' ], mode: 'vue', ext: [ 'vue' ] },
|
|
||||||
{
|
|
||||||
name: 'XML',
|
|
||||||
mime: 'application/xml',
|
|
||||||
mimes: [ 'application/xml', 'text/xml' ],
|
|
||||||
mode: 'xml',
|
|
||||||
ext: [ 'xml', 'xsl', 'xsd', 'svg' ],
|
|
||||||
alias: [ 'rss', 'wsdl', 'xsd' ],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'YAML',
|
|
||||||
mime: 'text/x-yaml',
|
|
||||||
mimes: [ 'text/x-yaml', 'text/yaml' ],
|
|
||||||
mode: 'yaml',
|
|
||||||
ext: [ 'yaml', 'yml' ],
|
|
||||||
alias: [ 'yml' ],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default modes;
|
|
227
yarn.lock
227
yarn.lock
|
@ -1637,7 +1637,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@codemirror/autocomplete@npm:^0.18.8":
|
"@codemirror/autocomplete@npm:^0.18.0, @codemirror/autocomplete@npm:^0.18.8":
|
||||||
version: 0.18.8
|
version: 0.18.8
|
||||||
resolution: "@codemirror/autocomplete@npm:0.18.8"
|
resolution: "@codemirror/autocomplete@npm:0.18.8"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1737,6 +1737,72 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-cpp@npm:^0.18.0":
|
||||||
|
version: 0.18.0
|
||||||
|
resolution: "@codemirror/lang-cpp@npm:0.18.0"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
lezer-cpp: ^0.13.0
|
||||||
|
checksum: e90e236540c1ebdc7638b7e9d3b5a890acab9402cdd6d4298d4cfc17f92c36ce45e74902f1c010de3879b96cb3e756b87f0ba68d1e63f87d137c408686547838
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-css@npm:^0.18.0":
|
||||||
|
version: 0.18.0
|
||||||
|
resolution: "@codemirror/lang-css@npm:0.18.0"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/autocomplete": ^0.18.0
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
"@codemirror/state": ^0.18.0
|
||||||
|
lezer-css: ^0.13.0
|
||||||
|
checksum: dbbc4997518aec7678ff6252543ae9af3af012d2d89a3a9ca6adf576799a0306806088eab060a0e1ea252a2f76fe387c2f3c0188392e26ae3aa4964e7896c8b4
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-html@npm:^0.18.0, @codemirror/lang-html@npm:^0.18.1":
|
||||||
|
version: 0.18.1
|
||||||
|
resolution: "@codemirror/lang-html@npm:0.18.1"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/autocomplete": ^0.18.0
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/lang-css": ^0.18.0
|
||||||
|
"@codemirror/lang-javascript": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
"@codemirror/state": ^0.18.0
|
||||||
|
lezer-html: ^0.13.5
|
||||||
|
lezer-tree: ^0.13.0
|
||||||
|
checksum: 37468fb597b6ef1d207b5b6a5e35d31ff32e57b994883d74b8102e701a171c69f5e18545a4d7e4a554c752564deeb04e293facfa8a49e7d500b90d28c5f3ba92
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-java@npm:^0.18.0":
|
||||||
|
version: 0.18.0
|
||||||
|
resolution: "@codemirror/lang-java@npm:0.18.0"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
lezer-java: ^0.13.0
|
||||||
|
checksum: 4770afa4a6bdc83b93813541e58626932a0c31493b84bf53ea612f0b96da4d1ecdf7bd37eba9ea0d40e0de997c8763c609b1e70fb97734e018025b84f4781bee
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-javascript@npm:^0.18.0":
|
||||||
|
version: 0.18.0
|
||||||
|
resolution: "@codemirror/lang-javascript@npm:0.18.0"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/autocomplete": ^0.18.0
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
"@codemirror/lint": ^0.18.0
|
||||||
|
"@codemirror/state": ^0.18.0
|
||||||
|
"@codemirror/view": ^0.18.0
|
||||||
|
lezer-javascript: ^0.13.0
|
||||||
|
checksum: 0812bb583184869ee62aab90534aba4e778bd2e9bc37697c118e4e8464b9ec291fca1d049f86534dae4cb461d540d3f1fa6eab5870d3b1caff1ebf1bf309ce8f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@codemirror/lang-json@npm:^0.18.0":
|
"@codemirror/lang-json@npm:^0.18.0":
|
||||||
version: 0.18.0
|
version: 0.18.0
|
||||||
resolution: "@codemirror/lang-json@npm:0.18.0"
|
resolution: "@codemirror/lang-json@npm:0.18.0"
|
||||||
|
@ -1748,7 +1814,60 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@codemirror/language@npm:^0.18.0, @codemirror/language@npm:^0.18.2":
|
"@codemirror/lang-markdown@npm:^0.18.4":
|
||||||
|
version: 0.18.4
|
||||||
|
resolution: "@codemirror/lang-markdown@npm:0.18.4"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/highlight": ^0.18.4
|
||||||
|
"@codemirror/lang-html": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.1
|
||||||
|
"@codemirror/state": ^0.18.0
|
||||||
|
"@codemirror/view": ^0.18.0
|
||||||
|
lezer-markdown: ^0.14.3
|
||||||
|
lezer-tree: ^0.13.0
|
||||||
|
checksum: 90d1d7f8298cc90da554cc9f0e46ae2babb5642e503260704f2bf908f86433ff901bb5d7a75cbe77926b1ef5a47aa64de2f35e4dee8079c49e9c8750723de1e5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-rust@npm:^0.18.0":
|
||||||
|
version: 0.18.0
|
||||||
|
resolution: "@codemirror/lang-rust@npm:0.18.0"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
lezer-rust: ^0.13.0
|
||||||
|
checksum: a50027c2584f2e21dc350158469359f65fa522f68da97df2fd3d966bde5698cceb9555721475c9cf9ed96f31fe6f13909459227445a714fbdb12905956439d74
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-sql@npm:^0.18.0":
|
||||||
|
version: 0.18.0
|
||||||
|
resolution: "@codemirror/lang-sql@npm:0.18.0"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/autocomplete": ^0.18.0
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
"@codemirror/state": ^0.18.0
|
||||||
|
lezer: ^0.13.0
|
||||||
|
checksum: 945ced193f4016490f601f29a6dc0d6296c8ff32dfdeae7fa6bd563171d6898dffc75e8feb5ceb23a236585d9358dda9726131c2e047e78a7638ac593dda0f35
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/lang-xml@npm:^0.18.0":
|
||||||
|
version: 0.18.0
|
||||||
|
resolution: "@codemirror/lang-xml@npm:0.18.0"
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/autocomplete": ^0.18.0
|
||||||
|
"@codemirror/highlight": ^0.18.0
|
||||||
|
"@codemirror/language": ^0.18.0
|
||||||
|
"@codemirror/state": ^0.18.0
|
||||||
|
lezer-tree: ^0.13.0
|
||||||
|
lezer-xml: ^0.13.0
|
||||||
|
checksum: c61be7e1777ab9e5ad63846b62bf372c372cc3af73960039b38bfd440de1f9c72833927f88d416dd373d8aeef17dab68703e523cf4089caacb46f3380580d45d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@codemirror/language@npm:^0.18.0, @codemirror/language@npm:^0.18.1, @codemirror/language@npm:^0.18.2":
|
||||||
version: 0.18.2
|
version: 0.18.2
|
||||||
resolution: "@codemirror/language@npm:0.18.2"
|
resolution: "@codemirror/language@npm:0.18.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1770,7 +1889,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@codemirror/lint@npm:^0.18.4":
|
"@codemirror/lint@npm:^0.18.0, @codemirror/lint@npm:^0.18.4":
|
||||||
version: 0.18.4
|
version: 0.18.4
|
||||||
resolution: "@codemirror/lint@npm:0.18.4"
|
resolution: "@codemirror/lint@npm:0.18.4"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -2305,10 +2424,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/node@npm:^16.3.0":
|
"@types/node@npm:^16.4.0":
|
||||||
version: 16.3.0
|
version: 16.4.0
|
||||||
resolution: "@types/node@npm:16.3.0"
|
resolution: "@types/node@npm:16.4.0"
|
||||||
checksum: aec069f8dfeb1a3d8246013f55312a8effcf152f81250a762880670e53c5f676e7f6338746ca7e0aae4ecede5847c69917795fc74e10d5065dfa1ce6179a0c6e
|
checksum: 3f2aaccbe8795079dad399f9c0e90ebf97093835dbbe93284a3655b1c018b9db34c76b8ee16f14b06b6e6e3f69b23208055f8b7417be24f7eaaa048883af37c1
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -4078,13 +4197,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"codemirror@npm:^5.62.0":
|
|
||||||
version: 5.62.0
|
|
||||||
resolution: "codemirror@npm:5.62.0"
|
|
||||||
checksum: cab8037e65a35ac89edfd9e0a567079140ae07fa8d512d9ab752d7060bb573988ec32c613810e29006016fcc1d3b6acca01c3717cd293a0601e2e79f07d5b4ea
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"collection-visit@npm:^1.0.0":
|
"collection-visit@npm:^1.0.0":
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
resolution: "collection-visit@npm:1.0.0"
|
resolution: "collection-visit@npm:1.0.0"
|
||||||
|
@ -7663,6 +7775,51 @@ fsevents@^1.2.7:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer-cpp@npm:^0.13.0":
|
||||||
|
version: 0.13.2
|
||||||
|
resolution: "lezer-cpp@npm:0.13.2"
|
||||||
|
dependencies:
|
||||||
|
lezer: ^0.13.0
|
||||||
|
checksum: 9d1dba785c4c7fe676023b10aaaeb2b1daa2699753e1ba09275bc7a732cc9818679961d358b6cfd156c77224f5630402cc83b69bd680e3ae7230f7bfee877b19
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer-css@npm:^0.13.0":
|
||||||
|
version: 0.13.1
|
||||||
|
resolution: "lezer-css@npm:0.13.1"
|
||||||
|
dependencies:
|
||||||
|
lezer: ^0.13.0
|
||||||
|
checksum: f40600de936cc8887b18004757a7943e072b09d72a6624e9523677c67cc4d4ba97f80af929d18e5e08c9d3c778b531930b0ec0e41b0e9462686df60e3a6d0a71
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer-html@npm:^0.13.0, lezer-html@npm:^0.13.5":
|
||||||
|
version: 0.13.6
|
||||||
|
resolution: "lezer-html@npm:0.13.6"
|
||||||
|
dependencies:
|
||||||
|
lezer: ^0.13.3
|
||||||
|
checksum: 34bf99c35b568f344c770ae1c187701a256df9b8a50787592538c40a83c84c73ac98f7b5f9ece526f8091cc61dc2b7075d5d277821acad45e8237c4da845d089
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer-java@npm:^0.13.0":
|
||||||
|
version: 0.13.2
|
||||||
|
resolution: "lezer-java@npm:0.13.2"
|
||||||
|
dependencies:
|
||||||
|
lezer: ^0.13.0
|
||||||
|
checksum: bd380eaab50f823e04a0bfe061b3d504ae00f4616c4f84a8ba2e1af80730a4b9c73723f84f567caebda1487c15f6f67bdbbc94c6a3232c04d02185e2a59a63a4
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer-javascript@npm:^0.13.0":
|
||||||
|
version: 0.13.4
|
||||||
|
resolution: "lezer-javascript@npm:0.13.4"
|
||||||
|
dependencies:
|
||||||
|
lezer: ^0.13.0
|
||||||
|
checksum: 90f014f7f964365f9fff07ec39332711e750729b669c5d4ac76c8440749111fd115ec272f739f6c3b9c8e73ed768110b99e1380e9efc64fa5cd64ebabed73511
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"lezer-json@npm:^0.13.0":
|
"lezer-json@npm:^0.13.0":
|
||||||
version: 0.13.2
|
version: 0.13.2
|
||||||
resolution: "lezer-json@npm:0.13.2"
|
resolution: "lezer-json@npm:0.13.2"
|
||||||
|
@ -7672,6 +7829,25 @@ fsevents@^1.2.7:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer-markdown@npm:^0.14.3":
|
||||||
|
version: 0.14.5
|
||||||
|
resolution: "lezer-markdown@npm:0.14.5"
|
||||||
|
dependencies:
|
||||||
|
lezer-html: ^0.13.0
|
||||||
|
lezer-tree: ^0.13.0
|
||||||
|
checksum: e5804a6fada31876d60ec0ad7144ee4e01f6d135f2863a8664353e48367fadde2b48a1e60e67ebc45107f8776994aafedb7310fb329aff441af3bab26a7213af
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer-rust@npm:^0.13.0":
|
||||||
|
version: 0.13.1
|
||||||
|
resolution: "lezer-rust@npm:0.13.1"
|
||||||
|
dependencies:
|
||||||
|
lezer: ^0.13.0
|
||||||
|
checksum: a7d4c8eb6a4014e0cdf4596f3c0de11fbb2b83d6b4101e8cb2bc8c9e4942213d4963065b3a6f0e1526b00738d446961fa698867b7e96e066ffe9c256539fefef
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"lezer-tree@npm:^0.13.0, lezer-tree@npm:^0.13.2":
|
"lezer-tree@npm:^0.13.0, lezer-tree@npm:^0.13.2":
|
||||||
version: 0.13.2
|
version: 0.13.2
|
||||||
resolution: "lezer-tree@npm:0.13.2"
|
resolution: "lezer-tree@npm:0.13.2"
|
||||||
|
@ -7679,7 +7855,16 @@ fsevents@^1.2.7:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lezer@npm:^0.13.0, lezer@npm:^0.13.4":
|
"lezer-xml@npm:^0.13.0":
|
||||||
|
version: 0.13.4
|
||||||
|
resolution: "lezer-xml@npm:0.13.4"
|
||||||
|
dependencies:
|
||||||
|
lezer: ^0.13.3
|
||||||
|
checksum: e73d63a20d74e8088aefd4c95e6ece3dea9cef75498b4b1f3b18cd4c517352ff978b10d0ac12791a07ad84b9e3608a80da49c5e5bf370082afde9d7ae8456ee7
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"lezer@npm:^0.13.0, lezer@npm:^0.13.3, lezer@npm:^0.13.4":
|
||||||
version: 0.13.5
|
version: 0.13.5
|
||||||
resolution: "lezer@npm:0.13.5"
|
resolution: "lezer@npm:0.13.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -9658,7 +9843,16 @@ fsevents@^1.2.7:
|
||||||
"@codemirror/gutter": ^0.18.4
|
"@codemirror/gutter": ^0.18.4
|
||||||
"@codemirror/highlight": ^0.18.4
|
"@codemirror/highlight": ^0.18.4
|
||||||
"@codemirror/history": ^0.18.1
|
"@codemirror/history": ^0.18.1
|
||||||
|
"@codemirror/lang-cpp": ^0.18.0
|
||||||
|
"@codemirror/lang-css": ^0.18.0
|
||||||
|
"@codemirror/lang-html": ^0.18.1
|
||||||
|
"@codemirror/lang-java": ^0.18.0
|
||||||
|
"@codemirror/lang-javascript": ^0.18.0
|
||||||
"@codemirror/lang-json": ^0.18.0
|
"@codemirror/lang-json": ^0.18.0
|
||||||
|
"@codemirror/lang-markdown": ^0.18.4
|
||||||
|
"@codemirror/lang-rust": ^0.18.0
|
||||||
|
"@codemirror/lang-sql": ^0.18.0
|
||||||
|
"@codemirror/lang-xml": ^0.18.0
|
||||||
"@codemirror/language": ^0.18.2
|
"@codemirror/language": ^0.18.2
|
||||||
"@codemirror/legacy-modes": ^0.18.1
|
"@codemirror/legacy-modes": ^0.18.1
|
||||||
"@codemirror/lint": ^0.18.4
|
"@codemirror/lint": ^0.18.4
|
||||||
|
@ -9679,7 +9873,7 @@ fsevents@^1.2.7:
|
||||||
"@types/debounce": ^1.2.0
|
"@types/debounce": ^1.2.0
|
||||||
"@types/events": ^3.0.0
|
"@types/events": ^3.0.0
|
||||||
"@types/history": ^4.7.9
|
"@types/history": ^4.7.9
|
||||||
"@types/node": ^16.3.0
|
"@types/node": ^16.4.0
|
||||||
"@types/qrcode.react": ^1.0.2
|
"@types/qrcode.react": ^1.0.2
|
||||||
"@types/query-string": ^6.3.0
|
"@types/query-string": ^6.3.0
|
||||||
"@types/react": ^16.14.11
|
"@types/react": ^16.14.11
|
||||||
|
@ -9705,7 +9899,6 @@ fsevents@^1.2.7:
|
||||||
babel-plugin-styled-components: ^1.13.2
|
babel-plugin-styled-components: ^1.13.2
|
||||||
browserslist: ^4.16.6
|
browserslist: ^4.16.6
|
||||||
chart.js: ^2.9.3
|
chart.js: ^2.9.3
|
||||||
codemirror: ^5.62.0
|
|
||||||
cross-env: ^7.0.3
|
cross-env: ^7.0.3
|
||||||
css-loader: ^5.2.6
|
css-loader: ^5.2.6
|
||||||
date-fns: ^2.22.1
|
date-fns: ^2.22.1
|
||||||
|
|
Loading…
Reference in a new issue