reject or modify all changes that put buffer into inconsistent state

Consider a Lisp like language, where we always want balanced () [] {}.

A first step to this is: insert “()” instead of “(”, insert "[]’ instead of “[”, insert “{}” instead of “{”.

However, we need something a bit more. For example, it should be impossible to paste the string “ab ( + 2 3” because it does not have balanced ()'s.

Similarly, if we try to delete “ab ) 2 3” it should either fail or replace the string with a “)”.

The question here now is: at what layer / where in the CodeMirror config to we inject this “validation / modification” logic?

I.e. I want something that gets to see every “diff” that happens to the buffer and then either rejects or modifies the invalid ones.

So I think the simplest way to do this is to override the dispatch fn, but after seeing how complex the transactions can be, I’m no long sure this is a right approach.

I think here is the logic I want to express:

If the old editor state is a valid lezer parse, and the new editor state would be an invalid editor state, then reject.

The problem here is that this requires we first construct the new editor state, then decide whether to go through with the transaction … all in the dispatch fn.

Is this the right approach? My current idea above is:

  1. if we are currently in an invalid lezer state, let the user do whatever they want, as they’re probably trying to fix something (might be the case the file we loaded is in invalid lezer parser)

  2. if we are currently in a valid lezer state, only let the transaction through if the new state is also valid, but this requires that we, in the dispatch fn, construct the new editor state & try to parse it

Is this the right approach, or is something else better ?

The best layer at which to do this is probably a transaction filter.

1 Like