An open API service indexing awesome lists of open source software.

https://github.com/reybits/anvil.nvim

Asynchronous Makefile rule runner for Neovim with support for terminal and tmux.
https://github.com/reybits/anvil.nvim

neovim nvim nvim-plugin plugin

Last synced: about 1 month ago
JSON representation

Asynchronous Makefile rule runner for Neovim with support for terminal and tmux.

Awesome Lists containing this project

README

          

# anvil.nvim

A Neovim plugin that runs external commands asynchronously.
It can execute builds either inside Neovim's integrated terminal or in an external tmux pane.
The plugin provides a smooth workflow for compiling, running, and monitoring build results without blocking the editor.

## Features

- Run commands asynchronously in Neovim's terminal or a tmux pane.
- Automatic tmux detection (`mode = "auto"`).
- Output captured to quickfix list with large output truncation.
- Configurable terminal height and working directory.
- Job cancellation via `:AnvilStop`.
- Configurable timeout for long-running commands.
- Custom exit callbacks with notification support.
- Health check via `:checkhealth anvil`.

## Requirements

- Neovim >= 0.10
- (Optional) tmux for tmux mode.

## Installation

### [Lazy](https://github.com/folke/lazy.nvim)

```lua
{
"reybits/anvil.nvim",
keys = {
{ "rb", "Anvil make release", desc = "Build Release" },
{ "rs", "AnvilStop", desc = "Stop Build" },
},
cmd = {
"Anvil",
"AnvilStop",
},
opts = {},
}
```

## Configuration

The default configuration options are listed below:

```lua
opts = {
mode = "term", -- "auto" (tmux if available, else terminal) | "term" (always terminal)
log_to_qf = false, -- Log output to quickfix list.
open_qf_on_success = false, -- Open quickfix window on success.
open_qf_on_error = false, -- Open quickfix window on error.
close_on_success = false, -- Close the terminal/tmux pane on successful completion.
close_on_error = false, -- Close the terminal/tmux pane on error.
cwd = nil, -- Working directory for the command (nil = Neovim's cwd).
term_height = 0.3, -- Terminal/tmux pane height as a ratio of editor height (0.0-1.0).
timeout = 0, -- Timeout in seconds (0 = no timeout).
qf_max_lines = 10000, -- Max lines to load into quickfix (0 = unlimited). Keeps the tail.
title = "Command", -- Title used in notifications.
on_exit = function(code, o)
local title = o.title or "Anvil"
if code == 0 then
vim.notify(title .. " completed successfully.", vim.log.levels.INFO)
if o.open_qf_on_success then
vim.cmd("copen")
end
else
vim.notify(title .. " failed with exit code: " .. code, vim.log.levels.ERROR)
if o.open_qf_on_error then
vim.cmd("copen")
end
end
end,
}
```

## Usage

### Commands

| Command | Description |
|---|---|
| `:Anvil` | Run `make` (default command). |
| `:Anvil ` | Run an arbitrary shell command. |
| `:AnvilStop` | Stop the currently running job. |

### Lua API

```lua
local anvil = require("anvil")

-- Run default make
anvil.run()

-- Run a specific command
anvil.run("make release")

-- Run with per-call options
anvil.run("make test", {
log_to_qf = true,
open_qf_on_error = true,
close_on_success = true,
title = "Tests",
})

-- Run in a specific directory
anvil.run("make", { cwd = "~/projects/game" })

-- Run with a timeout (seconds)
anvil.run("make heavy-build", { timeout = 300 })

-- Stop the running job
anvil.stop()

-- Check if a job is running
if anvil.isRunning() then
vim.notify("Build in progress...")
end
```

### Keybinding Examples

```lua
keys = {
{ "rb", function()
require("anvil").run("make release", {
log_to_qf = true,
open_qf_on_error = true,
close_on_success = true,
title = "Release Build",
})
end, desc = "Build Release" },

{ "rB", function()
require("anvil").run("make debug", {
log_to_qf = true,
open_qf_on_error = true,
title = "Debug Build",
})
end, desc = "Build Debug" },

{ "rs", function()
require("anvil").stop()
end, desc = "Stop Build" },
}
```

## Quickfix Truncation

When `log_to_qf` is enabled and the build output exceeds `qf_max_lines`, only the tail of the log is loaded into the quickfix list (where build errors typically appear). A header line is added showing the total line count and the path to the full log file on disk for manual inspection.

## Health Check

Run `:checkhealth anvil` to verify the plugin configuration, tmux status, and job state.

> **Note:** The plugin must be loaded first (e.g. by running `:Anvil` or pressing a mapped key).
> Lazy-loaded plugins are not on the runtime path until triggered, so `:checkhealth` cannot discover the health module before that.

## License

[MIT License](LICENSE)

## Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.