mirror of
https://github.com/chinchang/web-maker.git
synced 2025-05-14 14:25:29 +02:00
175 lines
5.2 KiB
JavaScript
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"
|
|
/>
|
|
);
|
|
}
|
|
}
|