libtmux Reference MCP Search

Sending keys

Edit this page on GitHub

Every port’s version of send_keys is really tmux send-keys wearing that port’s calling convention, and send-keys has one behavior worth understanding before you rely on it: tmux can read the text you send either as literal characters or as tmux’s own key vocabulary (C-c, Enter, Up). Without a literal flag, q sent to a pane running less is a keypress; the same q sent literally is the character q, which happens to also quit less — so the ambiguity mostly hides until the text you’re sending collides with a real key name.

Literal text, key names, and whether Enter followsLink to section

Each block below sends the same two things a port can send — text and, separately, a named key — and shows whether pressing Enter is the default, an option, or a second call you make yourself. Source citations sit as comments in each block; see Attach and send keys for the same calls in their full, checked context.

// Literal text, never interpreted as key names or formats, and never
// followed by a newline the caller did not ask for.
pane.send_text("echo hey");
// One named key, sent separately — this is how Enter gets pressed.
pane.send_key("Enter");

Java, .NET, and Swift send exactly the text given, without a separate literal switch to reach for — the type signature doesn’t offer the ambiguous path in the first place. Confirm against your own port’s reference before assuming a call is unambiguous for input that looks like a key name (a literal # in an option value has this same class of gotcha — see the option-naming note in Concepts).

The race you can’t see from the call siteLink to section

tmux accepts a send-keys command the instant it’s issued — before the shell in that pane has necessarily started, and before whatever you sent has necessarily finished. Two ports say this outright, and a third ships the fix without spelling out the reason:

  • Rust: “tmux hands back a pane the moment it forks, before the shell in it has started” — the comment sits directly above a retry_until loop in README.md’s query example.
  • Go: doesn’t say the same sentence, but ships the fix for it — tmuxtest.WaitForShellReady exists specifically for a pane that hasn’t started its shell yet.
  • .NET: “tmux accepts a command before the shell has finished it, so the result is waited for rather than assumed” — from README.md’s “Running something, and reading it back” section.

The fix in every case is the same shape: don’t read a pane immediately after sending to it; wait for the text you expect to actually appear. That waiting mechanism — what each port offers instead of a fixed sleep — is the subject of the next guide.

Where to go nextLink to section

  • Capturing output — reading back what you just sent, and waiting for it correctly instead of guessing a delay.
  • Attach and send keys — the full sourced round trip this guide picks apart piece by piece.
Esc

Type to search.