223 lines
9.1 KiB
Markdown
223 lines
9.1 KiB
Markdown
<div align="center">
|
|
<img src="https://user-images.githubusercontent.com/5306901/141127528-ddff21bb-8da3-43da-8efe-9494a4f231d2.png" width=250><br>
|
|
|
|
# Neogen - Your Annotation Toolkit
|
|
|
|
[](https://neovim.io)
|
|
[](http://www.lua.org)
|
|
|
|
</div>
|
|
|
|
# Table Of Contents
|
|
|
|
- [Features](#features)
|
|
- [Requirements](#requirements)
|
|
- [Installation](#installation)
|
|
- [Usage](#usage)
|
|
- [Configuration](#configuration)
|
|
- [Supported Languages](#supported-languages)
|
|
- [Adding Languages](#adding-languages)
|
|
- [GIFS](#gifs)
|
|
- [Credits](#credits)
|
|
|
|
## Features
|
|
|
|
- Create annotations with one keybind, and jump your cursor in the inserted annotation
|
|
- Defaults for multiple languages and annotation conventions
|
|
- Extremely customizable and extensible
|
|
- Written in lua (and uses Tree-sitter)
|
|
|
|

|
|
|
|
## Requirements
|
|
|
|
- Install [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter)
|
|
|
|
## Installation
|
|
|
|
Use your favorite package manager to install Neogen, e.g:
|
|
|
|
```lua
|
|
use {
|
|
"danymat/neogen",
|
|
config = function()
|
|
require('neogen').setup {
|
|
enabled = true
|
|
}
|
|
end,
|
|
requires = "nvim-treesitter/nvim-treesitter"
|
|
}
|
|
```
|
|
|
|
## Usage
|
|
|
|
- If you want to keep it simple, you can use the `:Neogen` command:
|
|
|
|
```vim
|
|
" will generate annotation for the function you're inside
|
|
:Neogen
|
|
" or you can force a certain type of annotation.
|
|
" It'll find the next upper node that matches the type
|
|
" E.g if you're on a method of a class and do `:Neogen class`, it'll find the class declaration and generate the annotation.
|
|
:Neogen func|class|type|...
|
|
```
|
|
|
|
- If you like to use the lua API, I exposed a function to generate the annotations.
|
|
|
|
```lua
|
|
require('neogen').generate()
|
|
```
|
|
|
|
You can bind it to your keybind of choice, like so:
|
|
|
|
```lua
|
|
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:
|
|
|
|
```lua
|
|
require('neogen').generate({
|
|
type = "func" -- the annotation type to generate. Currently supported: func, class, type, file
|
|
})
|
|
```
|
|
|
|
For example, I can add an other keybind to generate class annotations:
|
|
|
|
```lua
|
|
local opts = { noremap = true, silent = true }
|
|
vim.api.nvim_set_keymap("n", "<Leader>nc", ":lua require('neogen').generate({ type = 'class' })<CR>", opts)
|
|
```
|
|
|
|
### Cycle between annotations
|
|
|
|
I added support passing cursor positionings in templates. That means you can now cycle your cursor between different parts of the annotation.
|
|
|
|
To configure it to the keybind of your choice, you can do something like this:
|
|
|
|
```lua
|
|
local opts = { noremap = true, silent = true }
|
|
vim.api.nvim_set_keymap("n", "<C-n>", ":lua require('neogen').jump_next()<CR>", opts)
|
|
vim.api.nvim_set_keymap("n", "<C-p>", ":lua require('neogen').jump_prev()<CR>", opts)
|
|
```
|
|
|
|
If you want to use a key that's already used for completion purposes, take a look at the code snippet here:
|
|
|
|
<details>
|
|
<summary>nvim-cmp</summary>
|
|
|
|
```lua
|
|
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 neogen.jumpable() then
|
|
vim.fn.feedkeys(t("<cmd>lua require('neogen').jump_next()<CR>"), "")
|
|
else
|
|
fallback()
|
|
end
|
|
end, {
|
|
"i",
|
|
"s",
|
|
}),
|
|
["<S-tab>"] = cmp.mapping(function(fallback)
|
|
if neogen.jumpable(-1) then
|
|
vim.fn.feedkeys(t("<cmd>lua require('neogen').jump_prev()<CR>"), "")
|
|
else
|
|
fallback()
|
|
end
|
|
end, {
|
|
"i",
|
|
"s",
|
|
}),
|
|
},
|
|
...
|
|
}
|
|
```
|
|
|
|
</details>
|
|
|
|
## Configuration
|
|
|
|
```lua
|
|
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>" -- (DROPPED SUPPORT, see [here](#cycle-between-annotations) !) 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:
|
|
|
|
```lua
|
|
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
|
|
}
|
|
},
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
Check out `:h neogen-advanced_configurations` for more information !
|
|
|
|
## Supported Languages
|
|
|
|
There is a list of supported languages and fields, with their annotation style
|
|
|
|
| Languages | Annotation Conventions | Supported annotation types |
|
|
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
|
|
| c | [Doxygen](https://www.doxygen.nl/manual/commands.html) (`"doxygen"`) | `func`, `file` |
|
|
| csharp | [Xmldoc](https://docs.microsoft.com/fr-fr/dotnet/csharp/language-reference/xmldoc/) (`"xmldoc"`) <br> [Doxygen](https://www.doxygen.nl/manual/commands.html) (`"doxygen"`) | `func`, `file`, `class` |
|
|
| cpp | [Doxygen](https://www.doxygen.nl/manual/commands.html) (`"doxygen"`) | `func`, `file`, `class` |
|
|
| go | [GoDoc](https://go.dev/blog/godoc) (`"godoc"`) | `func`, `type` |
|
|
| java | [Javadoc](https://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javadoc.html#documentationcomments) (`"javadoc`) | `func`, `class` |
|
|
| javascript | [JSDoc](https://jsdoc.app) (`"jsdoc"`) | `func`, `class`, `type`, `file` |
|
|
| lua | [Emmylua](https://emmylua.github.io/) (`"emmylua"`)<br> [Ldoc](https://stevedonovan.github.io/ldoc/manual/doc.md.html) (`"ldoc"`) | `func`, `class`, `type`, `file` |
|
|
| php | [Php-doc](https://docs.phpdoc.org/3.0/guide/references/phpdoc/index.html) (`"phpdoc"`) | `func`, `type`, `class` |
|
|
| python | [Google docstrings](https://google.github.io/styleguide/pyguide.html) (`"google_docstrings"`) <br> [Numpydoc](https://numpydoc.readthedocs.io/en/latest/format.html) (`"numpydoc"`) | `func`, `class`, `type`, `file` |
|
|
| rust | [RustDoc](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html) (`"rustdoc"`) <br> [Alternative](https://stackoverflow.com/questions/30009650/how-do-you-document-function-arguments) (`"alternative"`) | `func`, `file`, `class` |
|
|
| typescript | [JSDoc](https://jsdoc.app) (`"jsdoc"`) | `func`, `class`, `type`, `file` |
|
|
|
|
## Adding Languages
|
|
|
|
1. Using the defaults to generate a new language support: [Adding Languages](./docs/adding-languages.md)
|
|
2. (advanced) Only if the defaults aren't enough, please see here: [Advanced Integration](./docs/advanced-integration.md)
|
|
|
|
## GIFS
|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|
## Credits
|
|
|
|
- Binx, for making that gorgeous logo for free!
|
|
- [Github](https://github.com/Binx-Codes/)
|
|
- [Reddit](https://www.reddit.com/u/binxatmachine)
|