AST-powered C/C++ header <-> implementation sync for Neovim using clangd.
This plugin helps you:
- Generate a function declaration in the paired header from a function definition in an implementation file.
- Generate an implementation stub in the paired source file from a declaration in a header.
- Inspect AST output for debugging.
- Uses
clangdAST requests (textDocument/ast, with fallback toclangd/ast). - Supports C and C++ source/header pairs.
- Handles storage class cleanup for header declarations:
- Keeps
static inlineandinline. - Strips
staticand warns. - Strips
externand warns.
- Keeps
- Includes K&R-style C function heuristic support when building declarations.
- Adds C++ scope prefixes when creating impl stubs from class/namespace declarations (for example
User::login). - Tries to avoid duplicate declarations/definitions by function name match.
- Neovim with Lua plugin support.
clangdattached to the current buffer via LSP.- A
clangdbuild/config that supports AST request methods used by this plugin.
If clangd is not attached or AST request fails, the plugin will notify with an error.
Use your preferred plugin manager.
{
"LinkNexus/cpp_header_sync.nvim",
config = function()
require("cpp_header_sync").setup()
end,
}use {
"LinkNexus/cpp_header_sync.nvim",
config = function()
require("cpp_header_sync").setup()
end,
}Replace LinkNexus/cpp_header_sync.nvim with the actual repository path.
require("cpp_header_sync").setup({
mappings = {
impl_to_header = "<leader>ch", -- default
header_to_impl = "<leader>ci", -- default
},
})Default keymaps:
<leader>ch: sync implementation -> header<leader>ci: sync header -> implementation
Set a mapping to nil to disable it:
require("cpp_header_sync").setup({
mappings = {
impl_to_header = nil,
header_to_impl = "<leader>ci",
},
})Place your cursor on a function and run one of:
-
require("cpp_header_sync").impl_to_header()- Use from
.c/.cpp/.cc/.cxx. - Inserts declaration into paired header (
.h/.hpp/.hxx).
- Use from
-
require("cpp_header_sync").header_to_impl()- Use from
.h/.hpp/.hxx. - Inserts function stub into paired implementation (
.c/.cpp/.cc/.cxx).
- Use from
-
require("cpp_header_sync").dump_ast()- Opens a split with
vim.inspect()output of AST response.
- Opens a split with
Given name.ext, pairing is based on file stem:
- From headers:
.hprefers.c, then.cpp/.cc/.cxx.hpp/.hxxprefer.cpp/.cc/.cxx, then.c
- From impl files:
- prefers existing
.h, then.hpp, then.hxx
- prefers existing
If no paired file exists, a default path is chosen (.h or .c/.cpp depending on source extension) and used for insertion.
- Header insertion is made before the last
#endifwhen present. - If a target file is empty, a header guard skeleton is auto-created.
- The plugin warns when cursor is on a struct function-pointer field, because that is not treated as a normal function declaration target.
Main module:
lua/cpp_header_sync/init.lua
The plugin currently exposes a Lua API rather than user commands; integrate via keymaps or direct Lua calls.