Home Explore Blog CI



nushell

1st chunk of `book/hooks.md`
8ad8dad7b8978211fb7808f7f76d1c2ca11f2f954083584b0000000100000fa0
# Hooks

Hooks allow you to run a code snippet at some predefined situations.
They are only available in the interactive mode ([REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)), they do not work if you run Nushell with a script (`nu script.nu`) or command (`nu -c "print foo"`) argument.

Currently, we support these types of hooks:

- `pre_prompt` : Triggered before the prompt is drawn
- `pre_execution` : Triggered before the line input starts executing
- `env_change` : Triggered when an environment variable changes
- `display_output` : A block that the output is passed to
- `command_not_found` : Triggered when a command is not found

To make it clearer, we can break down Nushell's execution cycle.
The steps to evaluate one line in the REPL mode are as follows:

1. Check for `pre_prompt` hooks and run them
1. Check for `env_change` hooks and run them
1. Display prompt and wait for user input
1. After user typed something and pressed "Enter": Check for `pre_execution` hooks and run them
1. Parse and evaluate user input
1. If a command is not found: Run the `command_not_found` hook. If it returns a string, show it.
1. If `display_output` is defined, use it to print command output
1. Return to 1.

## Basic Hooks

To enable hooks, define them in your [config](configuration.md):

```nu
$env.config.hooks = {
    pre_prompt: [{ print "pre prompt hook" }]
    pre_execution: [{ print "pre exec hook" }]
    env_change: {
        PWD: [{|before, after| print $"changing directory from ($before) to ($after)" }]
    }
}
```

Try putting the above into your config, running Nushell and moving around your filesystem.
When you change a directory, the `PWD` environment variable changes and the change triggers the hook with the previous and the current values stored in `before` and `after` variables, respectively.

Instead of defining just a single hook per trigger, it is possible to define a **list of hooks** which will run in sequence:

```nu
$env.config.hooks = {
    pre_prompt: [
        { print "pre prompt hook" }
        { print "pre prompt hook2" }
    ]
    pre_execution: [
        { print "pre exec hook" }
        { print "pre exec hook2" }
    ]
    env_change: {
        PWD: [
            {|before, after| print $"changing directory from ($before) to ($after)" }
            {|before, after| print $"changing directory from ($before) to ($after) 2" }
        ]
    }
}
```

Instead of replacing all hooks, you can append a new hook to existing configuration:

```nu
$env.config.hooks.pre_execution = $env.config.hooks.pre_execution | append { print "pre exec hook3" }
```

## Changing Environment

One feature of the hooks is that they preserve the environment.
Environment variables defined inside the hook **block** will be preserved in a similar way as [`def --env`](environment.md#defining-environment-from-custom-commands).
You can test it with the following example:

```nu
$env.config = ($env.config | upsert hooks {
    pre_prompt: { $env.SPAM = "eggs" }
})

$env.SPAM
# => eggs
```

The hook blocks otherwise follow the general scoping rules, i.e., commands, aliases, etc. defined within the block will be thrown away once the block ends.

## `pre_execution` Hooks

`pre_execution` hooks can inspect the to-be-executed command through the [`commandline` command](/commands/docs/commandline.md).

For example, to print the command being executed:

```nu
$env.config = (
    $env.config
    | upsert hooks.pre_execution [ {||
        $env.repl_commandline = (commandline)
        print $"Command: ($env.repl_commandline)"
    } ]
)

print (1 + 3)
# => Command: print (1 + 3)
# => 4
```

## Conditional Hooks

One thing you might be tempted to do is to activate an environment whenever you enter a directory:

```nu
$env.config = ($env.config | upsert hooks {
    env_change: {
        PWD: [
            {|before, after|
                if $after == /some/path/to/directory {
                    load-env { SPAM: eggs }
                }

Title: Nushell Hooks: Customizing the REPL Experience
Summary
Nushell hooks enable users to run custom code snippets at specific points in the interactive REPL mode, such as before the prompt, before execution, or when environment variables change. Hooks are configured in the Nushell configuration file and can modify the environment, inspect commands, and conditionally execute code based on specific conditions. Multiple hooks can be defined for each trigger, and new hooks can be appended to existing configurations. Hooks preserve environment variables defined within them, similar to `def --env`.