From 880c4a5c00feb536c491b64c0882326869bd1838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ortega=20Froysa?= Date: Fri, 10 Jul 2026 16:01:29 +0200 Subject: [PATCH] Add plugin code. --- plugin/licenser.vim | 132 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 plugin/licenser.vim diff --git a/plugin/licenser.vim b/plugin/licenser.vim new file mode 100644 index 0000000..4d64cec --- /dev/null +++ b/plugin/licenser.vim @@ -0,0 +1,132 @@ +" Zlib License +" +" Copyright (c) 2026 Nicolás A. Ortega +" +" This software is provided 'as-is', without any express or implied warranty. In +" no event will the authors be held liable for any damages arising from the use +" of this software. +" +" Permission is granted to anyone to use this software for any purpose, including +" commercial applications, and to alter it and redistribute it freely, subject +" to the following restrictions: +" +" 1. The origin of this software must not be misrepresented; you must not claim +" that you wrote the original software. If you use this software in a product, +" an acknowledgment in the product documentation would be appreciated but is +" not required. +" +" 2. Altered source versions must be plainly marked as such, and must not be +" misrepresented as being the original software. +" +" 3. This notice may not be removed or altered from any source distribution. +" vim-licenser: A plugin for adding license headers to source code files + +" Usage: +" :Licenser +" +" Available licenses can be found in the licenses/ directory + +if exists('g:loaded_licenser') + finish +endif +let g:loaded_licenser = 1 + +function! s:GetCommentStyle(filetype) abort + let ft = a:filetype + + " Define comment styles for different filetypes + " - margin: if prefix and suffix should be used + " - hashbang: if the file has a hashbang line, we should skip it when + " adding the license header + " - prefix: the string to use at the beginning of the comment block + " - middle: the string to use at the beginning of each line in the comment + " - suffix: the string to use at the end of the comment block + let comment_styles = { + \ 'bash': {'margin': 0, 'hashbang': 1, 'prefix': '', 'middle': '#', 'suffix': ''}, + \ 'c': {'margin': 1, 'hashbang': 0, 'prefix': '/*', 'middle': ' *', 'suffix': ' */'}, + \ 'cpp': {'margin': 1, 'hashbang': 0, 'prefix': '/*', 'middle': ' *', 'suffix': ' */'}, + \ 'go': {'margin': 1, 'hashbang': 0, 'prefix': '/*', 'middle': ' *', 'suffix': ' */'}, + \ 'html': {'margin': 1, 'hashbang': 0, 'prefix': ''}, + \ 'java': {'margin': 1, 'hashbang': 0, 'prefix': '/*', 'middle': ' *', 'suffix': ' */'}, + \ 'javascript': {'margin': 1, 'hashbang': 0, 'prefix': '/*', 'middle': ' *', 'suffix': ' */'}, + \ 'lua': {'margin': 0, 'hashbang': 1, 'prefix': '', 'middle': '--', 'suffix': ''}, + \ 'python': {'margin': 0, 'hashbang': 1, 'prefix': '', 'middle': '#', 'suffix': ''}, + \ 'ruby': {'margin': 0, 'hashbang': 1, 'prefix': '', 'middle': '#', 'suffix': ''}, + \ 'rust': {'margin': 1, 'hashbang': 0, 'prefix': '/*', 'middle': ' *', 'suffix': ' */'}, + \ 'shell': {'margin': 0, 'hashbang': 1, 'prefix': '', 'middle': '#', 'suffix': ''}, + \ 'typescript': {'margin': 1, 'hashbang': 0, 'prefix': '/*', 'middle': ' *', 'suffix': ' */'}, + \ 'vim': {'margin': 0, 'hashbang': 0, 'prefix': '', 'middle': '"', 'suffix': ''}, + \ 'xml': {'margin': 1, 'hashbang': 0, 'prefix': ''}, + \ } + if has_key(comment_styles, ft) + return comment_styles[ft] + else + " Error message for unsupported filetypes + echohl ErrorMsg + echo 'Unsupported filetype: ' . ft + echohl None + return {'margin': 0, 'prefix': '', 'middle': '', 'suffix': ''} + endif +endfunction + +function! s:AddLicenseHeader(license) abort + let plugin_dir = fnamemodify(expand(''), ':h:h') + let license_file = plugin_dir . '/licenses/' . a:license . '.txt' + + if !filereadable(license_file) + echohl ErrorMsg + echo 'License file not found: ' . license_file + echohl None + return + endif + + let license_lines = readfile(license_file) + let author = get(g:, 'licenser_author', 'Author Name') + let year = strftime('%Y') + + let comment_style = s:GetCommentStyle(&filetype) + + let processed_lines = [] + + if comment_style.margin + call add(processed_lines, comment_style.prefix) + endif + + for line in license_lines + let line = substitute(line, 'YEAR', year, 'g') + let line = substitute(line, 'AUTHOR', author, 'g') + + if line ==# '' + call add(processed_lines, comment_style.middle) + else + call add(processed_lines, comment_style.middle . ' ' . line) + endif + endfor + + if comment_style.margin + call add(processed_lines, comment_style.suffix) + endif + + call append(comment_style.hashbang, processed_lines) +endfunction + +function! s:CompleteFiletype(A, L, P) abort + let plugin_dir = fnamemodify(expand(''), ':h:h') + let licenses_dir = plugin_dir . '/licenses/' + + if !isdirectory(licenses_dir) + return [] + endif + + let licenses = [] + for file in glob(licenses_dir . '*.txt', 0, 1) + let name = fnamemodify(file, ':t:r') + if name =~ '^' . a:A + call add(licenses, name) + endif + endfor + + return sort(licenses) +endfunction + +command! -nargs=1 -complete=customlist,s:CompleteFiletype Licenser call s:AddLicenseHeader()