Fast, minimal Neovim plugin to automatically add or update copyright and license headers in any programming language.
- Add new copyright header
- Update existing copyright header
- Add common licenses, see here
- Use
LICENCEfile from git repository, see here - Project specific configuration, see here
- Keybindings, see here
- Neovim 0.8+
with packer.nvim
use({ "attilarepka/header.nvim", config = function() require("header").setup() end})with lazy.nvim
{
"attilarepka/header.nvim",
config = function()
require("header").setup()
end,
},The script comes with the following defaults:
{
allow_autocmds = true,
file_name = true,
author = nil,
project = nil,
date_created = true,
date_created_fmt = "%Y-%m-%d %H:%M:%S",
date_modified = true,
date_modified_fmt = "%Y-%m-%d %H:%M:%S",
line_separator = nil,
use_block_header = true,
copyright_text = nil,
license_from_file = false,
author_from_git = false,
}To override the custom configuration, call:
require("header").setup({
-- your override config
})Example:
require("header").setup({
allow_autocmds = true,
file_name = true,
author = "Foo",
project = "header.nvim",
date_created = true,
date_created_fmt = "%Y-%m-%d %H:%M:%S",
date_modified = true,
date_modified_fmt = "%Y-%m-%d %H:%M:%S",
line_separator = "------",
use_block_header = false,
copyright_text = {
"Copyright (c) 2023 Your Name",
"Your Company",
"All rights reserved."
},
license_from_file = false,
author_from_git = false,
})To automatically include a license header from a LICENSE-style file from your Git repository, set license_from_file to true:
require("header").setup({
...
license_from_file = true
})When enabled, the plugin will scan your project root for license-related files. If multiple candidates are found, you will be prompted to select one. The selected file will be cached for the duration of your current Neovim session to avoid repeated prompts.
Supported File Patterns
The following file names are recognized:
LICENSE,LICENSE.md,LICENSE-*LICENCE,LICENCE.md,LICENCE-*(British spelling)COPYING,COPYING.mdUNLICENSE,UNLICENSE.mdNOTICE,NOTICE.mdLEGAL,LEGAL.md
⚠️ Matching is case-sensitive by default and limited to the top-level directory.
Notes:
- This feature is useful when working on open-source projects that already include a license file.
- License headers inserted from a file will be commented automatically based on the current filetype.
- If you want to override the selected license file or insert a different one later, you can disable and re-enable the plugin, or restart Neovim.
The default configuration can be overwritten by a local project .header.nvim file with the following format:
{
"allow_autocmds": true,
"file_name": true,
"author": "Your Name",
"project": "Your Project",
"date_created": true,
"date_created_fmt": "%Y-%m-%d %H:%M:%S",
"date_modified": true,
"date_modified_fmt": "%Y-%m-%d %H:%M:%S",
"line_separator": "------",
"use_block_header": true,
"copyright_text": [
"Copyright (c) 2023 Your Name",
"Your Company",
"All rights reserved."
]
}To setup custom keybindings:
local header = require("header")
vim.keymap.set("n", "<leader>hh", function() header.add_headers() end)
-- see supported licenses below, method handles case-insensitively
vim.keymap.set("n", "<leader>hm", function() header.add_license_header("mit") end):AddHeaderAdds brief copyright information
:AddLicenseAGPL3Adds AGPL3 License:AddLicenseAPACHEAdds Apache License:AddLicenseBSD2Adds BSD2 License:AddLicenseBSD3Adds BSD3 License:AddLicenseCC0Adds CC0 License:AddLicenseGPL3Adds GPL3 License:AddLicenseISCAdds ISC License:AddLicenseMITAdds MIT License:AddLicenseMPLAdds MPL License:AddLicenseUNLICENSEAdds Unlicense License:AddLicenseWTFPLAdds WTFPL License:AddLicenseX11Adds X11 License:AddLicenseZLIBAdds ZLIB License
local augroup = vim.api.nvim_create_augroup
local autocmd = vim.api.nvim_create_autocmd
augroup("mygroup", { clear = true })
autocmd("BufWritePre", {
pattern = "*",
callback = function()
local header = require("header")
if header and header.update_date_modified then
header.update_date_modified()
else
vim.notify_once("header.update_date_modified is not available", vim.log.levels.WARN)
end
end,
group = "mygroup",
desc = "Update header's date modified",
})local augroup = vim.api.nvim_create_augroup
local autocmd = vim.api.nvim_create_autocmd
augroup("mygroup", { clear = true })
autocmd({ "BufNewFile", "BufReadPost" }, {
pattern = "*",
callback = function()
local header = require("header")
if not header then
vim.notify_once(
"Could not automatically add header to new file: header module couldn't be found",
vim.log.levels.ERROR
)
return
end
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
local is_empty = #lines == 1 and lines[1] == ""
if header.config.allow_autocmds and is_empty then
local original_fmt = header.config.date_created_fmt
local now = os.date(header.config.date_created_fmt, os.time())
-- force add_headers to use the current datetime, otherwise it will show 1970-01-01
header.config.date_created_fmt = now
header.add_headers()
header.config.date_created_fmt = original_fmt -- restore the original format
end
end,
group = "mygroup",
desc = "Add copyright header to new/empty files",
})
Contributions are welcome! Open a GitHub Issue or Pull request.
This project is licensed under the MIT license
