-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hints? #52
Comments
I have found a way to use hint. // 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; and the file
also need a bit rearrange. // show-hint.js
// remove this part
/*
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})
*/
var showHint = function (CodeMirror) {
/*
contents remain unchanged.
*/
}
module.exports = showHint; and then you can use 'Tab' key to fire a hint. |
@desduvauchelle Did the above response solved the issue? I'm wondering can we close it. |
@yakewdx is there a way to show the autocomplete dropdown automatically on every key stroke? |
@ankitgoyal100
So you can change a bit of the source code of react-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();
}, and also in // 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} />
} If you want to handle other original events of codemirror, by the way, if you want to autocomplete by every keystroke, var defaultOptions = {
hint: CodeMirror.hint.auto,
completeSingle: false,
alignWithWord: true,
closeCharacters: /[\s()\[\]{};:>,]/,
closeOnUnfocus: true,
completeOnSingleClick: false,
container: null,
customKeys: null,
extraKeys: null
}; Hope this helps. |
I was able to get a built-in codemirror hints working and configured without modifying any of the react-codemirror or codemirror files, and figured I'd share. Assuming you have a webpack/create-react-app setup you can do: '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}
/>
);
}
} |
@rickbergfalk does the dropdown with options get shown ? I made it somehow working, it auto-completes a word, but the dropdown with options never appears. |
@JakubKahovec It should... I ran into similar issues. A couple things to check:
|
@rickbergfalk I've double checked show-hint css is there (it appears as an inline css) and completeSingle is false. The only thing is I don't use create-react-app, but have my own stack. The code is almost identical to yours, the only difference is I use javascript hint. When I press Ctrl-Space nothing appears but when then I press Tab it completes the word with some random word (i.e 'f' completes with 'find'). When I debug it it jumps into the autoComplete, calls codeMirror.showHint but the popup does not appear. |
@rickbergfalk finally got it. I had the codemirror editor in a modal window (semantic ui) so the hints popup was hidden behind it. Setting z-index to max on hints popup fixed it. |
`autoComplete = cm => {
Worked for me |
Hello.
Thanks for this!
Is it possible to use code hints?
If yes, could you provide an example?
Thanks!
The text was updated successfully, but these errors were encountered: