Skip to content

feat: Emacs kill-ring — CutToEndOfLine / CutToStartOfLine with consecutive-kill append#154

Merged
tig merged 8 commits into
developfrom
copilot/add-cut-to-eol-bol-commands
May 17, 2026
Merged

feat: Emacs kill-ring — CutToEndOfLine / CutToStartOfLine with consecutive-kill append#154
tig merged 8 commits into
developfrom
copilot/add-cut-to-eol-bol-commands

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 17, 2026

Editor lacks Emacs-style line-boundary kill commands where consecutive kills accumulate on the clipboard. TextView ships these via Command.CutToEndOfLine / Command.CutToStartOfLine; Editor only has selection-based Cut/Copy/Paste.

Commands

  • CutToEndOfLine — caret→EOL, or kills the line delimiter if already at EOL (joining lines). Consecutive kills append.
  • CutToStartOfLine — BOL→caret. Consecutive kills prepend (preserving document order).
  • Both: single undo step via RunUpdate(), no-op when ReadOnly, consume selection if present, abort without modifying document if clipboard write fails.

Kill-ring state

Two fields track the consecutive-kill run:

  • _lastCommandWasKill — set to true by kill commands after executing.
  • _previousCommandWasKill — set by OnKeyDown as a snapshot of _lastCommandWasKill before clearing it, so the dispatched kill command can read whether the preceding command was a kill.

Kill commands use consecutiveKill = _previousCommandWasKill || _lastCommandWasKill to cover both dispatch paths:

  • Keyboard dispatch (OnKeyDown): reads _previousCommandWasKill (snapshotted before clearing). _previousCommandWasKill is cleared after dispatch returns to prevent stale flag leaks into subsequent InvokeCommand calls.
  • Direct InvokeCommand dispatch: reads _lastCommandWasKill directly (since OnKeyDown is bypassed).

Any intervening non-kill command breaks the run: keyboard commands go through OnKeyDown which clears the flag; programmatic InvokeCommand of non-kill commands is a documented limitation.

Binding policy

Unbound by default — no entry in DefaultKeyBindings. Users opt in via [ConfigurationProperty] Editor.DefaultKeyBindings config.

Tests

16 integration tests: boundary kills, delimiter kills, end-of-document no-op, single undo, read-only guard, consecutive-kill append/prepend (including cross-line prepend), non-kill command breaking the run, unbound-by-default assertion, selection-consumed behavior, and clipboard-failure preservation for both commands.

Spec

specs/kill-ring/spec.md documents commands, append/prepend semantics, dual-path flag logic, and binding policy.

Copilot AI assigned Copilot and tig May 17, 2026
Copilot AI linked an issue May 17, 2026 that may be closed by this pull request
5 tasks
Copilot AI and others added 2 commits May 17, 2026 14:29
Implement Emacs-style kill commands:
- CutToEndOfLine: delete caret→EOL (or newline if at EOL)
- CutToStartOfLine: delete BOL→caret
- Consecutive kills append/prepend to clipboard (kill-ring)
- Unbound by default; bindable via Editor.DefaultKeyBindings config
- 13 integration tests covering kill, undo, append, and break-run

Agent-Logs-Url: https://github.com/gui-cs/Editor/sessions/f496a365-fb5d-4ff1-b62c-4d7a93b2a59a

Co-authored-by: tig <585482+tig@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Emacs kill-ring commands for line boundaries feat: Emacs kill-ring — CutToEndOfLine / CutToStartOfLine with consecutive-kill append May 17, 2026
Copilot finished work on behalf of tig May 17, 2026 14:32
Copilot AI requested a review from tig May 17, 2026 14:32
@tig tig marked this pull request as ready for review May 17, 2026 16:17
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f12bed4ac2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Terminal.Gui.Editor/Editor.Keyboard.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 019b0e943d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Terminal.Gui.Editor/Editor.Keyboard.cs Outdated
@tig
Copy link
Copy Markdown
Member

tig commented May 17, 2026

@copilot see cr feedback and address

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fbd4929f6f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/Terminal.Gui.Editor.IntegrationTests/EditorKillRingTests.cs
…append

Snapshot _lastCommandWasKill into _previousCommandWasKill before clearing,
so kill commands can read whether the preceding command was a kill.
Two snapshot sites cover both dispatch paths:
- OnKeyDown (keyboard dispatch)
- Each kill command entry (InvokeCommand dispatch)

Agent-Logs-Url: https://github.com/gui-cs/Editor/sessions/017298b2-f383-474b-92a5-ea7d1551be45

Co-authored-by: tig <585482+tig@users.noreply.github.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 17, 2026

@copilot see cr feedback and address

