Finding transaction effects which are the result of compartment reconfiguration

I’m using CodeMirror as part of a ProseMirror NodeView. My CodeMirror editor has a Compartment which contains the language/syntax for the code, and we dispatch compartment.reconfigure() effects when the user changes the language. When translating the CodeMirror transaction into changes in the ProseMirror model, I need to look through the transaction for these effects and turn them into node attribute updates.

However, I can’t find what feels like “the right way” to detect these effects. It seems like I should be using StateEffect.is() to determine which effects are from changes to the language compartments. But I what am I supposed to pass as an argument to this function? Since I haven’t defined a type myself (i.e. using StateEffect.define()), I don’t have anything at hand. Is there some way to go from a Compartment instance to a StateEffect type? Or so I need to define a custom StateEffect and somehow use it when dispatching the compartment reconfigurations?

You can either add a custom annotation to your language-changing transactions that simply tells what they are doing, or compare the language facet, comparing its old and new values to figure out if the language was changed.

1 Like

I implemented the comparison of the old and new language facets, and this almost works. The problem I’m running into is that names on these Language objects are a subset of the names on the LanguageDesecriptions. That is, my language selector control populates itself based on the names in language-data.languages, so it includes e.g. “C” and “C++”. However, the Language objects in the facets only have a “C++” name; there is no separate “C” language at that level. As a result, when the user selects “C” at the codemirror level, by the time I’m producing a prosemirror transaction, I’ll end up reporting “C++” since that’s the Language associated with the C LanguageDescription.

That’s confusing even to describe, so I feel like maybe I’ve just got the wrong end of the stick. When I’m producing the ProseMirror transaction based on comparison of Language objects, how can I differentiate between C and C++ (or JavaScript and JSX, or other “shared” languages)? The only approach I can really see is to store the selected name in the editor state along with the language compartment, but this feels cumbersome.

Language object don’t really describe their origins (there isn’t really a vocabulary for that in the library), so I guess adding a facet that describes the language along with it is what you want to do here.

1 Like