Files
watchexec.nvim/README.md
T

206 lines
8.5 KiB
Markdown
Raw Normal View History

2026-07-04 08:46:05 -05:00
# watchexec.nvim
2026-07-06 20:03:34 -05:00
Integrate the [watchexec](https://github.com/watchexec/watchexec) CLI into
Neovim - run file-watching commands and view their output in a floating or
2026-07-06 20:03:34 -05:00
split window.
## Features
- **Floating or split** output window, configurable per-user.
- **Status indicator** - a small non-focusable float that shows success or failure when the main window is hidden.
2026-07-06 20:03:34 -05:00
- **ANSI escape sequence stripping** so output is clean.
2026-07-06 20:07:44 -05:00
- **Keyword highlighting** via `DiagnosticError`, `DiagnosticWarn`, and `DiagnosticOk` for error/warning/success keywords in output.
2026-07-06 20:03:34 -05:00
- **Auto-scroll** to the latest output, with configurable buffer size limits.
- **Auto-resize** on `VimResized`, and automatic cleanup on `VimLeavePre`.
- **Binary auto-discovery** - searches PATH, `~/.cargo/bin`, Homebrew, and WSL locations.
2026-07-06 20:03:34 -05:00
## Requirements
- Neovim >= 0.10
- [watchexec CLI](https://github.com/watchexec/watchexec)
Install the CLI:
2026-07-06 20:07:44 -05:00
```pwsh
2026-07-06 20:03:34 -05:00
cargo install watchexec
```
Or download a prebuilt binary from the [releases page](https://github.com/watchexec/watchexec/releases).
## Installation
2026-07-06 20:07:44 -05:00
### lazy.nvim
2026-07-06 20:03:34 -05:00
```lua
{
2026-07-06 20:14:56 -05:00
"StevanFreeborn/watchexec.nvim",
2026-07-06 20:03:34 -05:00
opts = {},
}
```
2026-07-06 20:07:44 -05:00
### packer.nvim
2026-07-06 20:03:34 -05:00
```lua
use {
2026-07-06 20:14:56 -05:00
"StevanFreeborn/watchexec.nvim",
2026-07-06 20:03:34 -05:00
config = function()
require("watchexec").setup({})
end,
}
```
2026-07-06 20:07:44 -05:00
### vim-plug
2026-07-06 20:03:34 -05:00
```vim
2026-07-06 20:14:56 -05:00
Plug 'StevanFreeborn/watchexec.nvim'
2026-07-06 20:03:34 -05:00
lua require("watchexec").setup({})
```
## Quick Start
After installing, restart Neovim and run:
2026-07-06 20:07:44 -05:00
```txt
2026-07-06 20:03:34 -05:00
:WatchexecRun echo hello
```
Or press `<Leader>wxr`, type a command at the prompt, and press Enter.
The output window opens automatically. Press `q` or `<Esc>` inside the window
to close it. Press `<Leader>wxt` to toggle it back.
## Configuration
`setup()` accepts an optional table with the following fields:
### `watchexec` - binary options
2026-07-06 20:03:34 -05:00
2026-07-06 20:07:44 -05:00
| Field | Type | Default | Description |
|--------|----------|---------------|---------------------------------------------------------------------------------|
| `bin` | `string` | `"watchexec"` | Path to the watchexec executable. Auto-detected from PATH and common locations. |
| `args` | `table` | `{}` | Extra arguments passed to watchexec before the user command. |
2026-07-06 20:03:34 -05:00
### `window` - output window options
2026-07-06 20:03:34 -05:00
2026-07-06 20:07:44 -05:00
| Field | Type | Default | Description |
|----------|----------------------------------------------|---------------|--------------------------------------------------------|
| `type` | `"float"` / `"split"` | `"float"` | Window type. |
| `split` | `"below"` / `"above"` / `"left"` / `"right"` | `"below"` | Split direction (only used when `type` is `"split"`). |
| `size` | `integer` | `12` | Split window size in rows/columns. |
| `border` | `string` / `table` | `"single"` | Border style for floats (see `:help nvim_open_win()`). |
| `float` | `table` | *(see below)* | Float geometry. |
2026-07-06 20:03:34 -05:00
#### `window.float` - float geometry
2026-07-06 20:03:34 -05:00
2026-07-06 20:07:44 -05:00
| Field | Type | Default | Description |
|------------|----------|------------|---------------------------------------------------------------|
| `relative` | `string` | `"editor"` | Positioning anchor. |
| `width` | `number` | `0.8` | Width in columns (values <= 1 are fractions of editor width). |
| `height` | `number` | `0.6` | Height in rows (values <= 1 are fractions of editor height). |
| `row` | `number` | `0.5` | Row position (values <= 1 are fractions). |
| `col` | `number` | `0.5` | Column position (values <= 1 are fractions). |
2026-07-06 20:03:34 -05:00
### `indicator` - status indicator options
2026-07-06 20:03:34 -05:00
2026-07-06 20:07:44 -05:00
| Field | Type | Default | Description |
|--------------|-------------------------------------------------------------------|----------------------|----------------------------------|
| `enabled` | `boolean` | `true` | Enable/disable the indicator. |
| `position` | `"bottom-left"` / `"bottom-right"` / `"top-left"` / `"top-right"` | `"bottom-right"` | Screen corner. |
| `success_hl` | `string` | `"WatchexecSuccess"` | Highlight for success state. |
| `failure_hl` | `string` | `"WatchexecFailure"` | Highlight for failure state. |
| `width` | `integer` | `2` | Indicator width in cells. |
| `height` | `integer` | `1` | Indicator height in cells. |
| `padding` | `table` | `{ x = 1, y = 3 }` | Offset from editor edges. |
2026-07-06 20:07:44 -05:00
| `patterns` | `table` | *(see below)* | Lua patterns for parsing output. |
2026-07-06 20:03:34 -05:00
#### `indicator.patterns`
2026-07-06 20:07:44 -05:00
| Field | Type | Default | Description |
|-----------|----------|--------------------------------|---------------------------------------------|
2026-07-06 20:03:34 -05:00
| `success` | `string` | `"%[Command was successful%]"` | Pattern matching successful command output. |
2026-07-06 20:07:44 -05:00
| `running` | `string` | `"%[Running"` | Pattern matching command start. |
2026-07-06 20:03:34 -05:00
### General options
2026-07-06 20:07:44 -05:00
| Field | Type | Default | Description |
|---------------|-----------|---------|------------------------------------------------------|
| `auto_scroll` | `boolean` | `true` | Scroll to bottom on new output. |
2026-07-06 20:03:34 -05:00
| `max_lines` | `integer` | `5000` | Maximum lines in the output buffer (oldest trimmed). |
### Full config example
```lua
require("watchexec").setup({
auto_scroll = false,
max_lines = 1000,
watchexec = {
bin = "watchexec",
args = { "--shell", "bash" },
},
window = {
type = "split",
split = "below",
size = 15,
},
indicator = {
enabled = true,
position = "bottom-left",
},
})
```
## Commands
2026-07-06 20:07:44 -05:00
| Command | Description |
|---------------------------|---------------------------------------------------------------------------------------------------|
2026-07-06 20:03:34 -05:00
| `:WatchexecRun {command}` | Start watchexec with the given shell command. Stops any previous run and opens the output window. |
2026-07-06 20:07:44 -05:00
| `:WatchexecStop` | Stop the currently running watchexec process and clear the output. |
| `:WatchexecToggle` | Toggle the output window. |
2026-07-06 20:03:34 -05:00
## Keymaps
2026-07-06 20:07:44 -05:00
| Keymap | Action | Description |
|---------------|--------------------|----------------------------------|
| `<Leader>wxt` | `:WatchexecToggle` | Toggle the output window. |
| `<Leader>wxs` | `:WatchexecStop` | Stop the running process. |
| `<Leader>wxr` | `:WatchexecRun` | Prompt for a command and run it. |
2026-07-06 20:03:34 -05:00
## Highlight Groups
2026-07-06 20:07:44 -05:00
| Group | Default | Description |
|--------------------|-----------------|-------------------------------------------------------|
2026-07-06 20:03:34 -05:00
| `WatchexecSuccess` | `guibg=#00ff00` | Indicator background when the last command succeeded. |
2026-07-06 20:07:44 -05:00
| `WatchexecFailure` | `guibg=#ff0000` | Indicator background when the last command failed. |
2026-07-06 20:03:34 -05:00
Output lines are also highlighted using built-in diagnostic groups:
2026-07-06 20:07:44 -05:00
- `DiagnosticError` - for error, fail, fatal keywords
- `DiagnosticWarn` - for warning keywords
- `DiagnosticOk` - for success, passed, ok keywords
2026-07-06 20:03:34 -05:00
## API
```lua
---@param opts? watchexec.Config
require("watchexec").setup(opts)
---@param command string
require("watchexec").run(command)
require("watchexec").stop()
require("watchexec").toggle()
```
## Documentation
Full help is available in Neovim:
2026-07-06 20:07:44 -05:00
```txt
2026-07-06 20:03:34 -05:00
:help watchexec
```
## License
MIT