marijnh/CodeMirror — pull request #1069 by mightyguava (2012-12-09 17:36:44+00:00)
Title: [vim keymap] Search highlighting using overlay mode

### Motivation

A big gripe I had about search in CodeMirror was that if you search for something, edit the file, and then insert some text that match your previous query, it doesn't get highlighted. Doing `findNext` will find it, but won't highlight it.

I attempted to avoid this in the vim keymap by redoing highlighting on findNext, but that was too expensive for short terms like `a` or `i`, though ok for long terms on a 2000 line file. It still isn't good enough since it won't highlight as you type.

I put some thought into highlighting only the current viewport, then listening to `viewportChange` and `change` events on CodeMirror to update highlights. But after thinking about how to implement this properly for a while, I realized that what I wanted actually aligned pretty well with modes.

### Search overlay mode

When a search is activated in Vim, an overlay mode is created, combining the search highlighting and the current file's mode. CodeMirror takes over seeking through the document and updating highlights. CodeMirror's awesome mode system also takes over highlighting matches as you type them and clearing highlights when terms no longer match. All Vim does is tell CodeMirror what to highlight.

Of course, there are a few issues with this approach:

- Vim is swapping out the mode the user specified with another mode. While the impacts are minimal from the user's perspective, it's not quite elegant
* I try to mitigate problems by keeping track of the mode that was swapped out, and restoring the mode when highlighting is cleared
* There's still the issue that modes have configuration options. Vim has no way to get at these options, so Vim has no way to restore them when search highlight is cleared. This is very bad if there are multiple `cm` instances around with different options but the same mode.
- Highlighting lags a bit (< 200ms) when the mode is swapped, probably because CodeMirror's mode parsing runs on a timeout. It's a tiny, acceptable lag though, at least to me.

### Request

The consistency issues (losing configuration) with swapping modes could be avoided if there was a way to restore the base mode on CodeMirror using a setMode() function rather than using setOption('mode', baseMode).