Re-highlighting from beginning; event on highlight finish?

Hi! I’ve written a custom mode for CM.

I have two problems:

  1. To highlight a procedure call correctly, I have to parse its definition first. But the definition may appear anywhere in the document—even after the procedure call.

  2. I want to compile the language in the browser. Since the editor’s already done some of the parsing, it’d be easiest to pick up the state object from the parser, once it’s highlighted the entire thing.

Does CM always highlight to the end of the document, or does it only go as far as is needed? A “highlighting reached end of document” event could make both of the above easier. But I’m suspicious that it’s the latter. If so, is there there maybe an asynchronous version of getStateAfter() which I could use to do the compilation (2)?

I could implement (1) by restarting parsing every time I see a definition—but that would be accidentally quadratic. Is there a better way? Setting to zero appears to make CM re-highlight previous lines, but it only seems to take effect on the next change event.

Procedure calls are standalone lines beginning with a known keyword, so if there’s a way to process the entire document before CM highlights it, that might make (1) easier.

Thanks for any thoughts! :)

Oops, just noticed getStateAfter allows no line number!

Returns the mode’s parser state, if any, at the end of the given line number. If no line number is given, the state at the end of the document is returned. This can be useful for storing parsing errors in the state, or getting other kinds of contextual information for a line. precise is defined as in getTokenAt().

And I should have checked the definition of precise:

If precise is true, the token will be guaranteed to be accurate based on recent edits. If false or not specified, the token will use cached state information, which will be faster but might not be accurate if edits were recently made and highlighting has not yet completed.

So I should be able to call getStateAfter(undefined, false) to check if there are new procedures defined; and then call getStateAfter(undefined, true) to re-parse the entire document. Will that also re-highlight it?

I’d still like an async version for compilation: is there such a thing? :slight_smile:

There is no async version. I would actually recommend that you don’t try to use the mode for compiling – it is probably a good idea to share code between the parser you use for compilation and the CodeMirror mode, but call that parser separately when compiling. You won’t save much CPU time by trying to combine the two passes, since they have very different characteristics (CodeMirror conservatively re-parses only the minimum needed to color the visible part of the document, a compiler needs to parse the whole thing).

That’s good advice, thanks very much!

Any idea how I can detect procedure definitions changing, and cause the whole document to be re-highligted (with the new start state containing the updated list of procedures)? :slight_smile:

You’ll have to watch "change" events and somehow determine whether they change a definition. Forcing a re-highlight can be done by re-setting the mode option using setOption.