Can I apply a Code Mirror overlay outside the definition of a mode? The code below works but seems redundant and slow. I'm defining a mode for each editor/viewer on a page which could be zero to many. How can this be optimized?
Ideally, I would like to define the mode once and then apply the overlay as needed.
I have not been able to find an answer if I can. I want to define a mode (it highlights a search term (see this question)) and then I want to apply that mode to many editors/viewers on a page. Each editor/viewer has a different language and is set on the DOM element (e.g <pre class="sourcecode" language="javascript">code</pr>
).
I think the solution would be something dealing with return CodeMirror.overlayMode(CodeMirror.getMode(config, mode),searchOverlay, true);
but I've been unable to get it to work.
$('.sourcecode').each( function() {
var value = $(this).text(),
search = (typeof keyword === 'undefined') ? false : true,
mode = $(this).attr('language'),
pre = $(this).get(0),
line = ($(this).attr('firstLineNumber') == undefined) ? 1 : parseInt($(this).attr('firstLineNumber'), 10);
// CodeMirror search highlighing
// this seems redundent, slow, and messy
if (search) {
CodeMirror.defineMode("highlightSearch", function(config, parserConfig) {
var searchOverlay = {
token: function(stream, state) {
if (stream.match(keyword)) {
return "highlightSearch";
}
while (stream.next() != null && !stream.match(keyword, false)) {}
return null;
}
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, mode),searchOverlay, true);
});
}
var viewer = CodeMirror(function(elt) {
pre.parentNode.replaceChild(elt, pre);
}, {
value: value,
lineNumbers: true,
firstLineNumber: line,
matchBrackets: true,
lineWrapping: true,
readOnly: true,
mode: (search) ? 'highlightSearch' : mode,
});
});
Thank you for any help.
This is unlikely to be very costly (unless you are creating hundreds of editors per second), but a more elegant solution would be to define your wrapping mode once, and read the inner mode (mode
variable in your code) from its parserConfig
object, say parserConfig.inner
. You'd then simply pass {name: "highlightSearch", inner: mode}
as your mode
option.