Reputation: 9560
import React, { Component } from "react";
import { render } from "react-dom";
import CodeMirror from "react-codemirror";
import "./style.css";
import "codemirror/lib/codemirror.css";
class App extends Component {
constructor() {
super();
this.state = {
name: "CodeMirror",
code: "Hello world Code Mirror"
};
}
updateCode(newCode) {
this.setState({
code: newCode
});
}
render() {
let options = {
lineNumbers: true
};
return (
<div>
<p>Start editing to see some magic happen :)</p>
<CodeMirror
value={this.state.code}
onChange={this.updateCode.bind(this)}
options={options}
/>
</div>
);
}
}
render(<App />, document.getElementById("root"));
I'm working on a tokenizer and want to highlight a specific token from the code.
How to underline or bold a specific token, like world
text in this case?
Or is there any other code editor library which can highlight any substring given start and end index?
Upvotes: 0
Views: 1706
Reputation: 21
Unfortunately, the most documented way of doing this (overlayMode
) does not work for CodeMirror 6.
The way to do this in CodeMirror 6 is to create a custom view plugin like this.
import { MatchDecorator, ViewPlugin, Decoration } from "@codemirror/view";
let worldDeco = Decoration.mark({ class: "world" }); // This adds a className to the text that matches the regex.
let decorator = new MatchDecorator({
regexp: /(world)/g,
decoration: (m) => worldDeco,
});
export const customPlugin = ViewPlugin.define(
(view) => ({
decorations: decorator.createDeco(view),
update(u) {
this.decorations = decorator.updateDeco(u, this.decorations);
},
}),
{
decorations: (v) => v.decorations,
}
);
And then you can go ahead and change styles like so
.world {
color: #e06c75;
font-weight: bold;
}
Last step is to hookup the plugin into your Editor view along with other extensions
let view = new EditorView({
extensions: [basicSetup, customPlugin, javascript()],
parent: document.body
})
Upvotes: 2
Reputation: 1213
You can achieve this by using CodeMirror.overlayMode
. You need to define your own mode that will parse codemirror's content and set some class to your custom tokens.
Let's say that you define your mode in the customHighlightsMode.js file:
import CodeMirror from 'codemirror';
import 'codemirror/addon/mode/overlay';
CodeMirror.defineMode("customHighlights", function (config, parserConfig) {
var myOverlay = {
token: function (stream) {
if (stream.match(/(world)/)) {
return 'custom-keyword';
} else {
stream.next();
return null;
}
}
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop), myOverlay);
});
Then you need to set a class with styles for your tokens:
.cm-custom-keyword {
font-weight: bold;
color: red;
}
And then you need to set your mode in the CodeMirror options:
import React, { Component } from "react";
import CodeMirror from "react-codemirror";
import "codemirror/lib/codemirror.css";
import "./style.css"; // add .cm-custom-keyword class here
import "./customHighlightsMode";
class App extends Component {
constructor() {
super();
this.state = {
name: "CodeMirror",
code: "Hello world Code Mirror"
};
}
updateCode(newCode) {
this.setState({
code: newCode
});
}
render() {
let options = {
lineNumbers: true,
mode: { name: "customHighlights" },
};
return (
<div>
<p>Start editing to see some magic happen :)</p>
<CodeMirror
value={this.state.code}
onChange={this.updateCode.bind(this)}
options={options}
/>
</div>
);
}
}
Upvotes: 1