Skip to content

fix(editor): trust & ergonomics cluster — undoable phrase add, Escape-deselect, default sustain keys - #298

Merged
byrongamatos merged 1 commit into
mainfrom
feat/editor-trust-cluster
Jul 16, 2026
Merged

fix(editor): trust & ergonomics cluster — undoable phrase add, Escape-deselect, default sustain keys#298
byrongamatos merged 1 commit into
mainfrom
feat/editor-trust-cluster

Conversation

@ChrisBeWithYou

@ChrisBeWithYou ChrisBeWithYou commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Three small, self-contained fixes that close credibility gaps in the manual editing loop. From a fresh gap-audit of origin/main — the old ranked backlog is fully shipped, and these are the highest-value cheap wins that remain (one is a genuine undo-integrity bug).

What changed

Fixed — Add-Phrase undo-trap (the integrity bug)

Adding a phrase (Shift+P) was the only structural add that bypassed EditHistory. So pressing Ctrl+Z afterward silently rolled back whatever you did before the phrase (a note move, a fret change) and left the phrase sitting there — undo lied about what it undid. New AddPhraseCmd (@pure:phrase-cmds) routes the add through the history, holding the arr.phrases array + phrase object by reference (never S.currentArr, which can change before an undo) so exec↔rollback restore that arrangement's phrases exactly, sort order included. Mirrors the existing AddSectionCmd pattern.

Changed — Escape clears the selection

In note/drum editing, Escape now drops the current selection — the standard DAW gesture, previously inert outside tempo-map mode. Layered under every existing Escape owner: the read-only Tab-preview / User-Guide lenses (handled at the top of onKeyDown, which return first), the transient modals (closed by main.js's import-time listener), and tempo-map's own suggest-dismiss / barline-clear branches (guarded out via !S.tempoMapMode). Non-destructive — selection isn't undo state, so it touches no history and no-ops when nothing is selected.

Changed — Sustain keys in the default FeedBack profile

[ and ] now shorten/lengthen the selected note's sustain by one grid step in the FeedBack profile. The commands (shortenSustain / lengthenSustain) already existed but were bound only in the Legacy (EOF) profile (feedback:''), so default-profile users had no keyboard sustain edit at all. Matches the EOF bracket convention; in tempo-map mode the brackets stay the beat-count controls (that block resolves first, so no shadowing).

Tests

  • New tests/phrase_undo.test.mjs — round-trips AddPhraseCmd through the real EditHistory (exec → rollback deep-equality → redo), incl. the interleaved case proving each add is its own LIFO step (the exact trap), equal-start_time refs, and redo-stack drop. Slices @pure:phrase-cmds, so it fails on main (the class doesn't exist there).
  • tests/eof_shortcuts.test.mjs — added a FeedBack-profile assertion that [/] resolve to shorten/lengthen sustain and display in the registry rows; fails on main (no FeedBack binding there).
  • Full JS suite green (180), npm run lint 0 errors (3 pre-existing baseline warnings in untouched files). routes.py untouched, so no pytest.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed phrase insertion so each addition becomes its own independent undo step (Ctrl+Z/undo no longer rolls back prior edits).
    • Undo/redo now properly handles sorted insertion by start time and restores the exact pre-change state.
  • Changed
    • Pressing Escape now clears the current note or drum selection (without impacting undo history).
    • Pressing Escape also dismisses the right-click/context menu when it’s open.
    • In the default profile, [/] shorten and lengthen sustain; tempo-map mode keeps its bracket beat controls.
  • Tests
    • Added automated coverage for phrase undo/redo behavior and Escape/context-menu shortcut handling.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 344e1e1a-0078-4c6c-9b81-3e003d48672c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Phrase insertion now executes through undo history, Escape dismisses menus and clears selections in the appropriate editor modes, and FeedBack maps [/] to sustain editing while preserving tempo-map controls.

Changes

Editor interaction behavior

Layer / File(s) Summary
Undoable phrase insertion
src/input.js, tests/phrase_undo.test.mjs, CHANGELOG.md
Phrase additions execute through history with sorted insertion and reference-specific rollback; tests cover ordering, LIFO undo, duplicate times, redo clearing, and read-only behavior.
Escape menu and selection handling
src/input.js, src/main.js, tests/escape_deselect_menu.test.mjs
Escape dismisses the context menu before clearing note or drum selections, while open dialogs consume Escape without triggering selection clearing.
FeedBack sustain shortcuts
src/shortcuts.js, tests/eof_shortcuts.test.mjs
FeedBack maps [ and ] to sustain shortening and lengthening in note mode while retaining tempo-map beat controls.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main editor fixes: undoable phrase adds, Escape selection clearing, and default sustain key bindings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/editor-trust-cluster

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

@byrongamatos

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@byrongamatos
byrongamatos force-pushed the feat/editor-trust-cluster branch from 03ec9b3 to a6aefbf Compare July 16, 2026 18:44
@byrongamatos
byrongamatos merged commit 79a302a into main Jul 16, 2026
3 checks passed
@byrongamatos
byrongamatos deleted the feat/editor-trust-cluster branch July 16, 2026 18:44
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.

2 participants