CodeMirror 6: Programmatically moving cursor to other editor instance

Hi @marijn, I’m trying to programmatically move the cursor from one editor to another. So far I have something like the following to be triggered on “Tab” (which does not work):

function tabCursor(view) {
    let nextView = _getNextView_(view);

    nextView.dispatch(
        nextView.state.update({
            selection: new EditorSelection([EditorSelection.cursor(0)], 0);
        })
    )
    return true;
}
...
{ key: 'Tab', run: tabCursor }

The actual result is that the cursor doesn’t move. Any ideas of how to make this work?

I suppose you’ll also want to focus the other editor.

1 Like

Ahh. Of course. That works. Thanks!

Somewhat related: would it be possible for an extension to be able to support multiple cursors spread across multiple editor instances? Something like the current multiple cursor extension, but not limited to a single editor instance?

Not in a straightforward way. CodeMirror uses the browser’s focus behavior, which means that your key events are only going to a single editor.

So an individual editor would need to be able to access references to all the editors with cursors/selections in them and propagate the event to them?

Has the API changed? Or the type definition is not showing that EditorSelection takes any arguments?

From the type that I see, it should be this:

selection: new EditorSelection().addRange(EditorSelection.cursor(data.editor.position), true)

EditorSelection's constructor was never public. Check the docs for public methods. In this case you probably want EditorSelection.single.

1 Like

Ah, I see, there’s an @internal comment on it.

I haven’t looked at how you’re generating the types, but my guess is you are somehow deleting constructor from the output. This causes TypeScript to denote the constructor as public (with no args) according to its type system.

The way to do this in TypeScript is with the private keyword:

  private constructor(...) {...}

With this method, TypeScript enforces that new happens only within any code in the body of the class, and any code that tries new EditorSelection will get a type error in their code instead of no error.

TypeScript has an option to delete stuff marked @internal from the types. I can’t make some of these constructors private, since they are used by other things inside the package. Maybe the proper solution would be to submit a PR to TypeScript to emit private constructors, rather than just omitting them, for @internal constructors.