1 // Highlighting text that matches the selection
3 // Defines an option highlightSelectionMatches, which, when enabled,
4 // will style strings that match the selection throughout the
7 // The option can be set to true to simply enable it, or to a
8 // {minChars, style} object to explicitly configure it. minChars is
9 // the minimum amount of characters that should be selected for the
10 // behavior to occur, and style is the token style to apply to the
11 // matches. This will be prefixed by "cm-" to create an actual CSS
15 var DEFAULT_MIN_CHARS
= 2;
16 var DEFAULT_TOKEN_STYLE
= "matchhighlight";
18 function State(options
) {
19 this.minChars
= typeof options
== "object" && options
.minChars
|| DEFAULT_MIN_CHARS
;
20 this.style
= typeof options
== "object" && options
.style
|| DEFAULT_TOKEN_STYLE
;
24 CodeMirror
.defineOption("highlightSelectionMatches", false, function(cm
, val
, old
) {
25 var prev
= old
&& old
!= CodeMirror
.Init
;
27 cm
.state
.matchHighlighter
= new State(val
);
28 cm
.on("cursorActivity", highlightMatches
);
29 } else if (!val
&& prev
) {
30 var over
= cm
.state
.matchHighlighter
.overlay
;
31 if (over
) cm
.removeOverlay(over
);
32 cm
.state
.matchHighlighter
= null;
33 cm
.off("cursorActivity", highlightMatches
);
37 function highlightMatches(cm
) {
38 cm
.operation(function() {
39 var state
= cm
.state
.matchHighlighter
;
41 cm
.removeOverlay(state
.overlay
);
45 if (!cm
.somethingSelected()) return;
46 var selection
= cm
.getSelection().replace(/^\s+|\s+$/g, "");
47 if (selection
.length
< state
.minChars
) return;
49 cm
.addOverlay(state
.overlay
= makeOverlay(selection
, state
.style
));
53 function makeOverlay(query
, style
) {
54 return {token: function(stream
) {
55 if (stream
.match(query
)) return style
;
57 stream
.skipTo(query
.charAt(0)) || stream
.skipToEnd();