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.
- Host: GitHub
- URL: https://github.com/reybits/anvil.nvim
- Owner: reybits
- License: mit
- Created: 2025-09-07T13:21:45.000Z (10 months ago)
- Default Branch: master
- Last Pushed: 2025-12-05T17:55:32.000Z (7 months ago)
- Last Synced: 2025-12-09T05:36:59.230Z (6 months ago)
- Topics: neovim, nvim, nvim-plugin, plugin
- Language: Lua
- Homepage:
- Size: 9.77 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
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.