# Configure Key Bindings

In xplr, each keyboard input passes through a bunch of handlers (e.g. `on_key`, `on_number`, `default` etc.) in a given order. If any of the handlers is configured to with an action, it will intercept the key and produce messages for xplr to handle.

Try debug key bindings to understand how key bindings actually work.

## Key Bindings

Key bindings contains the following information:

- on_key
- on_alphabet
- on_number
- on_alphanumeric
- on_special_character
- on_character
- on_navigation
- on_function
- default

### on_key

Type: mapping of Key to nullable Action

Defines what to do when an exact key is pressed.

### on_alphabet

Type: nullable Action

An action to perform if the keyboard input is an alphabet and is not mapped via the on_key field.

### on_number

Type: nullable Action

An action to perform if the keyboard input is a number and is not mapped via the on_key field.

### on_alphanumeric

Type: nullable Action

An action to perform if the keyboard input is alphanumeric and is not mapped via the on_key, on_alphabet or on_number field.

### on_special_character

Type: nullable Action

An action to perform if the keyboard input is a special character and is not mapped via the on_key field.

### on_character

Type: nullable Action

An action to perform if the keyboard input is a character and is not mapped via the on_key, on_alphabet, on_number, on_alphanumeric or on_special_character field.

### on_navigation

Type: nullable Action

An action to perform if the keyboard input is a navigation key and is not mapped via the on_key field.

### on_function

Type: nullable Action

An action to perform if the keyboard input is a function key and is not mapped via the on_key field.

### default

Type: nullable Action

Default action to perform in case if a keyboard input not mapped via any of the `on_*` fields mentioned above.

## Key

A key is a sum type can be one of the following:

- 0, 1, ... 9
- a, b, ... z
- A, B, ... Z
- f1, f2, ... f12
- backspace
- left
- right
- up
- down
- home
- end
- page-up
- page-down
- back-tab
- delete
- insert
- enter
- tab
- esc
- ctrl-a, ctrl-b, ... ctrl-z
- ctrl-backspace, ctrl-left, ... ctrl-esc
- alt-a, alt-b, ... alt-z

And finally, the special characters - including space (`" "`) with their `ctrl` bindings.

## Action

An action contains the following information:

- help
- messages

### help

Type: nullable string

Description of what it does. If unspecified, it will be excluded from the help menu.

### messages

Type: A list of Message to send.

The list of messages to send when a key is pressed.

## Tutorial: Adding a New Mode

Assuming xplr is installed and setup, let's add our own mode to integrate xplr with fzf.

We'll call it `fzxplr` mode.

First, let's add a custom mode called `fzxplr`, and map the key `F` to an action that will call `fzf` to search and focus on a file or enter into a directory.

    xplr.config.modes.custom.fzxplr = {
      name = "fzxplr",
      key_bindings = {
        on_key = {
          F = {
            help = "search",
            messages = {
              {
                BashExec = [===[
                  PTH=$(cat "${XPLR_PIPE_DIRECTORY_NODES_OUT:?}" | awk -F/ '{print $NF}' | fzf)
                  if [ -d "$PTH" ]; then
                    "$XPLR" -m 'ChangeDirectory: %q' "$PTH"
                  else
                    "$XPLR" -m 'FocusPath: %q' "$PTH"
                  fi
                ]===]
              },
              "PopMode",
            },
          },
        },
        default = {
          messages = {
            "PopMode",
          },
        },
      },
    }

As you can see, the key `F` in mode `fzxplr` (the name can be anything) executes a script in `bash`.

`BashExec`, `PopMode`, `SwitchModeBuiltin`, `ChangeDirectory` and `FocusPath` are messages, `$XPLR`, `$XPLR_PIPE_DIRECTORY_NODES_OUT` are environment variables exported by `xplr` before executing the command. They contain the path to the input and output pipes that allows external tools to interact with `xplr`.

Now that we have our new mode ready, let's add an entry point to this mode via the `default` mode.

    xplr.config.modes.builtin.default.key_bindings.on_key["F"] = {
      help = "fzf mode",
      messages = {
        { SwitchModeCustom = "fzxplr" },
      },
    }

Now let's try out the new `xplr`-`fzf` integration.

Visit Awesome Plugins for more integration options.