An asynchronous Neovim plugin for running checkpatch.pl (with full compatibility for QEMU 7.2+ and Linux kernel checkpatch.pl).
Populates Neovim's Quickfix list and native Diagnostics (vim.diagnostic) with errors, warnings, and style checks reported by checkpatch.pl.
- Multiple Execution Scopes:
:CheckpatchFile- Run checkpatch on the current active buffer/file.:CheckpatchModified- Run checkpatch on modified files in the working tree (filtered to modified lines by default).:CheckpatchStaged- Run checkpatch on staged files in git (filtered to staged lines by default).:CheckpatchAll- Run checkpatch on all tracked source files in the git repository.:CheckpatchClear- Clear checkpatch diagnostics and quickfix list.
- Diff Hunk Line Filtering: When running staged or modified checks,
checkpatch.nvimparsesgit diff -U0hunks to ensure only warnings/errors on modified lines are reported, ignoring pre-existing issues on unmodified lines. - Asynchronous Execution: Uses
vim.systemto prevent freezing the UI even when scanning thousands of files. - Full QEMU 7.2+ Compatibility: Tested specifically against QEMU 7.2
scripts/checkpatch.pl, with fallback support for standard multi-line kernel checkpatch formats. - Quickfix & Diagnostics Integration: Populates the quickfix list (
:copen) and places inline diagnostic signs and highlights (vim.diagnostic).
Using lazy.nvim:
{
"buxtonpaul/checkpatch.nvim",
config = function()
require("checkpatch").setup({
-- Custom path to checkpatch.pl (defaults to auto-detecting ./scripts/checkpatch.pl or PATH)
cmd = nil,
-- Flags passed to checkpatch.pl
extra_args = { "--no-tree", "--terse", "--no-summary" },
-- Automatically open quickfix list if issues are found
auto_open_quickfix = true,
-- Populate native vim.diagnostic
populate_diagnostics = true,
-- Populate quickfix list
populate_quickfix = true,
-- Only report issues on modified/added lines during staged and modified checks
filter_changed_lines = true,
-- Save buffer before checking if modified
save_before_check = true,
-- File extensions to include for modified/staged/all checks
file_extensions = { "c", "h", "cpp", "hpp", "cc", "hh", "cxx", "S" },
-- Show notifications
notify = true,
})
end,
}| Command | Description |
|---|---|
:CheckpatchFile |
Run checkpatch.pl on the current file |
:CheckpatchModified |
Run checkpatch.pl on modified working tree files in git (filtered to changed lines) |
:CheckpatchStaged |
Run checkpatch.pl on staged files in git (filtered to staged lines) |
:CheckpatchAll |
Run checkpatch.pl on all tracked files in git |
:CheckpatchClear |
Clear all checkpatch diagnostics and quickfix items |
You can also trigger checks programmatically from Lua or bind them to custom keymaps:
local checkpatch = require("checkpatch")
-- Keymaps example
vim.keymap.set("n", "<leader>cf", checkpatch.check_file, { desc = "Checkpatch current file" })
vim.keymap.set("n", "<leader>cm", checkpatch.check_modified, { desc = "Checkpatch modified files" })
vim.keymap.set("n", "<leader>cs", checkpatch.check_staged, { desc = "Checkpatch staged files" })
vim.keymap.set("n", "<leader>ca", checkpatch.check_all, { desc = "Checkpatch all files" })
vim.keymap.set("n", "<leader>cc", checkpatch.clear, { desc = "Checkpatch clear" })| Option | Type | Default | Description |
|---|---|---|---|
cmd |
`string | function | nil` |
extra_args |
table |
{ "--no-tree", "--terse", "--no-summary" } |
Command line flags passed to checkpatch.pl. |
auto_open_quickfix |
boolean |
true |
Open quickfix list automatically when errors/warnings are found. |
populate_diagnostics |
boolean |
true |
Publish issues to vim.diagnostic. |
populate_quickfix |
boolean |
true |
Populate Neovim quickfix list (setqflist). |
filter_changed_lines |
boolean |
true |
When enabled, filters :CheckpatchStaged and :CheckpatchModified results to only lines that were added/modified in the git diff. |
save_before_check |
boolean |
true |
Auto-save modified buffer before checking current file. |
file_extensions |
table |
{ "c", "h", "cpp", "hpp", "cc", "hh", "cxx", "S" } |
File extensions filtered when running batch checks (Modified, Staged, All). |
notify |
boolean |
true |
Show status notifications using vim.notify. |
Tests can be run headlessly using Neovim:
nvim --headless -u NONE -c "set runtimepath+=." -c "runtime plugin/checkpatch.lua" -c "luafile tests/run_tests.lua"
nvim --headless -u NONE -c "set runtimepath+=." -c "runtime plugin/checkpatch.lua" -c "luafile tests/test_git_commands.lua"
nvim --headless -u NONE -c "set runtimepath+=." -c "runtime plugin/checkpatch.lua" -c "luafile tests/test_staged_line_filter.lua"