Pane.SendKeys
SendKeys invokes tmux send-keys with the receiver's exact linked session-window-pane target. This is tmux key input, not shell execution: Literal only changes tmux key parsing, and any delivered text may still be interpreted by the pane's application. KeyName routes through a client's key table instead of delivering to the pane.
Source and package
- Qualified name
-
tmux.Pane. Send Keys - Package
- tmux
- Declared in
Pane- Distribution
- github.com/libtmux/libtmux-go/tmux
- Source
- tmux/pane_input.go
- Other languages
- Perlmethod Erlang PowerShell Julia Elixir Haskell Common LispPythonRubyLuaTypeScriptRust Java C#C++SwiftKotlinScalaOCaml F# Clojure
- func (p Pane) SendKeys( ctx context
.Context , request SendKeys , ) errorRequest -
Description#
KeyName and TargetClient require tmux 3.4 and follow
UnsupportedPolicy.Stderr from either the Command send or the separate Enter becomes a redacted
CommandError: Command may carry a caller's secret, so only tmux's exit code is retained. A nonzero exit with empty stderr is success, as for every mutation (see the package documentation). Transport and context errors are delivery-ambiguous, including between Command and Enter.Examples#
Send literal text followed by Enter to a pane running cat, then wait for the text to appear. Literal controls tmux key parsing; it does not prevent the pane's application from interpreting input. SendKeys returning does not establish that the application has processed the text. Use Go 1.26 or newer and tmux 3.3a or newer on a Unix system, with
tmuxandcatonPATH. In a new directory, create a module and add the library from the Go module proxy:Terminal window $ go mod init example.com/libtmux-api && \go get github.com/libtmux/libtmux-go@latestSave this complete example as
example_test.go. It creates a private temporary socket and stops its server before removing the directory. Cleanup failure fails the example and retains the socket directory. View sourcepackage tmux_testimport ("context""errors""fmt""os""path/filepath""slices""time""github.com/libtmux/libtmux-go/tmux")// Send literal text followed by Enter to a pane running cat, then wait for// the text to appear. Literal controls tmux key parsing; it does not prevent// the pane's application from interpreting input. SendKeys returning does// not establish that the application has processed the text.func ExamplePane_SendKeys_complete() {run := func() (runErr error) {directory, err := os.MkdirTemp("", "libtmux-go-api-")if err != nil {return fmt.Errorf("create socket directory: %w", err)}server, err := tmux.NewServer(tmux.ServerOptions{SocketPath: filepath.Join(directory, "tmux.sock"),ConfigFile: "/dev/null",})if err != nil {return errors.Join(err, os.RemoveAll(directory))}defer func() {// Cleanup has its own deadline because the operation may have timed out.cleanup, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()if err := server.Kill(cleanup); err != nil && !errors.Is(err, tmux.ErrNoServer) {runErr = errors.Join(runErr, fmt.Errorf("stop server at %s: %w", directory, err))return}runErr = errors.Join(runErr, os.RemoveAll(directory))}()ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()session, err := server.NewSession(ctx, tmux.NewSessionRequest{Name: "work", WindowName: "editor", Command: "cat", Width: 100, Height: 30,})if err != nil {return fmt.Errorf("create session: %w", err)}pane, err := session.ResolveActivePane(ctx)if err != nil {return fmt.Errorf("resolve pane: %w", err)}text := "api input"if err := pane.SendKeys(ctx, tmux.SendKeysRequest{Command: &text, Literal: true}); err != nil {return fmt.Errorf("send literal input: %w", err)}// Capture is a point-in-time read, so wait for a complete matching line.ticker := time.NewTicker(10 * time.Millisecond)defer ticker.Stop()for {lines, err := pane.Capture(ctx, tmux.CapturePaneRequest{Start: tmux.CaptureBoundary, End: tmux.CaptureBoundary,})if err != nil {return fmt.Errorf("capture pane: %w", err)}if slices.Contains(lines, "api input") {fmt.Println("captured: api input")break}select {case <-ctx.Done():return fmt.Errorf("wait for pane text: %w", ctx.Err())case <-ticker.C:}}return nil}if err := run(); err != nil {panic(err)}// Output:// captured: api input}Run the saved file. Go checks the Output comment and fails on different output or an operation or cleanup error:
Terminal window $ go test -count=1 -v example_test.go- Parameters
tmux command#
The tmux commands behind SendKeys.
tmux C API#
The C declarations in tmux that implement these commands.
Guides#
Pages that discuss SendKeys.
- Examples
- Guides
In other ports#
Send keystrokes to a pane
| Language | Equivalent |
|---|---|
| Python | libtmux |
| Ruby | Lib |
| Lua | libtmux |
| Erlang | tmux |
| Haskell | No public Haskell equivalent is implemented; the current modules expose scalar values and version parsing. |
| Common Lisp | libtmux: |
| TypeScript | pane |
| Rust | pane |
| Java | no direct equivalent; Pane.paste writes a buffer instead |
| Clojure | libtmux |
| Kotlin | io |
| Scala | io |
| C# | Lib |
| C++ | libtmux:: |
| Swift | Server |
| OCaml | Libtmux |
| Perl | Lib Explicit Server operation. Captured entities remain local observations; use a new snapshot to observe changes. |
No equivalent is recorded in PowerShell, Julia, Elixir or F#.