# window.settings.Window.set_hooks

- **Module:** window.settings.Window
- **Package:** libtmux
- **Language:** Rust
- **Kind:** method
- **Source:** https://github.com/libtmux/libtmux-rs/blob/8a648c0894dfffc9303583f753b6c8ae01f2fe76/crates/libtmux/src/window/settings.rs#L221
- **Page:** https://libtmux.org/reference/rs/window-settings-window-set_hooks/

```
window.settings.Window.set_hooks(self, name: &str, hooks: &IndexedHooks, replace: ReplaceMode) -> Result<(), Error>
```

Write a whole hook at once.

[`ReplaceMode::Replace`] clears the hook first, so only what is
written remains; [`ReplaceMode::Merge`] leaves entries at indices the
write does not name.

Sent as one tmux invocation rather than one per index. That costs one
process instead of several, but it is not atomic: tmux applies a
shared invocation in order and stops at the first refusal, so a
rejected entry leaves the ones before it written.

# Errors

Returns an error when tmux rejects the name or any command.

Returns [`crate::Error::OptionScopeMismatch`] when tmux keeps the
option in another of its tables.

## Example

```rust
use std::collections::BTreeMap;
use libtmux::{IndexedHooks, ReplaceMode, TmuxText};

let guard = libtmux::test::TestServer::new().await?;
let session = guard.server().new_session("hooked").await?;
let window = session.active_window().await?.expect("a window");

let mut entries = BTreeMap::new();
entries.insert(0, TmuxText::from(b"display-message first".to_vec()));
entries.insert(3, TmuxText::from(b"display-message fourth".to_vec()));

window
    .set_hooks("pane-died", &IndexedHooks::from(entries), ReplaceMode::Replace)
    .await?;

let written = window.hook("pane-died").await?.expect("the hook is set");
assert_eq!(written.len(), 2);
assert!(written.get(1).is_none(), "the gap is kept");

guard.shutdown().await?;
```
