// editor.js
var React = require('react');
var Codemirror = require('react-codemirror');
var CodeMirror = React.createClass({
getInitialState: function () {
return {
code: "// Code"
};
},
updateCode: function (newCode) {
this.setState({
code: newCode
});
},
componentDidMount: function () {
"use strict";
let CodeMirror = this.refs['CodeMirror'].getCodeMirrorInstance();
let showHint = require('./show-hint');
showHint(CodeMirror);
/* the part below is copied from anyword-hint.js */
var WORD = /([u4e00-u9fa5]|[a-zA-Z])+/, RANGE = 500;
CodeMirror.registerHelper("hint", "tag", function (editor, options) {
var word = options && options.word || WORD;
var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
var end = cur.ch, start = end;
while (start && word.test(curLine.charAt(start - 1)))--start;
var curWord = start != end && curLine.slice(start, end);
var list = options && options.list || [], seen = {};
var re = new RegExp(word.source, "g");
for (var dir = -1; dir <= 1; dir += 2) {
var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
for (; line != endLine; line += dir) {
var text = editor.getLine(line), m;
while (m = re.exec(text)) {
if (line == cur.line && m[0] === curWord) continue;
if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
seen[m[0]] = true;
list.push(m[0]);
}
}
}
}
return { list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end) };
});
},
autocomplete: function (cm) {
let codeMirror = this.refs['CodeMirror'].getCodeMirrorInstance();
codeMirror.showHint(cm, codeMirror.hint.tag);
},
render: function () {
var options = {
lineNumbers: true,
lineWrapping: true,
extraKeys: {
'Tab': this.autocomplete
}
};
return <Codemirror ref="CodeMirror" value={this.state.code} onChange={this.updateCode} options={options} />
}
});
module.exports.CodeMirror = CodeMirror;
// Codemirror.js
componentDidMount: function componentDidMount() {
var textareaNode = this.refs.textarea;
var codeMirrorInstance = this.getCodeMirrorInstance();
this.codeMirror = codeMirrorInstance.fromTextArea(textareaNode, this.props.options);
this.codeMirror.on('change', this.codemirrorValueChanged);
this.codeMirror.on('focus', this.focusChanged.bind(this, true));
this.codeMirror.on('blur', this.focusChanged.bind(this, false));
// add keyup events
this.codeMirror.on('keyup', this.keyUp.bind(this, true));
this.codeMirror.setValue(this.props.defaultValue || this.props.value || '');
},
keyUp: function (key) {
this.props.onKeyUp();
}
// editor.js
handleKeyUpEvent: function (e) {
let cm = this.refs['CodeMirror'].getCodeMirror();
this.autocomplete(cm);
},
autocomplete: function (cm) {
let codeMirror = this.refs['CodeMirror'].getCodeMirrorInstance();
codeMirror.showHint(cm, codeMirror.hint.tag);
},
render: function () {
var options = {
lineNumbers: true,
lineWrapping: true,
completeSingle: false,
completeOnSingleClick: false,
extraKeys: {
'Tab': this.autocomplete
}
};
return <Codemirror ref="CodeMirror" value={this.state.code} onKeyUp={this.handleKeyUpEvent} onChange={this.updateCode} options={options} />
}
'use es6';
import React, { PureComponent } from 'react';
import CodeMirror from 'react-codemirror';
// assuming a setup with webpack/create-react-app import the additional js/css files
import 'codemirror/mode/sql/sql';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/sql-hint';
import 'codemirror/addon/hint/show-hint.css'; // without this css hints won't show
class CodeEditorField extends PureComponent {
autoComplete = cm => {
const codeMirror = this.refs['CodeMirror'].getCodeMirrorInstance();
// hint options for specific plugin & general show-hint
// 'tables' is sql-hint specific
// 'disableKeywords' is also sql-hint specific, and undocumented but referenced in sql-hint plugin
// Other general hint config, like 'completeSingle' and 'completeOnSingleClick'
// should be specified here and will be honored
const hintOptions = {
tables: {
table_name: ['column1', 'column2', 'column3', 'etc'],
another_table: ['columnA', 'columnB']
},
disableKeywords: true,
completeSingle: false,
completeOnSingleClick: false
};
// codeMirror.hint.sql is defined when importing codemirror/addon/hint/sql-hint
// (this is mentioned in codemirror addon documentation)
// Reference the hint function imported here when including other hint addons
// or supply your own
codeMirror.showHint(cm, codeMirror.hint.sql, hintOptions);
};
handleChange = value => {};
render() {
const options = {
lineNumbers: true,
mode: 'text/x-pgsql',
tabSize: 2,
readOnly: false,
extraKeys: {
'Ctrl-Space': this.autoComplete
}
};
return (
<CodeMirror
ref="CodeMirror"
value={value}
onChange={this.handleChange}
options={options}
/>
);
}
}
This is one of the properties you can set on creating the CodeMirror component, within the options:
render() {
const options = {
mode: this.props.language,
lineNumbers: this.props.lineNumbers,
theme: this.props.theme,
autofocus: false, // not that it's lowercase, from the CodeMirror Docs
hintOptions: {
hint: this.hint,
},
extraKeys: {
'Ctrl-Space': 'autocomplete',
},
};
return (
<div className="cell_editor">
<CodeMirror
value={this.state.source}
ref="codemirror"
className="cell_cm"
options={options}
onChange={this.onChange}
/>
</div>
);
}
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.sql, {
tables: {
"table1": [ "col_A", "col_B", "col_C" ],
"table2": [ "other_columns1", "other_columns2" ]
}
} );
}
更多参见:https://codemirror.net/doc/manual.html#config