- Create annotations with one keybind, and jump your cursor using
Tab
. - Defaults for multiple languages and annotation conventions
- Extremely customizable and extensible
- Written in lua
- Install nvim-treesitter
Use your favorite package manager to install Neogen, e.g:
use {
"danymat/neogen",
config = function()
require('neogen').setup {
enabled = true
}
end,
requires = "nvim-treesitter/nvim-treesitter"
}
I exposed a function to generate the annotations.
require('neogen').generate()
You can bind it to your keybind of choice, like so:
local opts = { noremap = true, silent = true }
vim.api.nvim_set_keymap("n", "<Leader>nf", ":lua require('neogen').generate()<CR>", opts)
Calling the generate
function without any parameters will try to generate annotations for the current function.
You can provide some options for the generate, like so:
require('neogen').generate({
type = "func" -- the annotation type to generate. Currently supported: func, class, type
})
For example, I can add an other keybind to generate class annotations:
local opts = { noremap = true, silent = true }
vim.api.nvim_set_keymap("n", "<Leader>nc", ":lua require('neogen').generate({ type = 'class' })<CR>", opts)
I added support passing cursor positionings in templates.
That means you can now cycle your cursor between different parts of the annotation.
The default keybind is <C-e>
in insert mode.
If you want to add <Tab>
completion instead, be sure you don't have a completion plugin. If so, you have to configure them:
nvim-cmp
local cmp = require('cmp')
local neogen = require('neogen')
local t = function(str)
return vim.api.nvim_replace_termcodes(str, true, true, true)
end
local check_back_space = function()
local col = vim.fn.col '.' - 1
return col == 0 or vim.fn.getline('.'):sub(col, col):match '%s' ~= nil
end
cmp.setup {
...
-- You must set mapping if you want.
mapping = {
["<tab>"] = cmp.mapping(function(fallback)
if vim.fn.pumvisible() == 1 then
vim.fn.feedkeys(t("<C-n>"), "n")
elseif neogen.jumpable() then
vim.fn.feedkeys(t("<cmd>lua require('neogen').jump_next()<CR>"), "")
elseif check_back_space() then
vim.fn.feedkeys(t("<tab>"), "n")
else
fallback()
end
end, {
"i",
"s",
}),
},
...
}
require('neogen').setup {
enabled = true, --if you want to disable Neogen
input_after_comment = true, -- (default: true) automatic jump (with insert mode) on inserted annotation
jump_map = "<C-e>" -- The keymap in order to jump in the annotation fields (in insert mode)
}
}
If you're not satisfied with the default configuration for a language, you can change the defaults like this:
require('neogen').setup {
enabled = true,
languages = {
lua = {
template = {
annotation_convention = "emmylua" -- for a full list of annotation_conventions, see supported-languages below,
... -- for more template configurations, see the language's configuration file in configurations/{lang}.lua
}
},
...
}
}
There is a list of supported languages and fields, with their annotation style
Language | Annotation conventions | Supported fields |
---|---|---|
lua | ||
Emmylua ("emmylua" ) |
@param , @varargs , @return , @class , @type |
|
Ldoc ("ldoc" ) |
@param , @varargs , @return , @class , @type |
|
python | ||
Google docstrings ("google_docstrings" ) |
Args , Attributes , Returns |
|
Numpydoc ("numpydoc" ) |
Arguments , Attributes , Returns |
|
javascript | ||
JSDoc ("jsdoc" ) |
@param , @returns , @class , @classdesc |
|
c | ||
Doxygen ("doxygen" ) |
@param , @returns |
|
go | ||
Godoc ("godoc" ) |
- Using the defaults to generate a new language support: Adding Languages
- (advanced) Only if the defaults aren't enough, please see here: Advanced Integration