1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-05-14 14:25:29 +02:00
php-web-maker/src/components/UserCodeMirror.jsx

175 lines
5.2 KiB
JavaScript

import { h, Component } from 'preact';
import CodeMirror from '../CodeMirror';
import 'codemirror/addon/edit/matchbrackets.js';
import 'codemirror/addon/edit/matchtags.js';
import 'codemirror/addon/edit/closebrackets.js';
import 'codemirror/addon/edit/closetag.js';
import 'codemirror/addon/comment/comment.js';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/foldgutter.js';
import 'codemirror/addon/fold/xml-fold.js';
import 'codemirror/addon/fold/indent-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
import 'codemirror/addon/fold/brace-fold.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/javascript-hint.js';
import 'codemirror/addon/hint/xml-hint.js';
import 'codemirror/addon/hint/html-hint.js';
import 'codemirror/addon/hint/css-hint.js';
import 'codemirror/addon/selection/active-line.js';
import 'codemirror/addon/search/searchcursor.js';
import 'codemirror/addon/search/search.js';
import 'codemirror/addon/dialog/dialog.js';
import 'codemirror/addon/search/jump-to-line.js';
import 'codemirror/mode/xml/xml.js';
import 'codemirror/mode/css/css.js';
import 'codemirror/mode/javascript/javascript.js';
import 'codemirror/mode/htmlmixed/htmlmixed.js';
import 'codemirror/keymap/sublime.js';
import 'codemirror/keymap/vim.js';
import 'code-blast-codemirror/code-blast.js';
import emmet from '@emmetio/codemirror-plugin';
import { prettify } from '../utils';
emmet(CodeMirror);
export default class UserCodeMirror extends Component {
componentDidMount() {
this.initEditor();
}
shouldComponentUpdate(nextProps) {
if (nextProps.prefs !== this.props.prefs) {
const { prefs } = nextProps;
this.cm.setOption('indentWithTabs', prefs.indentWith !== 'spaces');
this.cm.setOption(
'blastCode',
prefs.isCodeBlastOn ? { effect: 2, shake: false } : false
);
this.cm.setOption('theme', prefs.editorTheme);
this.cm.setOption('indentUnit', +prefs.indentSize);
this.cm.setOption('tabSize', +prefs.indentSize);
this.cm.setOption('keyMap', prefs.keymap);
this.cm.setOption('lineWrapping', prefs.lineWrap);
this.cm.refresh();
}
return false;
}
initEditor() {
const { options, prefs } = this.props;
this.cm = CodeMirror.fromTextArea(this.textarea, {
mode: options.mode,
lineNumbers: true,
lineWrapping: !!prefs.lineWrap,
autofocus: options.autofocus || false,
autoCloseBrackets: true,
autoCloseTags: true,
matchBrackets: true,
matchTags: options.matchTags || false,
tabMode: 'indent',
keyMap: prefs.keyMap || 'sublime',
theme: prefs.editorTheme || 'monokai',
lint: !!options.lint,
tabSize: +prefs.indentSize || 2,
indentWithTabs: prefs.indentWith !== 'spaces',
indentUnit: +prefs.indentSize,
foldGutter: true,
styleActiveLine: true,
gutters: options.gutters || [],
// cursorScrollMargin: '20', has issue with scrolling
profile: options.profile || '',
extraKeys: {
Up: function(editor) {
// Stop up/down keys default behavior when saveditempane is open
// if (isSavedItemsPaneOpen) {
// return;
// }
CodeMirror.commands.goLineUp(editor);
},
Down: function(editor) {
// if (isSavedItemsPaneOpen) {
// return;
// }
CodeMirror.commands.goLineDown(editor);
},
'Shift-Tab': function(editor) {
if (options.prettier) {
prettify({
content: editor.getValue(),
type: options.prettierParser
}).then(formattedCode => editor.setValue(formattedCode));
} else {
CodeMirror.commands.indentAuto(editor);
}
},
Tab: function(editor) {
if (options.emmet) {
const didEmmetWork = editor.execCommand('emmetExpandAbbreviation');
if (didEmmetWork === true) {
return;
}
}
const input = $('[data-setting=indentWith]:checked');
if (
!editor.somethingSelected() &&
(!prefs.indentWith || prefs.indentWith === 'spaces')
) {
// softtabs adds spaces. This is required because by default tab key will put tab, but we want
// to indent with spaces if `spaces` is preferred mode of indentation.
// `somethingSelected` needs to be checked otherwise, all selected code is replaced with softtab.
CodeMirror.commands.insertSoftTab(editor);
} else {
CodeMirror.commands.defaultTab(editor);
}
},
Enter: 'emmetInsertLineBreak'
}
});
this.cm.on('focus', editor => {
if (typeof this.props.onFocus === 'function') this.props.onFocus(editor);
});
this.cm.on('change', this.props.onChange);
this.cm.addKeyMap({
'Ctrl-Space': 'autocomplete'
});
this.cm.on('inputRead', (editor, input) => {
// Process further If this has autocompletition on and also the global
// autocomplete setting is on.
if (!this.props.options.noAutocomplete && this.props.prefs.autoComplete) {
if (
input.origin !== '+input' ||
input.text[0] === ';' ||
input.text[0] === ',' ||
input.text[0] === ' '
) {
return;
}
CodeMirror.commands.autocomplete(this.cm, null, {
completeSingle: false
});
}
});
this.props.onCreation(this.cm);
}
render() {
return (
<textarea
ref={el => (this.textarea = el)}
name=""
id=""
cols="30"
rows="10"
/>
);
}
}