Codemirror v5 Dynamically Add Multiple Cursors

226 Views Asked by At

I'm using Codemirror v5.65.12. I know I can press and hold the CTRL key and then click to add multiple cursors into the editor. However mobile users don't have a CTRL key. My first attempt was using...

EventTarget.dispatchEvent() to trigger the ctrlKey to be down as long as a class is visible. I had no success with this attempt.

I'm also aware that Codemirror comes with an undocumented function triggerOnKeyDown with which you can trigger a keydown on Codemirror.

const ev = {
  type: 'keydown',
  keyCode: 13 // keycode for the Enter key, use any keycode here
};
cm.triggerOnKeyDown(ev);

However when I tried that using ctrlKey alongside onclick on the editor I wasn't able to successfully add multiple cursors for mobile in Codemirror.

I'm aware I can use .getCursor() to get the cursor's position and I can use .setCursor() to set the cursor's position but no matter what way I approach this I always manage to just move the cursor position to a new position instead of adding an additional cursor when I touch on mobile (specifically Android).

Is there a way in Codemirror v5.65.12 to dynamically add multiple cursors to a Codemirror instance that doesn't require a desktop (IE holding down the ctrlKey)? If not what other methods can I do to achieve this?

Codemirror .getCursor()

1

There are 1 best solutions below

0
Simon Laux On BEST ANSWER

Looking at the code it does not look at the key events but instead looks for the modifier keys event.ctrl (and ev.metaKey on MacOS) in the mouse event:

https://github.com/codemirror/codemirror5/blob/658bff7c56b7829aeabb8a914be5ca728d8aba0b/src/edit/mouse_events.js#L124

There we can also see that we can overwrite behaviour via configureMouse, which will add a new cursor when we return {addNew:true} (for more info search for configureMouse on https://codemirror.net/5/doc/manual.html#config)

var multiselectCheckbox = document.querySelector("#multi");
var editor = CodeMirror.fromTextArea(document.querySelector("#code"), {
  lineNumbers: true,
  configureMouse: (cm, repeat, ev) => {
    if (multiselectCheckbox.checked) {
      return {
        addNew: true
      }
    } else {
      return {}
    }
  }
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.min.js"></script>

<label for="multi">Create more cursors</label>
<input type="checkbox" id="multi" />
<textarea id="code" name="code">
// some sample source code
CodeMirror.fromTextArea(document.querySelector("#code"), {
    lineNumbers: true,
    configureMouse: (cm, repeat, ev) => {
      if (multiselectCheckbox.checked){
        return {addNew:true}
      } else {
        return {}
      }
    }
  });
</textarea>