Skip to content

Strip copies in the substring filter, not via yank-handler - #801

Open
OSadovy wants to merge 1 commit into
xenodium:mainfrom
OSadovy:remove-yank-handler
Open

Strip copies in the substring filter, not via yank-handler#801
OSadovy wants to merge 1 commit into
xenodium:mainfrom
OSadovy:remove-yank-handler

Conversation

@OSadovy

@OSadovy OSadovy commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Problem

Rendered output and block-quoted replies carry a yank-handler text property
whose lambda strips properties (and the leading > ) at paste time. The
property rides on the characters, which has surprising reach:

  • Once the text lands in any other buffer, copies from there still run
    agent-shell's lambda - for the rest of the session, in buffers unrelated to
    agent-shell.
  • insert-for-yank is not just C-y: registers, rectangles, cua, xterm
    paste, and any third-party property-preserving insertion all hit the handler.
  • The same M-w yields different content depending on destination: C-y
    gives hello, while the OS clipboard and isearch's C-s C-y keep the
    stored > hello. yank-excluded-properties is never consulted for handler
    text, so no setting affects any of this.

Change

Delete both yank-handler puts and finish the job in
agent-shell--filter-buffer-substring, which shell and viewport buffers
already install as filter-buffer-substring-function - the hook Emacs
provides for deciding what a copy of a buffer yields. Copies now come out
property-free, and one > per line is dropped from text tagged with a
private agent-shell-block-quote marker (set by agent-shell--block-quote
in place of the handler). The decision happens once, at copy time, in buffers
agent-shell owns; paste stays stock Emacs.

Behaviour

M-w, C-w, mouse copy, and registers out of agent-shell buffers paste the
same as before. Markdown-rendered blockquotes still keep their > on copy,
so the source round-trips. Two visible changes, both toward consistency:

  • Copies of block-quoted replies are now identical everywhere. Previously the
    OS clipboard and isearch kept the > that yank removed.
  • Strings from the standalone agent-shell-markdown-convert API, killed from
    non-agent-shell buffers, now paste with stock Emacs semantics. No in-tree
    caller does this. Happy to gate it behind a keyword if you'd rather keep
    the old behaviour there.

Context

Found while speech-enabling agent-shell with Emacspeak: its speech layer
inserts buffer text via insert-for-yank precisely to keep the text
properties it builds voices from, and the handler strips them. Any consumer
using insert-for-yank for property-preserving insertion hits the same wall,
and a buffer-local filter cannot break them.

Tests: the yank test is rewritten as filter tests - properties stripped,
> dropped from quoted replies, one level per line for nested quotes,
markdown blockquotes keep theirs. Full suite passes.

Checklist

  • I agree to communicate (PR description and comments) with the author myself (not AI-generated).
  • I've reviewed all code in PR myself and will vouch for its quality.
  • I've read and followed the Contributing guidelines.
  • I've filed a feature request/discussion for a new feature. (N/A - bug-ish cleanup, no new feature)
  • I'm making visual changes, so I'm including screenshots so you can view and discuss. (N/A - no visual changes)
  • I've added tests where applicable.
  • I've updated documentation where necessary. (docstrings updated)
  • I've run M-x checkdoc and M-x byte-compile-file.

Rendered output and block-quoted replies carried a yank-handler text
property whose lambda stripped properties (and the "> " prefix) at
paste time.  Unlike the buffer-local filter-buffer-substring-function
already installed in shell and viewport buffers, the property rides on
the characters into any buffer they reach: it runs agent-shell code on
yanks in unrelated buffers for the rest of the session, fires from
every insert-for-yank caller (registers, rectangles, cua, xterm paste),
and bypasses the user's yank-excluded-properties.

Do the same work in agent-shell--filter-buffer-substring instead: return
the copy free of text properties, and drop one "> " per line from text
tagged agent-shell-block-quote, the property that now marks block-quoted
replies.  Copies out of agent-shell buffers are unchanged: kill, copy,
mouse drag and registers all route through the filter and yield the same
plain text as before.  Markdown-rendered blockquotes keep their "> "
on copy, as they already did, so the source still round-trips.
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.

1 participant