mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-04 16:31:13 +00:00
code file support syntax highlight (#6922)
* code file support syntax highlight * add theme.js --------- Co-authored-by: zhouwenxuan <aries@Mac.local>
This commit is contained in:
2118
frontend/package-lock.json
generated
2118
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-markdown": "6.2.3",
|
"@codemirror/lang-markdown": "6.2.3",
|
||||||
"@codemirror/language-data": "6.3.1",
|
"@codemirror/language-data": "6.3.1",
|
||||||
"@codemirror/view": "6.22.1",
|
"@codemirror/view": "^6.34.1",
|
||||||
"@emoji-mart/data": "^1.2.1",
|
"@emoji-mart/data": "^1.2.1",
|
||||||
"@emoji-mart/react": "^1.1.1",
|
"@emoji-mart/react": "^1.1.1",
|
||||||
"@gatsbyjs/reach-router": "1.3.9",
|
"@gatsbyjs/reach-router": "1.3.9",
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
"@seafile/seafile-editor": "^1.0.122",
|
"@seafile/seafile-editor": "^1.0.122",
|
||||||
"@seafile/sf-metadata-ui-component": "^0.0.45",
|
"@seafile/sf-metadata-ui-component": "^0.0.45",
|
||||||
"@uiw/codemirror-extensions-langs": "^4.19.4",
|
"@uiw/codemirror-extensions-langs": "^4.19.4",
|
||||||
|
"@uiw/codemirror-themes": "^4.23.5",
|
||||||
"@uiw/react-codemirror": "^4.19.4",
|
"@uiw/react-codemirror": "^4.19.4",
|
||||||
"axios": "^1.7.4",
|
"axios": "^1.7.4",
|
||||||
"chart.js": "3.6.0",
|
"chart.js": "3.6.0",
|
||||||
|
@@ -1,11 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import CodeMirror from '@uiw/react-codemirror';
|
import CodeMirror from '@uiw/react-codemirror';
|
||||||
import { EditorView } from '@codemirror/view';
|
import { getLanguageExtensions } from './languages';
|
||||||
import { loadLanguage } from '@uiw/codemirror-extensions-langs';
|
import { myTheme } from './theme';
|
||||||
import { Utils } from '../../utils/utils';
|
|
||||||
|
|
||||||
import './style.css';
|
|
||||||
|
|
||||||
const DEFAULT_CODEMIRROR_OPTIONS = {
|
const DEFAULT_CODEMIRROR_OPTIONS = {
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
@@ -31,41 +28,21 @@ class SeafileCodeMirror extends React.Component {
|
|||||||
this.options = null;
|
this.options = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getOptions = () => {
|
|
||||||
if (this.options) return this.options;
|
|
||||||
|
|
||||||
const { fileExt, readOnly } = this.props;
|
|
||||||
const mode = Utils.chooseLanguage(fileExt);
|
|
||||||
const extensions = loadLanguage(mode);
|
|
||||||
if (extensions) {
|
|
||||||
return {
|
|
||||||
theme: 'light',
|
|
||||||
readOnly: readOnly,
|
|
||||||
extensions: extensions,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
theme: 'light',
|
|
||||||
readOnly: readOnly,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
onChange = (value) => {
|
onChange = (value) => {
|
||||||
this.props.onChange && this.props.onChange(value);
|
this.props.onChange && this.props.onChange(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { value } = this.props;
|
const { value, readOnly, fileExt } = this.props;
|
||||||
const options = this.getOptions();
|
|
||||||
return (
|
return (
|
||||||
<div className='seafile-code-mirror-container'>
|
<div className='seafile-code-mirror-container'>
|
||||||
<CodeMirror
|
<CodeMirror
|
||||||
ref="code-mirror-editor"
|
|
||||||
value={value}
|
value={value}
|
||||||
{...options}
|
|
||||||
onChange={this.onChange}
|
|
||||||
basicSetup={DEFAULT_CODEMIRROR_OPTIONS}
|
basicSetup={DEFAULT_CODEMIRROR_OPTIONS}
|
||||||
extensions={[EditorView.lineWrapping]}
|
theme={myTheme}
|
||||||
|
readOnly={readOnly}
|
||||||
|
extensions={[...getLanguageExtensions(fileExt)]}
|
||||||
|
onChange={this.onChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
30
frontend/src/components/seafile-codemirror/languages.js
Normal file
30
frontend/src/components/seafile-codemirror/languages.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { python } from '@codemirror/lang-python';
|
||||||
|
import { javascript } from '@codemirror/lang-javascript';
|
||||||
|
import { cpp } from '@codemirror/lang-cpp';
|
||||||
|
import { java } from '@codemirror/lang-java';
|
||||||
|
import { shell } from '@codemirror/legacy-modes/mode/shell';
|
||||||
|
import { html } from '@codemirror/lang-html';
|
||||||
|
import { loadLanguage } from '@uiw/codemirror-extensions-langs';
|
||||||
|
import { Utils } from '../../utils/utils';
|
||||||
|
|
||||||
|
export const getLanguageExtensions = (fileExt) => {
|
||||||
|
const mode = Utils.chooseLanguage(fileExt);
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case 'javascript':
|
||||||
|
return [javascript({ jsx: true })];
|
||||||
|
case 'python':
|
||||||
|
return [python()];
|
||||||
|
case 'cpp':
|
||||||
|
case 'c':
|
||||||
|
return [cpp()];
|
||||||
|
case 'java':
|
||||||
|
return [java()];
|
||||||
|
case 'shell':
|
||||||
|
return [shell()];
|
||||||
|
case 'html':
|
||||||
|
return [html()];
|
||||||
|
default:
|
||||||
|
return [loadLanguage(mode)];
|
||||||
|
}
|
||||||
|
};
|
70
frontend/src/components/seafile-codemirror/theme.js
Normal file
70
frontend/src/components/seafile-codemirror/theme.js
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
import { tags as t } from '@lezer/highlight';
|
||||||
|
import { createTheme } from '@uiw/codemirror-themes';
|
||||||
|
|
||||||
|
import './style.css';
|
||||||
|
|
||||||
|
export const myTheme = createTheme({
|
||||||
|
theme: 'light',
|
||||||
|
settings: {
|
||||||
|
background: '#ffffff',
|
||||||
|
foreground: '#383a42',
|
||||||
|
caret: '#000',
|
||||||
|
selection: '#add6ff',
|
||||||
|
selectionMatch: '#a8ac94',
|
||||||
|
lineHighlight: '#99999926',
|
||||||
|
gutterBackground: '#fff',
|
||||||
|
gutterForeground: '#237893',
|
||||||
|
gutterActiveForeground: '#0b216f',
|
||||||
|
fontFamily: 'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace',
|
||||||
|
},
|
||||||
|
styles: [
|
||||||
|
{
|
||||||
|
tag: [
|
||||||
|
t.keyword,
|
||||||
|
t.operatorKeyword,
|
||||||
|
t.modifier,
|
||||||
|
t.color,
|
||||||
|
t.constant(t.name),
|
||||||
|
t.standard(t.name),
|
||||||
|
t.standard(t.tagName),
|
||||||
|
t.special(t.brace),
|
||||||
|
t.atom,
|
||||||
|
t.bool,
|
||||||
|
t.special(t.variableName),
|
||||||
|
],
|
||||||
|
color: '#0000ff',
|
||||||
|
},
|
||||||
|
{ tag: [t.moduleKeyword, t.controlKeyword], color: '#af00db' },
|
||||||
|
{
|
||||||
|
tag: [
|
||||||
|
t.name,
|
||||||
|
t.deleted,
|
||||||
|
t.character,
|
||||||
|
t.macroName,
|
||||||
|
t.propertyName,
|
||||||
|
t.variableName,
|
||||||
|
t.labelName,
|
||||||
|
t.definition(t.name),
|
||||||
|
],
|
||||||
|
color: '#0070c1',
|
||||||
|
},
|
||||||
|
{ tag: t.heading, fontWeight: 'bold', color: '#0070c1' },
|
||||||
|
{
|
||||||
|
tag: [t.typeName, t.className, t.tagName, t.number, t.changed, t.annotation, t.self, t.namespace],
|
||||||
|
color: '#267f99',
|
||||||
|
},
|
||||||
|
{ tag: [t.function(t.variableName), t.function(t.propertyName)], color: '#795e26' },
|
||||||
|
{ tag: [t.number], color: '#098658' },
|
||||||
|
{ tag: [t.operator, t.punctuation, t.separator, t.url, t.escape, t.regexp], color: '#383a42' },
|
||||||
|
{ tag: [t.regexp], color: '#af00db' },
|
||||||
|
{ tag: [t.special(t.string), t.processingInstruction, t.string, t.inserted], color: '#a31515' },
|
||||||
|
{ tag: [t.angleBracket], color: '#383a42' },
|
||||||
|
{ tag: t.strong, fontWeight: 'bold' },
|
||||||
|
{ tag: t.emphasis, fontStyle: 'italic' },
|
||||||
|
{ tag: t.strikethrough, textDecoration: 'line-through' },
|
||||||
|
{ tag: [t.meta, t.comment], color: '#008000' },
|
||||||
|
{ tag: t.link, color: '#4078f2', textDecoration: 'underline' },
|
||||||
|
{ tag: t.invalid, color: '#e45649' },
|
||||||
|
],
|
||||||
|
});
|
Reference in New Issue
Block a user