Skip to content

fix(session-ui): add CM6 editing shortcuts (undo/redo/copy/cut/paste/select-all) to Files Changed editor - #304

Merged
jeonghun-jj-lee merged 11 commits into
local/amicodefrom
cm6-editing-shortcuts
Sep 6, 2026
Merged

jeonghun-jj-lee merged 11 commits into
local/amicodefrom
cm6-editing-shortcuts

Conversation

@jeonghun-jj-lee

@jeonghun-jj-lee jeonghun-jj-lee commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Closes #302

Adds standard editing shortcuts to the CodeMirror 6 diff editor in the Files Changed tab.

Changes

session-ui

  • Add @codemirror/commands 6.11.0 dependency
  • Wire history(), defaultKeymap, historyKeymap, bracketMatching() into the diff editor
  • history() lives in editableExtensions (only when readOnly: false)
  • Revert uses isolateHistory.of('full') so it's always undoable via Cmd+Z (D7)
  • Fix stale revert() docstrings (said 'clear undo history' — now correct)
  • Add data-amc-clipboard="codemirror" on the container div
  • Fix invisible selection highlight: boost .cm-selectionBackground CSS specificity to beat CM6's built-in defaults (#233 dark / #d7d4f0 light)
  • Fix copy in unified mode: stash __amcEditor bridge on the container element with getSelectedText() / cutSelectedText() that read from CM6's document model (state.sliceDoc), not the DOM

app

  • Add CLIPBOARD_EDITOR_SELECTOR for the CM6 opt-out contract
  • Global clipboard handler delegates Z/Y/A to CM6 (no preventDefault)
  • extractSelection uses execCommand('delete') for CM6 cut targets
  • Fix copy/cut: for C/X on CM6 targets, read from the __amcEditor bridge instead of window.getSelection().toString() — fixes garbled copy in unified mode and empty copy in readOnly mode

Testing

  • 74 tests in editable-diff-view.test.ts (13 new): undo/redo, external update exclusion, revert undoability, selection highlight specificity, __amcEditor bridge (stash/read/cut/readOnly/cleanup)
  • 55 tests in global-clipboard.test.ts (12 new): CM6 delegation for Z/Shift+Z/Y/A, clipboard bridging for C/V, extractSelection cut behavior, __amcEditor bridge copy/cut/no-selection
  • All 61 original diff editor tests and 43 original clipboard tests pass unchanged
  • Manually verified: selection visible, Cmd+A → Cmd+C copies full file, undo/redo works

…ions

Add @codemirror/commands dependency and wire history(), defaultKeymap,
historyKeymap, and bracketMatching() into the diff editor.

- history() in editableExtensions (only when readOnly is false)
- keymap + bracketMatching in baseExtensions (shared by all panes)

Part of #302
updateModified and updateOriginal use addToHistory.of(false), which the
new history() extension respects. These tests confirm the invariant.

Part of #302
Use isolateHistory.of('full') on the revert dispatch so it always
creates its own undo group. Cmd+Z after revert now restores the
pre-revert edits. Updated docstrings to match.

Part of #302
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 2697bbee-50fd-47ce-a018-fab95c0927f7


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Add CLIPBOARD_EDITOR_SELECTOR for data-amc-clipboard='codemirror'.
The global handler returns early (no preventDefault) for undo/redo/
select-all when the target is inside a CM6 editor, letting CM6's
own keymap handle them. Clipboard chords (C/X/V) still bridge.

Part of #302
Inside a CM6 editor, cut deletion uses execCommand('delete') instead
of range.deleteContents() so CM6's mutation observer creates a proper
undo-tracked transaction. Non-CM6 contenteditable targets keep the
existing range.deleteContents() + dispatchInput('deleteByCut') path.

Part of #302
…tion

Add data-amc-clipboard='codemirror' to the EditableDiffView container
div so global-clipboard.ts recognizes it and delegates Z/Y/A to CM6.

Part of #302
@jeonghun-jj-lee
jeonghun-jj-lee marked this pull request as ready for review September 6, 2026 20:23
…faults

CM6's built-in default uses a 5-class child-combinator selector for
.cm-selectionBackground with hardcoded colors (#233 dark, #d7d4f0 light).
Our theme's lower-specificity descendant selector lost, making selections
invisible in dark mode. Use matching child-combinator depth so our
CSS variable (--v2-background-bg-layer-03) wins.

Part of #302
… handler

createDiffEditor attaches getSelectedText() and cutSelectedText() on
the parent element so the global clipboard handler can read from CM6's
document model without importing @codemirror packages. Cleaned up on
destroy().

Part of #302
When copying or cutting inside a CM6 editor, the global clipboard
handler now reads from the __amcEditor bridge (which uses
state.sliceDoc) instead of window.getSelection().toString(). This
fixes two bugs:
- Unified mode: DOM selection included deleted-line decoration widgets
- ReadOnly mode: DOM selection might not be synced by CM6

Part of #302
@jeonghun-jj-lee
jeonghun-jj-lee merged commit a904877 into local/amicode Sep 6, 2026
3 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the cm6-editing-shortcuts branch September 6, 2026 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(session-ui): add CM6 editing shortcuts (undo/redo/copy/cut/paste/select-all) to Files Changed editor

1 participant