Skip to main content

ClipboardTarget

Enum ClipboardTarget 

Source
#[non_exhaustive]
pub enum ClipboardTarget { Clipboard, Primary, Selection, }
Expand description

Which selection an OSC 52 clipboard request names (#828).

A value, never the protocol byte, so a consumer never parses the sequence — the same reason TermEvent::SetPaletteColor carries a u8 index rather than the field it was written in.

Three members, and p is kept apart from s deliberately. The sequence’s target field admits c, p, q, s and the eight cut buffers (ctlseqs.txt:2156); justerm models the three a consumer can act on and ignores the rest rather than folding them onto a neighbour, since mapping q onto a selection would be the engine inventing an equivalence the application did not ask for. ghostty folds every unrecognised kind onto the clipboard (src/termio/stream_handler.zig:1013); alacritty ignores them (alacritty_terminal/src/term/mod.rs:1714), and so does this. Read ghostty’s from the switch and not from the comment four lines above it, which says “we ignore the ‘kind’ field and always use the standard clipboard” and is contradicted by the code under it — only the else arm goes to .standard.

The first draft collapsed p and s into one member, and that was wrong on the wire. alacritty collapses them (alacritty_terminal/src/term/mod.rs:1713) but replies with the byte the application sent (:1744), so the collapse never reaches a client. This engine hands the consumer a value and gets it back at report_clipboard, so a collapse here would answer ESC ] 52 ; s ; ? naming p — a selector the application never wrote, in the one field a client could pair a reply on. The spec lists the two separately (ctlseqs.txt:2157), xterm binds them to different atoms (misc.c:3327) and echoes the recognised list back (misc.c:3384), and ghostty keeps three locations apart in both directions (src/Surface.zig:5954, src/terminal/c/terminal.zig:2942). Splitting the member is what lets the value round-trip without the engine remembering anything.

#[non_exhaustive] (#843). The set is open by the paragraph above: q and the eight cut buffers are in the sequence and unmodelled here, so a later slice may name one. A consumer meeting a member it does not know can decline the request, which is already how it refuses any of them.

ghostty reaches the same shape independently, which #843 had recorded as impossible — its issue says Zig “has no such construct”, and Zig does: a trailing _ marks a non-exhaustive enum, used at 23 sites in that tree. The one that matters here is src/terminal/clipboard.zig:2, whose Location is { standard, selection, primary, _ } — the same three members this type carries, and open for the same reason. Convergence on both the partition and the openness is the non-arbitrariness signal; it was invisible while the corpus was recorded as having no vote.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Clipboard

The system clipboard — the c field, and the empty field.

The empty field is the common form in the wild rather than an edge case: it is what tmux 3.2a was measured emitting for both an ordinary copy-mode copy and set-buffer -w (#828). Reading it as “unrecognised” would drop the only emission this project has observed.

§

Primary

The primary selection — the p field. On a platform with no primary selection a consumer may treat it as Clipboard; the engine does not make that choice for it.

§

Selection

The s field — “the configurable primary/clipboard selection” (ctlseqs.txt:2161), which is to say: whichever of the two the user has configured.

Relayed rather than resolved, and that is the boundary working. The thing that decides what s means is a setting: xterm resolves SELECT through DefaultSelection, which is the selectToClipboard resource (button.c:2081), and under ADR-0017 a setting is the consumer’s. So the application’s choice is carried through unchanged and the consumer resolves it against the configuration it owns.

A consumer with no such setting should treat this as Primary, because that is what xterm-as-shipped doesselectToClipboard defaults to false. Worth stating rather than left to taste, since the alternative reading sends the copy somewhere the reference would not.

And the setting is not purely out of reach: DECSET 1041 sets the same resource from the stream (ctlseqs.txt:1008), so an engine that tracked that mode could resolve s itself. justerm does not model 1041, which is a declined capability rather than an impossible one — the honest form of the claim, and the mode is unimplemented here like the rest of the tail (#47).

Trait Implementations§

Source§

impl Clone for ClipboardTarget

Source§

fn clone(&self) -> ClipboardTarget

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for ClipboardTarget

Source§

impl Debug for ClipboardTarget

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for ClipboardTarget

Source§

impl Hash for ClipboardTarget

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for ClipboardTarget

Source§

fn eq(&self, other: &ClipboardTarget) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for ClipboardTarget

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.