Bracket matching in mode

I realize there is a bracket matching addon, but its not quite what I want and I haven’t been able to adapt it to my needs.

I want to be able to highlight matching brackets in the mode, and highlight the ones that don’t have a matching counterpart as well. My initial idea was to do this in the mode but it has proven difficult, as there is no way to change the state of a token once its been parsed.

Is it possible to store a token in the state which can then be modified later in the mode? Or perhaps a second pass of some sort?

Thanks in advance.

I suspect you or your colleague also asked me the same question over direct mail. And through gitter. So that’s too many channels – ask once, then have some patience please.

Modes highlight once, not dynamically. You can base a mode’s highlighting on what came before, using state, but not on what comes after. If you need dynamic highlighting, use the markText method.

Thanks for the response. The issue was rather that I was unsure which communication channel was active and which wasn’t, but now I know both are.

Is it possible to use the markText method in the mode or would it be better suited as a separate addon that does the parsing for me?

Modes are just tokenizers. Don’t try to make them do anything imperative like calling markText.

Alright, thank you. I have created an addon that does the job :smile:

I ran into an issue with my addon: there seems to be race condition between it and the mode. I assume the mode has not yet finished parsing the document before the addon is ran and thus the outcome is not accurate as the mode has yet not identified all the tokens in the document (which the addon needs to know whats what).

The only way I have managed to solve this is to defer the execution of the addon, which is not pretty (since you’ll actually see the slight delay). Is there another way of doing this?

Another thing that crossed my mind just now is that this will never work if I try to run the mode outside of the editor, since the addon won’t be ran. Do you have any suggestions on how this issue can be solved in a different manner?

See the second argument to getTokenAt and getLineTokens.

As for running this outside of the editor, no, that obviously won’t work.

Is there no way to keep the logic inside of the mode? The only thing that is missing is “moving backwards” in the mode - just allowing tokens to be modified later on in the mode.

I assume that codemirror keeps track of all the tokens that have been styled and when there are no more tokens to be styled left, it pushes the changes to the DOM. Would it be possible to allow the mode to have a reference to these tokens so that you can in the mode state keep track of which tokens need a second pass or something?

Ideally what I would want would be to keep an array of bracket tokens in my state (a reference to an object or whatever) which I can loop over and style accordingly. This does end up looking more like a parser, which it is, but I don’t know how to integrate a parser with the mode so I’m a bit lost unfortunately.

No, and this is not going to happen. CodeMirror modes are strictly linear parses, and that fact is relied on to optimize highlighting.

Okay. Is there a way to abstract the parser out into its own class and have codemirror use that instead? Then that parser can keep all the logic and the mode simply asks it for token styling.

You can do that, I guess, since a mode can wrap whatever it wants, but it’s not generally a very good idea.

Care to elaborate? How would you solve this problem if you wanted the mode to be able to run outside of the editor?

To clarify: I want to be able to do a second pass over a specific set of tokens.

Nope, I don’t really have the time and energy to solve everybody’s tangentially-CodeMirror related problems, sorry.

I’m really not asking you to write any code for me, just point me in the right direction. I assumed you would know what would be the best approach seeing as how you designed the library.

If it is a question about money I am willing to pay you for your help.

Money does help. If you could shoot me an email with your requirements (especially how you’re envisioning this outside-CodeMirror use) I’ll get back to you with an offer.