Non-empty selection for Helix keybindings

:wave: I’m developing a Helix keybindings extension.

Helix is a modal editor, and conceptually, while in normal mode, the selection is never empty. I’m having a bit of trouble mapping this to CM, given that I was hoping to import liberally from @codemirror/commands. I suspect that answer is simply that I can’t have my cake and eat it too, and I should just write all commands from scratch and not reuse any built-in ones. In any case, here it is, in case anybody has a better idea.

I had 2 options in mind:

  1. Pretend that a [from, to] selection actually means [from, to + 1] for the purposes of yanking, etc (and add visual decorations to make it look bigger).
  2. Force CM to always have at least a 1-char selection (through some transaction filter).

As far as I can see, both approaches get me into trouble if I want to use a built-in command. In #1, I could have:

let x = |fooba]r();

where “real” selection is the whole foobar function identifier. But then, a selectParentSyntax() would just grow the selection up to |foobar](), which is nonsensical when interpreted back as a “Helix selection” (it should grow up to |foobar(])).

In #2, a “simple cursor” would look like this:

// head: [       anchor: |
let x = f[o|obar();

but then a selectGroupRight() would keep the anchor fixed and swap the position of the head, resulting in fo|obar]() (instead of f[oobar|()).


Anybody have a better idea, before I jump into vendoring @codemirror/commands?

1 Like