# Options and hooks

Source: https://libtmux.org/en/go/latest/topics/options-and-hooks/

> Read and update tmux options, and register commands for tmux events.

Use options to change tmux behavior, such as [`automatic-rename`](https://libtmux.org/en/tmux/latest/catalog/options/automatic-rename/) or the
status-line format. Use hooks to run commands on events such as
[`session-renamed`](https://libtmux.org/en/tmux/latest/catalog/hooks/session-renamed/) or [`after-split-window`](https://libtmux.org/en/tmux/latest/catalog/hooks/after-split-window/). Choose the scope supported by the
option or hook.

## Reading and writing options

Read, set, or unset an option at its supported scope. Distinguish a local
override from the effective value inherited from a parent scope.

[`pane.Options(ctx)`](<https://libtmux.org/en/go/latest/reference/tmux-pane-options/>) returns a fresh typed snapshot, including inherited values.
Its accessors return an [`OptionValue`](<https://libtmux.org/en/go/latest/reference/tmux-optionvalue/>); use [`OptionValue.Get`](<https://libtmux.org/en/go/latest/reference/tmux-optionvalue-get/>) to distinguish a
present value from an absent one. Check the read error before inspecting the snapshot.

Use the handle that owns the option's scope. For example, [`automatic-rename`](https://libtmux.org/en/tmux/latest/catalog/options/automatic-rename/)
belongs to a window: use [`Window.SetOption`](<https://libtmux.org/en/go/latest/reference/tmux-window-setoption/>) or [`Window.UnsetOption`](<https://libtmux.org/en/go/latest/reference/tmux-window-unsetoption/>), then read
[`Window.Options`](<https://libtmux.org/en/go/latest/reference/tmux-window-options/>) again for an updated snapshot.

For a single raw value, [`Pane.RawOption`](<https://libtmux.org/en/go/latest/reference/tmux-pane-rawoption/>) returns the string, its presence, and an
error. Do not treat an error as an absent option.

### Examples

After a successful write completes, read the option to obtain its updated value.
The following examples set, read, and unset an option:

```go
if err := window.SetOption(ctx, "automatic-rename", "off", tmux.SetOptionOptions{}); err != nil {
    return fmt.Errorf("set automatic rename: %w", err)
}
options, err := window.Options(ctx)
if err != nil {
    return fmt.Errorf("read window options: %w", err)
}
value, present := options.AutomaticRename().Get()
fmt.Println("automatic rename:", value, "present:", present)
if err := window.UnsetOption(ctx, "automatic-rename", tmux.UnsetOptionOptions{}); err != nil {
    return fmt.Errorf("unset automatic rename: %w", err)
}
```

## Hooks

Use [`session.SetHook`](<https://libtmux.org/en/go/latest/reference/tmux-session-sethook/>) to register a command and [`session.Hooks`](<https://libtmux.org/en/go/latest/reference/tmux-session-hooks/>) to read the
session's typed hook values. [`session.UnsetHook`](<https://libtmux.org/en/go/latest/reference/tmux-session-unsethook/>) removes a registration.
[`Session.SetHooks`](<https://libtmux.org/en/go/latest/reference/tmux-session-sethooks/>) writes indexed entries when an event needs more than one command.

Use [`server.GlobalSessionScope()`](<https://libtmux.org/en/go/latest/reference/tmux-server-globalsessionscope/>) for hooks shared by sessions. Keep hook
registration at a scope supported by the tmux event.

### Examples

tmux stores hook commands in indexed arrays, such as [`after-new-window[0]`](https://libtmux.org/en/tmux/latest/catalog/hooks/after-new-window/).

[`Session.SetHooks`](<https://libtmux.org/en/go/latest/reference/tmux-session-sethooks/>) accepts indexed hook entries. Pass a context and check errors from
both mutations and reads; a successful write does not refresh earlier snapshots.

Set and list a session hook. The next section explains window and pane scope
limitations:

```go
if err := session.SetHook(ctx, "session-renamed", "display-message 'renamed'"); err != nil {
    return fmt.Errorf("set session hook: %w", err)
}
value, present, err := session.RawHook(ctx, "session-renamed")
if err != nil {
    return fmt.Errorf("read session hooks: %w", err)
}
fmt.Println("session-renamed:", value, "present:", present)
```

<a id="window-and-pane-hook-scopes-are-mostly-fiction"></a>

## Supported hook scopes

tmux stores hooks globally or per session. Accepted [`set-hook -w`](https://libtmux.org/en/tmux/latest/manual/set-hook/) or `-p` flags
do not imply a separate window or pane hook table, and [`show-hooks`](https://libtmux.org/en/tmux/latest/manual/show-hooks/) does not
provide a corresponding listing. Check the event's supported scope if a hook is
accepted but never fires.

Options have window and pane tables of their own. The hook-scope limitation does
not apply to ordinary options.

## tmux version compatibility

Check the library's supported tmux versions before using a version-specific
option or hook.

<details>
<summary>tmux manual and source</summary>

The tmux manual defines [option scopes and inherited reads](https://github.com/tmux/tmux/blob/94796f6b1182507efac8a272fc309a79e22e58a5/tmux.1#L4725).
Unsetting a local value restores inheritance. Hook programs run in tmux when
their event occurs; see the [hook implementation](https://github.com/tmux/tmux/blob/94796f6b1182507efac8a272fc309a79e22e58a5/cmd-set-option.c).

</details>