Fixed in afdf479. Introduced _previousCommandWasKill to snapshot the kill-run flag before clearing it in OnKeyDown. Kill commands now read _previousCommandWasKill for append/prepend decisions, with dual snapshot sites covering both keyboard dispatch (OnKeyDown) and direct InvokeCommand paths. All 13 kill-ring tests + full suite (236 integration, 461 unit) pass.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Emacs-style kill-to-line-boundary commands to Editor, with clipboard accumulation semantics for consecutive kills and documentation/tests for the behavior.

Changes:

  • Registers CutToEndOfLine / CutToStartOfLine commands without default key bindings.
  • Adds kill-run state tracking and clipboard append/prepend logic.
  • Adds integration tests and a feature spec for kill-ring behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/Terminal.Gui.Editor/Editor.cs Adds kill-ring state fields.
src/Terminal.Gui.Editor/Editor.Keyboard.cs Tracks kill-run state around keyboard dispatch.
src/Terminal.Gui.Editor/Editor.Commands.cs Registers and implements kill-to-EOL/BOL commands and clipboard writes.
tests/Terminal.Gui.Editor.IntegrationTests/EditorKillRingTests.cs Adds integration tests for kill commands and bindings policy.
specs/kill-ring/spec.md Documents command behavior and binding policy.
Comments suppressed due to low confidence (1)

tests/Terminal.Gui.Editor.IntegrationTests/EditorKillRingTests.cs:171

  • This consecutive-kill coverage uses InvokeCommand, so it exercises only the direct command path. Because the implementation has separate OnKeyDown snapshot logic for keyboard dispatch, add a test that temporarily binds a key to the kill command and uses InjectKey for two consecutive kills; otherwise the user opt-in key-binding path can regress independently.
        fx.Top.Editor.InvokeCommand (Command.CutToEndOfLine);
        Assert.Equal ("\ndef\nghi", fx.Top.Editor.Document?.Text);

        // Second kill (consecutive): "\n" → clipboard = "abc\n"
        fx.Top.Editor.InvokeCommand (Command.CutToEndOfLine);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Terminal.Gui.Editor/Editor.Commands.cs Outdated
Comment thread src/Terminal.Gui.Editor/Editor.cs Outdated
Comment thread tests/Terminal.Gui.Editor.IntegrationTests/EditorKillRingTests.cs Outdated
Comment thread src/Terminal.Gui.Editor/Editor.Commands.cs Outdated
Comment thread tests/Terminal.Gui.Editor.IntegrationTests/EditorKillRingTests.cs Outdated
Comment thread specs/kill-ring/spec.md Outdated
@tig
Copy link
Copy Markdown
Member

tig commented May 17, 2026

@copilot address CR feedback

… leak, add clipboard-failure tests, fix prepend test, remove unused usings, update spec

Agent-Logs-Url: https://github.com/gui-cs/Editor/sessions/d3cdb4ab-2c70-4881-acd3-299f9a1ad336

Co-authored-by: tig <585482+tig@users.noreply.github.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 17, 2026

@copilot address CR feedback

All six CR items addressed in 8bef477:

  1. Double-snapshot bug — Kill commands no longer re-snapshot _previousCommandWasKill. They use consecutiveKill = _previousCommandWasKill || _lastCommandWasKill to cover both keyboard and InvokeCommand paths.
  2. Stale flag leakOnKeyDown now clears _previousCommandWasKill after dispatch returns, so it doesn't leak into subsequent InvokeCommand calls.
  3. Wrong testConsecutiveKillToBOL_Prepends now uses CutToStartOfLine for both kills. Added ConsecutiveKillToBOL_TwoLines_Prepends for cross-line prepend coverage.
  4. Clipboard-failure tests — Added CutToEndOfLine_PreservesText_When_Clipboard_Unavailable and CutToStartOfLine_PreservesText_When_Clipboard_Unavailable.
  5. Unused usings — Removed Terminal.Gui.ViewBase and Terminal.Gui.Views.
  6. Spec — Updated to document _previousCommandWasKill field and dual-path flag logic.

All 239 integration + 461 unit tests pass. Formatting clean.

Copilot finished work on behalf of tig May 17, 2026 19:55
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b2774772a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Terminal.Gui.Editor/Editor.Commands.cs
Copilot finished work on behalf of tig May 17, 2026 21:46
@tig tig merged commit 1069cd6 into develop May 17, 2026
9 checks passed
@tig tig deleted the copilot/add-cut-to-eol-bol-commands branch May 17, 2026 21:51
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.

Editor: Emacs kill-ring (kill-to-EOL / kill-to-BOL with append)

3 participants