scniro / react-codemirror2

Codemirror integrated components for React
MIT License
1.66k stars 193 forks source link

Controlled editor - pasting doesn't cause an update unless it changes the text #77

Open Adam13531 opened 6 years ago

Adam13531 commented 6 years ago

This feels like a bug to me even though it may not exactly be one.

Repro:

  1. Load the demo site.
  2. Ensure you're in CONTROLLED mode.
  3. Select the first entire line: image
  4. Press ctrl+C to copy
  5. Press ctrl+V to paste

Expected: the cursor/selection looks like this: image

Note: the expected behavior is what's currently happening with the UNCONTROLLED editor.

Actual: nothing changes from the first picture: image

scniro commented 6 years ago

@Adam13531 Interesting, I can definitely reproduce the discrepancy. Hm, unsure straight away what could be going on but I'll gladly look into this. Have you tried autoCursor={true}? Unsure if it'd make any difference but the thought comes to mind. Anyways, will keep you posted with my findings 👍

Adam13531 commented 6 years ago

Have you tried autoCursor={true}?

I just tried it now and it didn't seem to change anything. From what little investigation I did, it looks like setting hydrate to true internally in the following code gets the correct behavior:

https://github.com/scniro/react-codemirror2/blob/f4dc069c130a8c608c3d69868d57a2d6d98a20d6/src/index.tsx#L580-L582

I think the right way to do it would be to set hydrate if the selection changes.

silverwind commented 6 years ago

setting hydrate to true

Just tested this fix (https://github.com/silverwind/react-codemirror2/commit/50781bd5b6d4a89681b0aa66b6e7c941fe9f5f26), but didn't work for me, the editor didn't seem to accept any input with that change.

silverwind commented 6 years ago

Possible workaround below. Note that it only works on single selections:

  onPaste = (editor, e) => {
    if (!e.clipboardData || !e.clipboardData.items || !e.clipboardData.items[0]) return;
    e.clipboardData.items[0].getAsString(pasted => {
      if (editor.getSelection() !== pasted) return;
      const {anchor, head} = editor.listSelections()[0];
      editor.setCursor({
        line: Math.max(anchor.line, head.line),
        ch: Math.max(anchor.ch, head.ch),
      });
    });
  }
scniro commented 4 years ago

@Adam13531 @silverwind I am a lot shorter on time these days as when I started this project. Codemirror & React APIs are moving to quickly for me to keep atop of for the day-to-day. I am looking for a co-maintainer of this project. Please contact me directly if you are interested. Thank you for understanding.