Skip to content

Commit bb59fab

Browse files
committed
1 parent 3f60a67 commit bb59fab

File tree

7 files changed

+66
-5
lines changed

7 files changed

+66
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
==================
33
* (`onValueSet`, `onValueChange`) deprecated, now => (`onSet`, `onChange`);
44
* + (`onBeforeChange`, `onBeforeSet`)
5-
5+
* + `defineMode`

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ require('codemirror/mode/javascript/javascript');
5252
> `boolean` reset the internal codemirror cursor position should a new `value` prop be set. Default: `false`
5353
- `autoScrollCursorOnSet`
5454
> `boolean` scroll the cursor position into view automatically. Default: `false`
55+
- `defineMode`
56+
> pass a custom mode object `{name: 'custom', fn: myModeFn}`
5557
5658
## props cont. (wrapped codemirror [programming api](https://codemirror.net/doc/manual.html#api))
5759

docs/app.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/src/components/Controls.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Controls extends React.Component {
2626
<select value={this.props.mode} onChange={this.onModeSelect.bind(this)}>
2727
<option value='xml'>html</option>
2828
<option value='javascript'>javascript</option>
29+
<option value='strings'>strings (custom)</option>
2930
</select>
3031
</div>
3132
)

docs/src/components/Editor.jsx

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,35 @@ import CodeMirror from '../../../index.js';
55
let jBeautify = require('js-beautify').js;
66
let hBeautify = require('js-beautify').html;
77

8+
// http://marijnhaverbeke.nl/blog/codemirror-mode-system.html
9+
let sampleMode = () => {
10+
return {
11+
startState: function () {
12+
return {inString: false};
13+
},
14+
token: function (stream, state) {
15+
// If a string starts here
16+
if (!state.inString && stream.peek() == '"') {
17+
stream.next(); // Skip quote
18+
state.inString = true; // Update state
19+
}
20+
21+
if (state.inString) {
22+
if (stream.skipTo('"')) { // Quote found on this line
23+
stream.next(); // Skip quote
24+
state.inString = false; // Clear flag
25+
} else {
26+
stream.skipToEnd(); // Rest of line is string
27+
}
28+
return "string"; // Token style
29+
} else {
30+
stream.skipTo('"') || stream.skipToEnd();
31+
return null; // Unstyled token
32+
}
33+
}
34+
};
35+
}
36+
837
class Editor extends React.Component {
938

1039
constructor(props) {
@@ -15,13 +44,30 @@ class Editor extends React.Component {
1544

1645
let exampleJS = 'function StringStream(string) { this.pos = 0; this.string = string; } StringStream.prototype = { done: function() {return this.pos >= this.string.length;}, peek: function() {return this.string.charAt(this.pos);}, next: function() { if (this.pos < this.string.length) return this.string.charAt(this.pos++); }, eat: function(match) { var ch = this.string.charAt(this.pos); if (typeof match == "string") var ok = ch == match; else var ok = ch && match.test ? match.test(ch) : match(ch); if (ok) {this.pos++; return ch;} }, eatWhile: function(match) { var start = this.pos; while (this.eat(match)); if (this.pos > start) return this.string.slice(start, this.pos); }, backUp: function(n) {this.pos -= n;}, column: function() {return this.pos;}, eatSpace: function() { var start = this.pos; while (/s/.test(this.string.charAt(this.pos))) this.pos++; return this.pos - start; }, match: function(pattern, consume, caseInsensitive) { if (typeof pattern == "string") { function cased(str) {return caseInsensitive ? str.toLowerCase() : str;} if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) { if (consume !== false) this.pos += str.length; return true; } } else { var match = this.string.slice(this.pos).match(pattern); if (match && consume !== false) this.pos += match[0].length; return match; } } };';
1746
this.defaultJS = jBeautify(exampleJS, {indent_size: 2});
47+
48+
this.exampleCustomModeStrings = 'only "double quotes" will be tokenized\n\nsee http://marijnhaverbeke.nl/blog/codemirror-mode-system.html'
1849
}
1950

2051
render() {
2152

53+
let value = '';
54+
55+
switch (this.props.mode) {
56+
case 'xml':
57+
value = this.defaultHTML;
58+
break;
59+
case 'javascript':
60+
value = this.defaultJS;
61+
break;
62+
case 'strings':
63+
value = this.exampleCustomModeStrings;
64+
break;
65+
}
66+
2267
return (
2368
<CodeMirror
24-
value={this.props.mode === 'xml' ? this.defaultHTML : this.defaultJS}
69+
value={value}
70+
defineMode={{name: 'strings', fn: sampleMode}}
2571
options={{
2672
mode: this.props.mode,
2773
theme: this.props.theme,

index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ var CodeMirror = function (_React$Component) {
7272
}
7373
/* end deprecation warnings per 1.0.0 release */
7474

75+
if (this.props.defineMode) {
76+
if (this.props.defineMode.name && this.props.defineMode.fn) {
77+
codemirror.defineMode(this.props.defineMode.name, this.props.defineMode.fn);
78+
}
79+
}
80+
7581
this.editor = codemirror(this.ref);
7682

7783
this.editor.on('beforeChange', function (cm, changeObj) {

src/react-codemirror2.jsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,21 @@ export default class CodeMirror extends React.Component {
3636
componentDidMount() {
3737

3838
/* deprecation warnings per 1.0.0 release */
39-
if(this.props.onValueChange) {
39+
if (this.props.onValueChange) {
4040
console.warn('`onValueChange` has been deprecated. Please use `onChange` instead');
4141
}
4242

43-
if(this.props.onValueSet) {
43+
if (this.props.onValueSet) {
4444
console.warn('`onValueSet` has been deprecated. Please use `onSet` instead');
4545
}
4646
/* end deprecation warnings per 1.0.0 release */
4747

48+
if (this.props.defineMode) {
49+
if (this.props.defineMode.name && this.props.defineMode.fn) {
50+
codemirror.defineMode(this.props.defineMode.name, this.props.defineMode.fn);
51+
}
52+
}
53+
4854
this.editor = codemirror(this.ref);
4955

5056
this.editor.on('beforeChange', (cm, changeObj) => {

0 commit comments

Comments
 (0)