feat: help docs `:h comment-nvim` (#205)

Finally! We now have proper help docs for everything from keybindings to Lua API. It's auto generated from emmylua annotation so it would always be up to date.

Credits to https://github.com/phaazon/hop.nvim for excellent docs and reference.
This commit is contained in:
numToStr 2022-08-19 16:10:35 +05:30 committed by GitHub
parent ae8c440fe9
commit 089b972acc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1449 additions and 596 deletions

View File

@ -6,7 +6,6 @@ on:
- "**.lua"
branches:
- master
- docs
env:
PLUGIN_NAME: Comment

3
.gitignore vendored
View File

@ -41,3 +41,6 @@ luac.out
tmp
scratch
# ignore generated doc tags
doc/tags

136
README.md
View File

@ -6,7 +6,7 @@
### ✨ Features
- Supports treesitter. [Read more](#treesitter)
- Supports `commentstring`. [Read more](#commentstring)
- Supports `commentstring`. Read `:h comment.commentstring`
- Supports line (`//`) and block (`/* */`) comments
- Dot (`.`) repeat support for `gcc`, `gbc` and friends
- Count support for `[count]gcc` and `[count]gbc`
@ -37,6 +37,10 @@ Plug 'numToStr/Comment.nvim'
lua require('Comment').setup()
```
### 📖 Getting Help
`Comment.nvim` provides help docs which can be accessed by running `:help comment-nvim`
<a id="setup"></a>
### ⚒️ Setup
@ -63,46 +67,31 @@ EOF
#### Configuration (optional)
Following are the **default** config for the [`setup()`](#setup). If you want to override, just modify the option that you want then it will be merged with the default config.
Following are the **default** config for the [`setup()`](#setup). If you want to override, just modify the option that you want then it will be merged with the default config. Read `:h comment.config` for more info.
```lua
{
---Add a space b/w comment and the line
---@type boolean|fun():boolean
padding = true,
---Whether the cursor should stay at its position
---NOTE: This only affects NORMAL mode mappings and doesn't work with dot-repeat
---@type boolean
sticky = true,
---Lines to be ignored while comment/uncomment.
---Could be a regex string or a function that returns a regex string.
---Example: Use '^$' to ignore empty lines
---@type string|fun():string
---Lines to be ignored while (un)comment
ignore = nil,
---LHS of toggle mappings in NORMAL mode
---@type table
toggler = {
---Line-comment toggle keymap
line = 'gcc',
---Block-comment toggle keymap
block = 'gbc',
},
---LHS of operator-pending mappings in NORMAL mode
---LHS of mapping in VISUAL mode
---@type table
---LHS of operator-pending mappings in NORMAL and VISUAL mode
opleader = {
---Line-comment keymap
line = 'gc',
---Block-comment keymap
block = 'gb',
},
---LHS of extra mappings
---@type table
extra = {
---Add comment on the line above
above = 'gcO',
@ -111,29 +100,19 @@ Following are the **default** config for the [`setup()`](#setup). If you want to
---Add comment at the end of line
eol = 'gcA',
},
---Create basic (operator-pending) and extended mappings for NORMAL + VISUAL mode
---NOTE: If `mappings = false` then the plugin won't create any mappings
---@type boolean|table
---Enable keybindings
---NOTE: If given `false` then the plugin won't create any mappings
mappings = {
---Operator-pending mapping
---Includes `gcc`, `gbc`, `gc[count]{motion}` and `gb[count]{motion}`
---NOTE: These mappings can be changed individually by `opleader` and `toggler` config
---Operator-pending mapping; `gcc` `gbc` `gc[count]{motion}` `gb[count]{motion}`
basic = true,
---Extra mapping
---Includes `gco`, `gcO`, `gcA`
---Extra mapping; `gco`, `gcO`, `gcA`
extra = true,
---Extended mapping
---Includes `g>`, `g<`, `g>[count]{motion}` and `g<[count]{motion}`
---Extended mapping; `g>` `g<` `g>[count]{motion}` `g<[count]{motion}`
extended = false,
},
---Pre-hook, called before commenting the line
---@type fun(ctx: CommentCtx):string
---Function to call before (un)comment
pre_hook = nil,
---Post-hook, called after commenting is done
---@type fun(ctx: CommentCtx)
---Function to call after (un)comment
post_hook = nil,
}
```
@ -224,14 +203,6 @@ These mappings are disabled by default. (config: `mappings.extended`)
`gbac` - Toggle comment around a class (w/ LSP/treesitter support)
```
<a id="api"></a>
### ⚙️ API
- [Plug Mappings](./doc/plugs.md) - Excellent for creating custom keybindings
- [Lua API](./doc/API.md) - Details the Lua API. Great for making custom comment function.
<a id="treesitter"></a>
### 🌳 Treesitter
@ -254,12 +225,10 @@ There are two hook methods i.e `pre_hook` and `post_hook` which are called befor
<a id="pre-hook"></a>
- `pre_hook` - This method is called with a [`ctx`](#comment-context) argument before comment/uncomment is started. It can be used to return a custom `commentstring` which will be used for comment/uncomment the lines. You can use something like [nvim-ts-context-commentstring](https://github.com/JoosepAlviste/nvim-ts-context-commentstring) to compute the commentstring using treesitter.
- `pre_hook` - Called with a `ctx` argument (Read `:h comment.utils.CommentCtx`) before (un)comment. Can optionally return a `commentstring` to be used for (un)commenting. You can use [nvim-ts-context-commentstring](https://github.com/JoosepAlviste/nvim-ts-context-commentstring) to easily comment `tsx/jsx` files.
```lua
-- NOTE: The example below is a proper integration and it is RECOMMENDED.
{
---@param ctx CommentCtx
pre_hook = function(ctx)
-- Only calculate commentstring for tsx filetypes
if vim.bo.filetype == 'typescriptreact' then
@ -285,13 +254,14 @@ There are two hook methods i.e `pre_hook` and `post_hook` which are called befor
}
```
> **Note** - `Comment.nvim` already supports [`treesitter`](#treesitter) out-of-the-box except for `tsx/jsx`.
<a id="post-hook"></a>
- `post_hook` - This method is called after commenting is done. It receives the same [`ctx`](#comment-context) argument as [`pre_hook`](#pre_hook).
- `post_hook` - This method is called after (un)commenting. It receives the same `ctx` (Read `:h comment.utils.CommentCtx`) argument as [`pre_hook`](#pre_hook).
```lua
{
---@param ctx CommentCtx
post_hook = function(ctx)
if ctx.range.srow == ctx.range.erow then
-- do something with the current line
@ -347,7 +317,7 @@ ignore = '^const(.*)=(%s?)%((.*)%)(%s?)=>'
Most languages/filetypes have native support for comments via `commentstring` but there might be a filetype that is not supported. There are two ways to enable commenting for unsupported filetypes:
1. You can set `commentstring` for that particular filetype like the following
1. You can set `commentstring` for that particular filetype like the following. Read `:h commentstring` for more info.
```lua
vim.bo.commentstring = '//%s'
@ -356,27 +326,23 @@ vim.bo.commentstring = '//%s'
vim.api.nvim_command('set commentstring=//%s')
```
> Run `:h commentstring` for more help
<a id="ft-lua"></a>
2. You can also use this plugin interface to store both line and block commentstring for the filetype. You can treat this as a more powerful version of the `commentstring`
2. You can also use this plugin interface to store both line and block commentstring for the filetype. You can treat this as a more powerful version of the `commentstring`. Read `:h comment.ft` for more info.
```lua
local ft = require('Comment.ft')
-- 1. Using set function
-- Just set only line comment
ft.set('yaml', '#%s')
-- Or set both line and block commentstring
-- You can also chain the set calls
ft.set('javascript', {'//%s', '/*%s*/'}).set('conf', '#%s')
ft
-- Set only line comment
.set('yaml', '#%s')
-- Or set both line and block commentstring
.set('javascript', {'//%s', '/*%s*/'})
-- 2. Metatable magic
-- One filetype at a time
ft.javascript = {'//%s', '/*%s*/'}
ft.yaml = '#%s'
@ -391,56 +357,6 @@ ft.lang('javascript') -- { '//%s', '/*%s*/' }
> PR(s) are welcome to add more commentstring inside the plugin
<a id="commentstring"></a>
### 🧵 Comment String
Although, `Comment.nvim` supports neovim's `commentstring` but unfortunately it has the least priority. The commentstring is taken from the following place in the respective order.
- [`pre_hook`](#hooks) - If a string is returned from this method then it will be used for commenting.
- [`ft.lua`](#ft-lua) - If the current filetype is found in the table, then the string there will be used.
- `commentstring` - Neovim's native commentstring for the filetype
<a id="commentstring-caveat"></a>
> There is one caveat with this approach. If someone sets the `commentstring` (w/o returning a string) from the `pre_hook` method and if the current filetype also exists in the `ft_table` then the commenting will be done using the string in `ft_table` instead of using `commentstring`
<a id="comment-context"></a>
### 🧠 Comment Context
The following object is provided as an argument to `pre_hook` and `post_hook` functions.
> I am just placing it here just for documentation purpose
```lua
---Comment context
---@class CommentCtx
---@field ctype CommentType
---@field cmode CommentMode
---@field cmotion CommentMotion
---@field range CommentRange
---Range of the selection that needs to be commented
---@class CommentRange
---@field srow integer Starting row
---@field scol integer Starting column
---@field erow integer Ending row
---@field ecol integer Ending column
```
`CommentType`, `CommentMode` and `CommentMotion` all of them are exported from the plugin's utils for reuse
```lua
require('Comment.utils').ctype.{linewise,blockwise}
require('Comment.utils').cmode.{toggle,comment,uncomment}
require('Comment.utils').cmotion.{line,char,v,V}
```
### 🤝 Contributing
There are multiple ways to contribute reporting/fixing bugs, feature requests. You can also submit commentstring to this plugin by updating [ft.lua](./lua/Comment/ft.lua) and sending PR.

View File

@ -1,227 +1 @@
# ⚙️ API
Following are list of APIs that are exported from the plugin. These can be used to setup [custom keybinding](#usage) or to make your own custom comment function. All API functions can take a `{motion}` (Read `:h :map-operator`) and a optional [`{cfg}`](../README.md#config) argument which can be used to override the [default configuration](../README.md#config)
<details>
<summary>Deprecated API</summary>
```lua
---@alias OpMode 'line'|'char'|'v'|'V' Vim operator-mode motions. Read `:h map-operator`
```
### Core
These APIs powers the [basic-mappings](../README.md#basic-mappings).
```lua
--######### LINEWISE #########--
---Toggle linewise-comment on the current line
---@param cfg? CommentConfig
require('Comment.api').toggle_current_linewise(cfg)
---(Operator-Pending) Toggle linewise-comment on the current line
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').toggle_current_linewise_op(opmode, cfg)
---(Operator-Pending) Toggle linewise-comment over multiple lines
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').toggle_linewise_op(opmode, cfg)
---Toggle linewise-comment over multiple lines using `vim.v.count`
---@param cfg? CommentConfig
require('Comment.api').toggle_linewise_count(cfg)
--######### BLOCKWISE #########--
---Toggle blockwise comment on the current line
---@param cfg? CommentConfig
require('Comment.api').toggle_current_blockwise(cfg)
---(Operator-Pending) Toggle blockwise comment on the current line
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').toggle_current_blockwise_op(opmode, cfg)
---(Operator-Pending) Toggle blockwise-comment over multiple lines
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').toggle_blockwise_op(opmode, cfg)
---Toggle blockwise-comment over multiple lines using `vim.v.count`
---@param cfg? CommentConfig
require('Comment.api').toggle_blockwise_count(cfg)
```
### Extra
These APIs powers the [extra-mappings](../README.md#extra-mappings) and also provides the blockwise version.
```lua
--######### LINEWISE #########--
---Insert a linewise-comment below
---@param cfg? CommentConfig
require('Comment.api').insert_linewise_below(cfg)
---Insert a linewise-comment above
---@param cfg? CommentConfig
require('Comment.api').insert_linewise_above(cfg)
---Insert a linewise-comment at the end-of-line
---@param cfg? CommentConfig
require('Comment.api').insert_linewise_eol(cfg)
--######### BLOCKWISE #########--
---Insert a blockwise-comment below
---@param cfg? CommentConfig
require('Comment.api').insert_blockwise_below(cfg)
---Insert a blockwise-comment above
---@param cfg? CommentConfig
require('Comment.api').insert_blockwise_above(cfg)
---Insert a blockwise-comment at the end-of-line
---@param cfg? CommentConfig
require('Comment.api').insert_blockwise_eol(cfg)
```
### Extended
These APIs powers the [extended-mappings](../README.md#extended-mappings).
```lua
--######### LINEWISE #########--
---Comment current line using linewise-comment
---@param cfg? CommentConfig
require('Comment.api').comment_current_linewise(cfg)
---(Operator-Pending) Comment current line using linewise-comment
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').comment_current_linewise_op(opmode, cfg)
---(Operator-Pending) Comment multiple line using linewise-comment
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').comment_linewise_op(opmode, cfg)
---Uncomment current line using linewise-comment
---@param cfg? CommentConfig
require('Comment.api').uncomment_current_linewise(cfg)
---(Operator-Pending) Uncomment current line using linewise-comment
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').uncomment_current_linewise_op(opmode, cfg)
---(Operator-Pending) Uncomment multiple line using linewise-comment
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').uncomment_linewise_op(opmode, cfg)
--######### BLOCKWISE #########--
---Comment current line using linewise-comment
---@param cfg? CommentConfig
require('Comment.api').comment_current_blockwise(cfg)
---(Operator-Pending) Comment current line using blockwise-comment
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').comment_current_blockwise_op(opmode, cfg)
---Uncomment current line using blockwise-comment
---@param cfg? CommentConfig
require('Comment.api').uncomment_current_blockwise(cfg)
---(Operator-Pending) Uncomment current line using blockwise-comment
---@param opmode OpMode
---@param cfg? CommentConfig
require('Comment.api').uncomment_current_blockwise_op(opmode, cfg)
```
</details>
### Core
> **NOTE**:
>
> 1. All API functions are dot-repeatable except `*.count()`
> 2. For the `*.current()` functions, `{motion}` argument is optional
> 3. `{cfg}` is optional for all the API functions
```lua
require('Comment.api').toggle.linewise(motion, cfg)
require('Comment.api').toggle.linewise.current(motion, cfg)
require('Comment.api').toggle.linewise.count(count, cfg)
require('Comment.api').toggle.blockwise(motion, cfg)
require('Comment.api').toggle.blockwise.current(motion, cfg)
require('Comment.api').toggle.blockwise.count(count, cfg)
require('Comment.api').comment.linewise(motion, cfg)
require('Comment.api').comment.linewise.current(motion, cfg)
require('Comment.api').comment.linewise.count(count, cfg)
require('Comment.api').comment.blockwise(motion, cfg)
require('Comment.api').comment.blockwise.current(motion, cfg)
require('Comment.api').comment.blockwise.count(count, cfg)
require('Comment.api').uncomment.linewise(motion, cfg)
require('Comment.api').uncomment.linewise.current(motion, cfg)
require('Comment.api').uncomment.linewise.count(count, cfg)
require('Comment.api').uncomment.blockwise(motion, cfg)
require('Comment.api').uncomment.blockwise.current(motion, cfg)
require('Comment.api').uncomment.blockwise.count(count, cfg)
```
### Additional
```lua
---Callback function to provide dot-repeat support
---NOTE: VISUAL mode mapping doesn't support dot-repeat
---@param cb string Name of the API function to call
require('Comment.api').call(cb)
```
<a id="usage"></a>
# ⚙️ Usage
Following are some example keybindings using the APIs.
```lua
-- # NORMAL mode
-- Linewise toggle current line using C-/
vim.keymap.set('n', '<C-_>', '<CMD>lua require("Comment.api").toggle.linewise.current()<CR>')
-- or with dot-repeat support
-- vim.keymap.set('n', '<C-_>', '<CMD>lua require("Comment.api").call("toggle.linewise.current")<CR>g@$')
-- Blockwise toggle current line using C-\
vim.keymap.set('n', '<C-\\>', '<CMD>lua require("Comment.api").toggle.blockwise.current()<CR>')
-- or with dot-repeat support
-- vim.keymap.set('n', '<C-\\>', '<CMD>lua require("Comment.api").call("toggle.blockwise.current")<CR>g@$')
-- Linewise toggle multiple line using <leader>gc with dot-repeat support
-- Example: <leader>gc3j will comment 4 lines
vim.keymap.set('n', '<leader>gc', '<CMD>lua require("Comment.api").call("toggle.linewise")<CR>g@')
-- Blockwise toggle multiple line using <leader>gc with dot-repeat support
-- Example: <leader>gb3j will comment 4 lines
vim.keymap.set('n', '<leader>gb', '<CMD>lua require("Comment.api").call("toggle.blockwise")<CR>g@')
-- # VISUAL mode
-- Linewise toggle using C-/
vim.keymap.set('x', '<C-_>', '<ESC><CMD>lua require("Comment.api").toggle.linewise(vim.fn.visualmode())<CR>')
-- Blockwise toggle using <leader>gb
vim.keymap.set('x', '<leader>gb', '<ESC><CMD>lua require("Comment.api").toggle.blockwise(vim.fn.visualmode())<CR>')
```
`Comment.nvim` now has `:help` docs 🎉. Read `:h comment.api` for the Lua API documentation and usage.

874
doc/Comment.txt Normal file
View File

@ -0,0 +1,874 @@
*comment-nvim.txt* For Neovim version 0.7 Last change: 2021 July 11
_____ _ _
/ ____/ / / (_)
/ / ___ _ __ ___ _ __ ___ ___ _ __ / /_ _ ____ ___ _ __ ___
/ / / _ \/ '_ ` _ \/ '_ ` _ \ / _ \ '_ \/ __/ / '_ \ \ / / / '_ ` _ \
/ /___/ (_) / / / / / / / / / / / __/ / / / /_ _/ / / \ V // / / / / / /
\_____\___//_/ /_/ /_/_/ /_/ /_/\___/_/ /_/\__(_)_/ /_/\_/ /_/_/ /_/ /_/
· Smart and Powerful comment plugin ·
================================================================================
Table of Contents *comment.contents*
Introduction······················································|comment-nvim|
Usage····························································|comment.usage|
Configuration···················································|comment.config|
Keybindings················································|comment.keybindings|
Plug Mappings··················································|comment.plugmap|
Core Lua API·······················································|comment.api|
Language/Filetype detection·········································|comment.ft|
Utilities························································|comment.utils|
Operator-mode API···············································|comment.opfunc|
Insert API·······················································|comment.extra|
================================================================================
Introduction *comment-nvim*
Comment.nvim is a smart and powerful comment plugin for neovim. It supports
dot-repeat, counts, line ('//') and block ('/* */') comments, and can be used
with motion and text-objects. It has native integration with tressitter to
support embedded filetypes like html, vue, markdown with codeblocks etc.
*comment.dotrepeat*
Comment.nvim uses |operatorfunc| combined with |g@| to support dot-repeat, and
various marks i.e., |'[| |']| |'<| |'>| to deduce the region with the {motion}
argument provided by 'operatorfunc'. See |comment.api.call|
*comment.commentstring*
Comment.nvim picks commentstring, either linewise/blockwise, from one of the
following places
1. 'pre_hook'
If a string is returned from this function then it will be used for
(un)commenting. See |comment.config|
2. |comment.ft|
Using the commentstring table inside the plugin (using treesitter).
Fallback to |commentstring|, if not found.
3. |commentstring| - Neovim's native commentstring for the filetype
Although Comment.nvim supports native 'commentstring' but unfortunately it has
the least priority. The caveat with this approach is that if someone sets the
`commentstring`, without returning it, from the 'pre_hook' and the current
filetype also exists in the |comment.ft| then the commenting will be done using
the string in |comment.ft| instead of using 'commentstring'. To override this
behavior, you have to manually return the 'commentstring' from 'pre_hook'.
================================================================================
Usage *comment.usage*
Before using the plugin, you need to call the `setup()` function to create the
default mappings. If you want, you can also override the default configuration
by giving it a partial 'comment.config.Config' object, it will then be merged
with the default config.
C.setup({config?}) *comment.usage.setup*
Configures the plugin
Parameters: ~
{config?} (CommentConfig) User configuration
Returns: ~
{CommentConfig} Returns the mutated config
See: ~
|comment.config|
Usage: ~
>
require('Comment').setup({
ignore = '^$',
toggler = {
line = '<leader>cc',
block = '<leader>bc',
},
opleader = {
line = '<leader>c',
block = '<leader>b',
},
})
<
================================================================================
Configuration *comment.config*
CommentConfig *comment.config.CommentConfig*
Plugin's configuration
Fields: ~
{padding} (boolean) Controls space between the comment
and the line (default: 'true')
{sticky} (boolean) Whether cursor should stay at the
same position. Only works with NORMAL
mode mappings (default: 'true')
{ignore} (string|fun():string) Lua pattern used to ignore lines
during (un)comment (default: 'nil')
{mappings} (Mappings|boolean)
{toggler} (Toggler)
{opleader} (Opleader)
{extra} (ExtraMapping)
{pre_hook} (fun(ctx):string) Function to call before (un)comment
(default: 'nil')
{post_hook} (fun(ctx)) Function to call after (un)comment
(default: 'nil')
Mappings *comment.config.Mappings*
Create default mappings
Fields: ~
{basic} (boolean) Enables operator-pending mapping; `gcc`, `gbc`,
`gc{motion}` and `gb{motion}` (default: 'true')
{extra} (boolean) Enable extra mapping; `gco`, `gcO` and `gcA`
(default: 'true')
{extended} (boolean) Enable extended mapping; `g>`, `g<c`, 'g<b',
'g<', 'g<c', 'g<b', `g>{motion}` and `g<{motion}`
(default: 'false')
Toggler *comment.config.Toggler*
LHS of toggle mappings in NORMAL
Fields: ~
{line} (string) Linewise comment (default: 'gcc')
{block} (string) Blockwise comment (default: 'gbc')
Opleader *comment.config.Opleader*
LHS of operator-mode mappings in NORMAL and VISUAL mode
Fields: ~
{line} (string) Linewise comment (default: 'gc')
{block} (string) Blockwise comment (default: 'gb')
ExtraMapping *comment.config.ExtraMapping*
LHS of extra mappings
Fields: ~
{below} (string) Inserts comment below (default: 'gco')
{above} (string) Inserts comment above (default: 'gcO')
{eol} (string) Inserts comment at the end of line (default: 'gcA')
Config:get() *comment.config:get*
Get the config
Returns: ~
{CommentConfig}
Usage: ~
>
require('Comment.config'):get()
<
================================================================================
Keybindings *comment.keybindings*
Comment.nvim provides default keybinds which is used for (un)comment your code.
These keybinds are enabled upon calling |commen.usage.setup| and can be
configured or disabled, if desired.
Basic: ~
*gc*
*gb*
*gc[count]{motion}*
*gb[count]{motion}*
Toggle comment on a region using linewise/blockwise comment. In 'NORMAL'
mode, it uses 'Operator-Pending' mode to listen for an operator/motion.
In 'VISUAL' mode it simply comment the selected region.
*gcc*
*gbc*
*[count]gcc*
*[count]gbc*
Toggle comment on the current line using linewise/blockwise comment. If
prefixed with a 'v:count' then it will comment over the number of lines
corresponding to the {count}. These are only available in 'NORMAL' mode.
Extra: ~
*gco* - Inserts comment below and enters INSERT mode
*gcO* - Inserts comment above and enters INSERT mode
*gcA* - Inserts comment at the end of line and enters INSERT mode
================================================================================
Plug Mappings *comment.plugmap*
Comment.nvim provides <Plug> mappings for most commonly used actions. These
can be used to make custom keybindings and are enabled by default. All plug
mappings has support for dot-repeat except VISUAL mode keybindings. To create
custom comment function, check out 'comment.api' section.
*<Plug>(comment_toggle_linewise)*
*<Plug>(comment_toggle_blockwise)*
Toggle comment on a region with linewise/blockwise comment in NORMAL mode.
using |Operator-Pending| mode (or |g@|) to get the region to comment.
These powers the |gc| and |gb| keybindings.
*<Plug>(comment_toggle_linewise_current)*
*<Plug>(comment_toggle_blockwise_current)*
Toggle comment on the current line with linewise/blockwise comment in
NORMAL mode. These powers the |gcc| and 'gbc' keybindings.
*<Plug>(comment_toggle_linewise_count)*
*<Plug>(comment_toggle_blockwise_count)*
Toggle comment on a region using 'v:count' with linewise/blockwise comment
in NORMAL mode. These powers the |[count]gcc| and |[count]gbc| keybindings.
*<Plug>(comment_toggle_linewise_visual)*
*<Plug>(comment_toggle_blockwise_visual)*
Toggle comment on the selected region with linewise/blockwise comment in
NORMAL mode. These powers the |{visual}gc| and |{visual}gb| keybindings.
Usage: ~
>
-- Toggle current line or with count
vim.keymap.set('n', 'gcc', function()
return vim.v.count == 0
and '<Plug>(comment_toggle_linewise_current)'
or '<Plug>(comment_toggle_linewise_count)'
end, { expr = true })
-- Toggle in Op-pending mode
vim.keymap.set('n', 'gc', '<Plug>(comment_toggle_linewise)')
-- Toggle in VISUAL mode
vim.keymap.set('x', 'gc', '<Plug>(comment_toggle_linewise_visual)')
<
================================================================================
Core Lua API *comment.api*
This module provides the core lua APIs which is used by the default keybindings
and <Plug> (Read |comment.plugmap|) mappings. These API can be used to setup your
own custom keybindings or to even make your (un)comment function.
*comment.api.toggle.linewise*
*comment.api.toggle.blockwise*
api.toggle *comment.api.toggle*
Provides API to toggle comments over a region, on current-line, or with a
count using line or block comment string.
All functions takes a {motion} argument, except '*.count()' function which
takes an {count} argument, and an optional {config} parameter.
Type: ~
(table) A metatable containing API functions
See: ~
|comment.opfunc.OpMotion|
|comment.config|
Usage: ~
>
local api = require('Comment.api')
api.toggle.linewise(motion, config)
api.toggle.linewise.current(motion?, config?)
api.toggle.linewise.count(count, config?)
api.toggle.blockwise(motion, config?)
api.toggle.blockwise.current(motion?, config?)
api.toggle.blockwise.count(count, config?)
-- NORMAL mode
-- Toggle current line (linewise) using C-/
vim.keymap.set('n', '<C-_>', api.toggle.linewise.current)
-- Toggle current line (blockwise) using C-\
vim.keymap.set('n', '<C-\\>', api.toggle.blockwise.current)
-- Toggle lines (linewise) with dot-repeat support
-- Example: <leader>gc3j will comment 4 lines
vim.keymap.set(
'n', '<leader>gc', api.call('toggle.linewise', 'g@'),
{ expr = true }
)
-- Toggle lines (blockwise) with dot-repeat support
-- Example: <leader>gb3j will comment 4 lines
vim.keymap.set(
'n', '<leader>gb', api.call('toggle.blockwise', 'g@'),
{ expr = true }
)
-- VISUAL mode
local esc = vim.api.nvim_replace_termcodes(
'<ESC>', true, false, true
)
-- Linewise toggle (linewise)
vim.keymap.set('x', '<leader>c', function()
vim.api.nvim_feedkeys(esc, 'nx', false)
api.toggle.linewise(vim.fn.visualmode())
end)
-- Blockwise toggle (blockwise)
vim.keymap.set('x', '<leader>b', function()
vim.api.nvim_feedkeys(esc, 'nx', false)
api.toggle.blockwise(vim.fn.visualmode())
end)
<
*comment.api.comment.linewise*
*comment.api.comment.blockwise*
api.comment *comment.api.comment*
Provides API to (only) comment a region, on current-line, or with a
count using line or block comment string.
All functions takes a {motion} argument, except '*.count()' function which
takes an {count} argument, and an optional {config} parameter.
Type: ~
(table) A metatable containing API functions
See: ~
|comment.opfunc.OpMotion|
|comment.config|
Usage: ~
>
local api = require('Comment.api')
api.comment.linewise(motion, config)
api.comment.linewise.current(motion?, config?)
api.comment.linewise.count(count, config?)
api.comment.blockwise(motion, config?)
api.comment.blockwise.current(motion?, config?)
api.comment.blockwise.count(count, config?)
<
*comment.api.uncomment.linewise*
*comment.api.uncomment.blockwise*
api.uncomment *comment.api.uncomment*
Provides API to (only) uncomment a region, on current-line, or with a
count using line or block comment string.
All functions takes a {motion} argument, except '*.count()' function which
takes an {count} argument, and an optional {config} parameter.
Type: ~
(table) A metatable containing API functions
See: ~
|comment.opfunc.OpMotion|
|comment.config|
Usage: ~
>
local api = require('Comment.api')
api.uncomment.linewise(motion, config)
api.uncomment.linewise.current(motion?, config?)
api.uncomment.linewise.count(count, config?)
api.uncomment.blockwise(motion, config?)
api.uncomment.blockwise.current(motion?, config?)
api.uncomment.blockwise.count(count, config?)
<
api.insert *comment.api.insert*
Provides API to to insert comment on previous, next or at the end-of-line.
All functions takes an optional {config} parameter.
Type: ~
(table) A metatable containing API functions
See: ~
|comment.config|
Usage: ~
>
local api = require('Comment.api')
api.insert.linewise.above(cfg?)
api.insert.linewise.below(cfg?)
api.insert.linewise.eol(cfg?)
api.insert.blockwise.above(cfg?)
api.insert.blockwise.below(cfg?)
api.insert.blockwise.eol(cfg?)
<
api.locked *comment.api.locked*
Wraps the given API function with 'lockmarks' to preserve marks/jumps
Type: ~
(fun(cb:string):fun(motion:OpMotion))
See: ~
|lockmarks|
|comment.opfunc.OpMotion|
Usage: ~
>
local api = require('Comment.api')
vim.keymap.set(
'n', '<leader>c', api.locked('toggle.linewise.current')
)
local esc = vim.api.nvim_replace_termcodes(
'<ESC>', true, false, true
)
vim.keymap.set('x', '<leader>c', function()
vim.api.nvim_feedkeys(esc, 'nx', false)
api.locked('toggle.linewise')(vim.fn.visualmode())
end)
-- NOTE: `locked` method is just a wrapper around `lockmarks`
vim.api.nvim_command([[
lockmarks lua require('Comment.api').toggle.linewise.current()
]])
<
api.call({cb}, {op}) *comment.api.call*
Callback function which does the following
1. Sets 'operatorfunc' for dot-repeat
2. Preserves jumps and marks
3. Stores last cursor position
Parameters: ~
{cb} (string) Name of the API function to call
{op} ('g@'|'g@$') Operator string to execute
Returns: ~
{fun():string} Keymap RHS callback
See: ~
|g@|
|operatorfunc|
Usage: ~
>
local api = require('Comment.api')
vim.keymap.set(
'n', 'gc', api.call('toggle.linewise', 'g@'),
{ expr = true }
)
vim.keymap.set(
'n', 'gcc', api.call('toggle.linewise.current', 'g@$'),
{ expr = true }
)
<
================================================================================
Language/Filetype detection *comment.ft*
ft.set({lang}, {val}) *comment.ft.set*
Sets a commentstring(s) for a filetype/language
Parameters: ~
{lang} (string) Filetype/Language of the buffer
{val} (string|string[])
Returns: ~
{table} Returns itself
Usage: ~
>
local ft = require('Comment.ft')
--1. Using method signature
-- Set only line comment or both
-- You can also chain the set calls
ft.set('yaml', '#%s').set('javascript', {'//%s', '/*%s*/'})
-- 2. Metatable magic
ft.javascript = {'//%s', '/*%s*/'}
ft.yaml = '#%s'
-- 3. Multiple filetypes
ft({'go', 'rust'}, {'//%s', '/*%s*/'})
ft({'toml', 'graphql'}, '#%s')
<
ft.get({lang}, {ctype}) *comment.ft.get*
Get line/block commentstring for a given filetype
Parameters: ~
{lang} (string) Filetype/Language of the buffer
{ctype} (integer) See |comment.utils.ctype|
Returns: ~
{string} Commentstring
Usage: ~
>
local ft = require('Comment.ft')
local U = require('Comment.utils')
print(ft.get(vim.bo.filetype, U.ctype.linewise))
<
ft.lang({lang}) *comment.ft.lang*
Get a copy of commentstring(s) for a given filetype
Parameters: ~
{lang} (string) Filetype/Language of the buffer
Returns: ~
{string[]} Tuple of { line, block } commentstring
Usage: ~
>
require('Comment.ft').lang(vim.bo.filetype)
<
ft.contains({tree}, {range}) *comment.ft.contains*
Get a language tree for a given range by walking the parse tree recursively.
This uses 'lua-treesitter' API under the hood. This can be used to calculate
language of a particular region which embedded multiple filetypes like html,
vue, markdown etc.
NOTE: This ignores `tree-sitter-comment` parser, if installed.
Parameters: ~
{tree} (userdata) Parse tree to be walked
{range} (integer[]) Range to check for
{start_row, start_col, end_row, end_col}
Returns: ~
{userdata} Returns a |treesitter-languagetree|
See: ~
|treesitter-languagetree|
|lua-treesitter-core|
Usage: ~
>
local ok, parser = pcall(vim.treesitter.get_parser, 0)
assert(ok, "No parser found!")
local tree = require('Comment.ft').contains(parser, {0, 0, -1, 0})
print('Lang:', tree:lang())
<
ft.calculate({ctx}) *comment.ft.calculate*
Calculate commentstring with the power of treesitter
Parameters: ~
{ctx} (CommentCtx)
Returns: ~
{string} Commentstring
See: ~
|comment.utils.CommentCtx|
================================================================================
Utilities *comment.utils*
CommentCtx *comment.utils.CommentCtx*
Comment context
Fields: ~
{ctype} (integer) See |comment.utils.ctype|
{cmode} (integer) See |comment.utils.cmode|
{cmotion} (integer) See |comment.utils.cmotion|
{range} (CommentRange)
CommentRange *comment.utils.CommentRange*
Range of the selection that needs to be commented
Fields: ~
{srow} (integer) Starting row
{scol} (integer) Starting column
{erow} (integer) Ending row
{ecol} (integer) Ending column
CommentMode *comment.utils.CommentMode*
Comment modes - Can be manual or computed via operator-mode
Fields: ~
{toggle} (integer) Toggle action
{comment} (integer) Comment action
{uncomment} (integer) Uncomment action
U.cmode *comment.utils.cmode*
An object containing comment modes
Type: ~
(CommentMode)
CommentType *comment.utils.CommentType*
Comment types
Fields: ~
{linewise} (integer) Use linewise commentstring
{blockwise} (integer) Use blockwise commentstring
U.ctype *comment.utils.ctype*
An object containing comment types
Type: ~
(CommentType)
CommentMotion *comment.utils.CommentMotion*
Comment motion types
Fields: ~
{line} (integer) Line motion (ie. 'gc2j')
{char} (integer) Character/left-right motion (ie. 'gc2w')
{block} (integer) Visual operator-pending motion
{v} (integer) Visual motion (ie. 'v3jgc')
{V} (integer) Visual-line motion (ie. 'V10kgc')
U.cmotion *comment.utils.cmotion*
An object containing comment motions
Type: ~
(CommentMotion)
U.get_region({opmode?}) *comment.utils.get_region*
Get region for line movement or visual selection
NOTE: Returns the current line region, if `opmode` is not given.
Parameters: ~
{opmode?} (OpMotion)
Returns: ~
{CommentRange}
U.get_count_lines({count}) *comment.utils.get_count_lines*
Get lines from the current position to the given count
Parameters: ~
{count} (integer) Probably 'vim.v.count'
Returns: ~
{string[]} of lines
{CommentRange}
U.get_lines({range}) *comment.utils.get_lines*
Get lines from a NORMAL/VISUAL mode
Parameters: ~
{range} (CommentRange)
Returns: ~
{string[]} of lines
U.unwrap_cstr({cstr}) *comment.utils.unwrap_cstr*
Validates and unwraps the given commentstring
Parameters: ~
{cstr} (string) See 'commentstring'
Returns: ~
{string} Left side of the commentstring
{string} Right side of the commentstring
U.parse_cstr({cfg}, {ctx}) *comment.utils.parse_cstr*
Parses commentstring from the following places in the respective order
1. pre_hook - commentstring returned from the function
2. ft.lua - commentstring table bundled with the plugin
3. commentstring - Neovim's native. See 'commentstring'
Parameters: ~
{cfg} (CommentConfig)
{ctx} (CommentCtx)
Returns: ~
{string} Left side of the commentstring
{string} Right side of the commentstring
*comment.utils.commenter*
U.commenter({left}, {right}, {padding}, {scol?}, {ecol?})
Returns a closure which is used to do comments
If given {string[]} to the closure then it will do blockwise comment
else linewise comment will be done with the given {string}
Parameters: ~
{left} (string) Left side of the commentstring
{right} (string) Right side of the commentstring
{padding} (boolean) Is padding enabled?
{scol?} (integer) Starting column
{ecol?} (integer) Ending column
Returns: ~
{fun(line:string|string[]):string}
*comment.utils.uncommenter*
U.uncommenter({left}, {right}, {padding}, {scol?}, {ecol?})
Returns a closure which is used to uncomment a line
If given {string[]} to the closure then it will block uncomment
else linewise uncomment will be done with the given {string}
Parameters: ~
{left} (string) Left side of the commentstring
{right} (string) Right side of the commentstring
{padding} (boolean) Is padding enabled?
{scol?} (integer) Starting column
{ecol?} (integer) Ending column
Returns: ~
{fun(line:string|string[]):string}
*comment.utils.is_commented*
U.is_commented({left}, {right}, {padding}, {scol?}, {ecol?})
Check if the given string is commented or not
If given {string[]} to the closure, it will check the first and last line
with LHS and RHS of commentstring respectively else it will check the given
line with LHS and RHS (if given) of the commenstring
Parameters: ~
{left} (string) Left side of the commentstring
{right} (string) Right side of the commentstring
{padding} (boolean) Is padding enabled?
{scol?} (integer) Starting column
{ecol?} (integer) Ending column
Returns: ~
{fun(line:string|string[]):boolean}
================================================================================
Operator-mode API *comment.opfunc*
Underlying functions that powers the |comment.api.toggle|, |comment.api.comment|,
and |comment.api.uncomment| lua API.
OpMotion *comment.opfunc.OpMotion*
Vim operator-mode motion enum. Read |:map-operator|
Variants: ~
('line') Vertical motion
('char') Horizontal motion
('v') Visual Block motion
('V') Visual Line motion
*comment.opfunc.opfunc*
Op.opfunc({motion?}, {cfg}, {cmode}, {ctype})
Common operatorfunc callback
This function contains the core logic for comment/uncomment
Parameters: ~
{motion?} (OpMotion) If given 'nil', it'll only (un)comment
the current line
{cfg} (CommentConfig)
{cmode} (integer) See |comment.utils.cmode|
{ctype} (integer) See |comment.utils.ctype|
*comment.opfunc.count*
Op.count({count}, {cfg}, {cmode}, {ctype})
Line commenting with count
Parameters: ~
{count} (integer) Value of |v:count|
{cfg} (CommentConfig)
{cmode} (integer) See |comment.utils.cmode|
{ctype} (integer) See |comment.utils.ctype|
OpFnParams *comment.opfunc.OpFnParams*
Operator-mode function parameters
Fields: ~
{cfg} (CommentConfig)
{cmode} (integer) See |comment.utils.cmode|
{lines} (string[]) List of lines
{rcs} (string) RHS of commentstring
{lcs} (string) LHS of commentstring
{range} (CommentRange)
Op.linewise({param}) *comment.opfunc.linewise*
Line commenting
Parameters: ~
{param} (OpFnParams)
Returns: ~
{integer} Returns a calculated comment mode
Op.blockwise({param}, {partial?}) *comment.opfunc.blockwise*
Full/Partial/Current-Line Block commenting
Parameters: ~
{param} (OpFnParams)
{partial?} (boolean) Comment the partial region (visual mode)
Returns: ~
{integer} Returns a calculated comment mode
================================================================================
Insert API *comment.extra*
Underlying functions that powers the |comment.api.insert| lua API.
extra.insert_below({ctype}, {cfg}) *comment.extra.insert_below*
Add a comment below the current line and goes to INSERT mode
Parameters: ~
{ctype} (integer) See |comment.utils.ctype|
{cfg} (CommentConfig)
extra.insert_above({ctype}, {cfg}) *comment.extra.insert_above*
Add a comment above the current line and goes to INSERT mode
Parameters: ~
{ctype} (integer) See |comment.utils.ctype|
{cfg} (CommentConfig)
extra.insert_eol({ctype}, {cfg}) *comment.extra.insert_eol*
Add a comment at the end of current line and goes to INSERT mode
Parameters: ~
{ctype} (integer) See |comment.utils.ctype|
{cfg} (CommentConfig)
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -1,34 +1 @@
## 🔌 Plug Mappings
Following are the `<Plug>` mappings which you can use to quickly setup your custom keybindings
- `<Plug>(comment_toggle_linewise)` - Toggles line comment via Operator pending mode
- `<Plug>(comment_toggle_blockwise)` - Toggles block comment via Operator pending mode
- `<Plug>(comment_toggle_linewise_current)` - Toggles line comment on the current line
- `<Plug>(comment_toggle_blockwise_current)` - Toggles block comment on the current line
- `<Plug>(comment_toggle_linewise_count)` - Toggles line comment with count
- `<Plug>(comment_toggle_blockwise_count)` - Toggles block comment with count
- `<Plug>(comment_toggle_linewise_visual)` - Toggles line comment in VISUAL mode
- `<Plug>(comment_toggle_blockwise_visual)` - Toggles block comment in VISUAL mode
> NOTE: There are only meant for custom keybindings but If you want to create a custom comment function then be sure to check out all the [API](./API.md).
#### Usage
Following snippets is same as the default mappings set by the plugin.
```lua
local opt = { expr = true, remap = true, replace_keycodes = false }
-- Toggle using count
vim.keymap.set('n', 'gcc', "v:count == 0 ? '<Plug>(comment_toggle_linewise_current)' : '<Plug>(comment_toggle_linewise_count)'", opt)
vim.keymap.set('n', 'gbc', "v:count == 0 ? '<Plug>(comment_toggle_blockwise_current)' : '<Plug>(comment_toggle_blockwise_count)'", opt)
-- Toggle in Op-pending mode
vim.keymap.set('n', 'gc', '<Plug>(comment_toggle_linewise)')
vim.keymap.set('n', 'gb', '<Plug>(comment_toggle_blockwise)')
-- Toggle in VISUAL mode
vim.keymap.set('x', 'gc', '<Plug>(comment_toggle_linewise_visual)')
vim.keymap.set('x', 'gb', '<Plug>(comment_toggle_blockwise_visual)')
```
`Comment.nvim` now has `:help` docs 🎉. Read `:h comment.plugmap` for the `<Plug>` mappings documentation and usage.

View File

@ -1,56 +0,0 @@
-- TODO
-- [x] Handle Tabs
-- [x] Dot repeat
-- [x] Comment multiple line.
-- [x] Hook support
-- [x] pre
-- [x] post
-- [x] Custom (language) commentstring support
-- [x] Block comment basic ie. /* */ (for js)
-- [-] Block comment extended
-- [x] left-right-motions
-- [x] Partial blocks ie. gba{ gbaf
-- [ ] V-BLOCK (IDK, maybe)
-- [ ] Char motion covering mutliple lines ie. gc300w (level: HARD)
-- [-] Treesitter Integration
-- [ ] Better comment detection
-- [x] Context commentstring
-- [x] Port `commentstring` from tcomment
-- [x] Ignore line
-- [x] Disable `extra` mapping by default
-- [x] Provide more arguments to pre and post hooks
-- [x] `ignore` as a function
-- [x] Return the operator's starting and ending position in pre and post hook
-- [x] Restore cursor position in some motion operator (try `gcip`)
-- [ ] Doc comment ie. /** */ (for js)
-- [ ] Header comment
-- FIXME
-- [x] visual mode not working correctly
-- [x] space after and before of commentstring
-- [x] multiple line behavior to tcomment
-- [x] preserve indent
-- [x] determine comment status (to comment or not)
-- [x] prevent uncomment on uncommented line
-- [x] `comment` and `toggle` misbehaving when there is leading space
-- [x] messed up indentation, if the first line has greater indentation than next line (calc min indendation)
-- [x] `gcc` empty line not toggling comment
-- [x] Optimize blockwise mode (just modifiy the start and end line)
-- [x] Weird commenting when the first line is empty and the whole is indented
-- [x] no padding support in block-x
-- THINK:
-- [ ] Dot support for `[count]gcc` and `[count]gbc`
-- [ ] Parse `comments` if block comment is missing in the plugin
-- ITS_OK:
-- 1. Weird comments, if you do comments on already commented lines incl. an extra empty line
-- 2. Conflict when uncommenting interchangebly with line/block wise comment
-- 3. `ignore` doesn't work in blockwise and blockwise_x
-- 4. When a empty line is b/w two commented blocks then it should uncomment instead of commenting again in toggle.
-- DROPPED:
-- 1. Insert mode mapping (also move the cursor after commentstring)
-- 2. Use `nvim_buf_get_text` instead of `nvim_buf_get_lines`. Blocked by https://github.com/neovim/neovim/pull/15181
-- 3. Use `nvim_buf_set_text` instead of `nvim_buf_set_lines`
-- 4. Dot repeat support for visual mode mappings (Doesn't make sense)

View File

@ -1,4 +1,9 @@
---@mod comment.api API functions
---@mod comment.api Core Lua API
---@brief [[
---This module provides the core lua APIs which is used by the default keybindings
---and <Plug> (Read |comment.plugmap|) mappings. These API can be used to setup your
---own custom keybindings or to even make your (un)comment function.
---@brief ]]
local Config = require('Comment.config')
local U = require('Comment.utils')
@ -281,7 +286,7 @@ function core.__index(that, ctype)
---To comment lines with a count
function idxd.count(count, cfg)
Op.count(Config.count or count, cfg or Config:get(), U.ctype[ctype])
Op.count(Config.count or count, cfg or Config:get(), that.cmode, U.ctype[ctype])
end
---@private
@ -299,60 +304,126 @@ function core.__index(that, ctype)
})
end
---API to toggle comments using line or block comment string
---@tag comment.api.toggle.linewise
---@tag comment.api.toggle.blockwise
---Provides API to toggle comments over a region, on current-line, or with a
---count using line or block comment string.
---
---Following are the API functions that are available:
---
---require('Comment.api').toggle.linewise({motion}, {cfg?})
---require('Comment.api').toggle.linewise.current({motion?}, {cfg?})
---require('Comment.api').toggle.linewise.count({count}, {cfg?})
---
---require('Comment.api').toggle.blockwise({motion}, {cfg?})
---require('Comment.api').toggle.blockwise.current({motion?}, {cfg?})
---require('Comment.api').toggle.blockwise.count({count}, {cfg?})
---All functions takes a {motion} argument, except '*.count()' function which
---takes an {count} argument, and an optional {config} parameter.
---@type table A metatable containing API functions
---@see comment.opfunc.OpMotion
---@see comment.config
---@usage [[
---local api = require('Comment.api')
---
---api.toggle.linewise(motion, config)
---api.toggle.linewise.current(motion?, config?)
---api.toggle.linewise.count(count, config?)
---
---api.toggle.blockwise(motion, config?)
---api.toggle.blockwise.current(motion?, config?)
---api.toggle.blockwise.count(count, config?)
---
----- Toggle current line (linewise) using C-/
---vim.keymap.set('n', '<C-_>', api.toggle.linewise.current)
---
----- Toggle current line (blockwise) using C-\
---vim.keymap.set('n', '<C-\\>', api.toggle.blockwise.current)
---
----- Toggle lines (linewise) with dot-repeat support
----- Example: <leader>gc3j will comment 4 lines
---vim.keymap.set(
--- 'n', '<leader>gc', api.call('toggle.linewise', 'g@'),
--- { expr = true }
---)
---
----- Toggle lines (blockwise) with dot-repeat support
----- Example: <leader>gb3j will comment 4 lines
---vim.keymap.set(
--- 'n', '<leader>gb', api.call('toggle.blockwise', 'g@'),
--- { expr = true }
---)
---
---local esc = vim.api.nvim_replace_termcodes(
--- '<ESC>', true, false, true
---)
---
----- Toggle selection (linewise)
---vim.keymap.set('x', '<leader>c', function()
--- vim.api.nvim_feedkeys(esc, 'nx', false)
--- api.toggle.linewise(vim.fn.visualmode())
---end)
---
----- Toggle selection (blockwise)
---vim.keymap.set('x', '<leader>b', function()
--- vim.api.nvim_feedkeys(esc, 'nx', false)
--- api.toggle.blockwise(vim.fn.visualmode())
---end)
---@usage ]]
api.toggle = setmetatable({ cmode = U.cmode.toggle }, core)
---API to (only) comment using line or block comment string
---@tag comment.api.comment.linewise
---@tag comment.api.comment.blockwise
---Provides API to (only) comment a region, on current-line, or with a
---count using line or block comment string.
---
---Following are the API functions that are available:
---
---require('Comment.api').comment.linewise({motion}, {cfg?})
---require('Comment.api').comment.linewise.current({motion?}, {cfg?})
---require('Comment.api').comment.linewise.count({count}, {cfg?})
---
---require('Comment.api').comment.blockwise({motion}, {cfg?})
---require('Comment.api').comment.blockwise.current({motion?}, {cfg?})
---require('Comment.api').comment.blockwise.count({count}, {cfg?})
---All functions takes a {motion} argument, except '*.count()' function which
---takes an {count} argument, and an optional {config} parameter.
---@type table A metatable containing API functions
---@see comment.opfunc.OpMotion
---@see comment.config
---@usage [[
---local api = require('Comment.api')
---
---api.comment.linewise(motion, config)
---api.comment.linewise.current(motion?, config?)
---api.comment.linewise.count(count, config?)
---
---api.comment.blockwise(motion, config?)
---api.comment.blockwise.current(motion?, config?)
---api.comment.blockwise.count(count, config?)
---@usage ]]
api.comment = setmetatable({ cmode = U.cmode.comment }, core)
---API to (only) uncomment using line or block comment string
---@tag comment.api.uncomment.linewise
---@tag comment.api.uncomment.blockwise
---Provides API to (only) uncomment a region, on current-line, or with a
---count using line or block comment string.
---
---Following are the API functions that are available:
---
---require('Comment.api').uncomment.linewise({motion}, {cfg?})
---require('Comment.api').uncomment.linewise.current({motion?}, {cfg?})
---require('Comment.api').uncomment.linewise.count({count}, {cfg?})
---
---require('Comment.api').uncomment.blockwise({motion}, {cfg?})
---require('Comment.api').uncomment.blockwise.current({motion?}, {cfg?})
---require('Comment.api').uncomment.blockwise.count({count}, {cfg?})
---All functions takes a {motion} argument, except '*.count()' function which
---takes an {count} argument, and an optional {config} parameter.
---@type table A metatable containing API functions
api.uncomment = setmetatable({ cmode = U.cmode.comment }, core)
---@see comment.opfunc.OpMotion
---@see comment.config
---@usage [[
---local api = require('Comment.api')
---
---api.uncomment.linewise(motion, config)
---api.uncomment.linewise.current(motion?, config?)
---api.uncomment.linewise.count(count, config?)
---
---api.uncomment.blockwise(motion, config?)
---api.uncomment.blockwise.current(motion?, config?)
---api.uncomment.blockwise.count(count, config?)
---@usage ]]
api.uncomment = setmetatable({ cmode = U.cmode.uncomment }, core)
---API to insert comment on previous, next or at the end-of-line
---
---Following are the API functions that are available:
---
---require('Comment.api').insert.linewise.above({cfg?})
---require('Comment.api').insert.linewise.below({cfg?})
---require('Comment.api').insert.linewise.eol({cfg?})
---
---require('Comment.api').insert.blockwise.above({cfg?})
---require('Comment.api').insert.blockwise.below({cfg?})
---require('Comment.api').insert.blockwise.eol({cfg?})
---Provides API to to insert comment on previous, next or at the end-of-line.
---All functions takes an optional {config} parameter.
---@type table A metatable containing API functions
---@see comment.config
---@usage [[
---local api = require('Comment.api')
---
---api.insert.linewise.above(cfg?)
---api.insert.linewise.below(cfg?)
---api.insert.linewise.eol(cfg?)
---
---api.insert.blockwise.above(cfg?)
---api.insert.blockwise.below(cfg?)
---api.insert.blockwise.eol(cfg?)
---@usage ]]
api.insert = setmetatable({}, {
__index = function(_, ctype)
return {
@ -369,17 +440,41 @@ api.insert = setmetatable({}, {
end,
})
---Wraps a given function with `lockmarks` to preserve marks/jumps when commenting
-- TODO: After removing old API
-- 1. make `api.locked` a simple function call
-- 2. fix emmylua doc
---Wraps the given API function with 'lockmarks' to preserve marks/jumps
---@type fun(cb:string):fun(motion:OpMotion)
---@usage `require('Comment.api').locked('toggle.linewise.current')()`
---@see lockmarks
---@see comment.opfunc.OpMotion
---@usage [[
---local api = require('Comment.api')
---
---vim.keymap.set(
--- 'n', '<leader>c', api.locked('toggle.linewise.current')
---)
---
---local esc = vim.api.nvim_replace_termcodes(
--- '<ESC>', true, false, true
---)
---vim.keymap.set('x', '<leader>c', function()
--- vim.api.nvim_feedkeys(esc, 'nx', false)
--- api.locked('toggle.linewise')(vim.fn.visualmode())
---end)
---
----- NOTE: `locked` method is just a wrapper around `lockmarks`
---vim.api.nvim_command([[
--- lockmarks lua require('Comment.api').toggle.linewise.current()
---]])
---@usage ]]
api.locked = setmetatable({}, {
__index = function(this, cb)
D(string.format('locker.%s(args...)', cb), string.format('locked(%q)(args...)', cb))
return this(cb)
end,
-- TODO: After removal of the old api functions, make `api.locked` a simple function call
__call = function(_, cb)
---Actual function which will be attached to operatorfunc
---operatorfunc callback
---@param motion OpMotion
return function(motion)
return A.nvim_command(
@ -390,13 +485,25 @@ api.locked = setmetatable({}, {
})
---Callback function which does the following
--- 1. Sets operatorfunc for dot-repeat
--- 1. Sets 'operatorfunc' for dot-repeat
--- 2. Preserves jumps and marks
--- 3. Stores last cursor position
---@param cb string Name of the API function to call
---@param op 'g@'|'g@$' Operator string to execute
---@return fun():string _ Keymap RHS callback
---@usage `vim.keymap.set('n', 'gc', api.call('toggle.linewise', 'g@'), { expr = true })`
---@see g@
---@see operatorfunc
---@usage [[
---local api = require('Comment.api')
---vim.keymap.set(
--- 'n', 'gc', api.call('toggle.linewise', 'g@'),
--- { expr = true }
---)
---vim.keymap.set(
--- 'n', 'gcc', api.call('toggle.linewise.current', 'g@$'),
--- { expr = true }
---)
---@usage ]]
function api.call(cb, op)
return function()
A.nvim_set_option('operatorfunc', ("v:lua.require'Comment.api'.locked'%s'"):format(cb))

View File

@ -1,45 +1,92 @@
---@mod comment.config Configuration
---@class Toggler LHS of toggle mappings in NORMAL + VISUAL mode
---@field line string Linewise comment keymap
---@field block string Blockwise comment keymap
---@class Opleader LHS of operator-mode mappings in NORMAL + VISUAL mode
---@field line string Linewise comment keymap
---@field block string Blockwise comment keymap
---@class ExtraMapping LHS of extra mappings
---@field above string Mapping to add comment on the line above
---@field below string Mapping to add comment on the line below
---@field eol string Mapping to add comment at the end of line
---@class Mappings Create default mappings
---Enable operator-pending mapping
---Includes `gcc`, `gbc`, `gc[count]{motion}` and `gb[count]{motion}`
---NOTE: These mappings can be changed individually by `opleader` and `toggler` config
---@field basic boolean
---Enable extra mapping
---Includes `gco`, `gcO`, `gcA`
---@field extra boolean
---Enable extended mapping
---Includes `g>`, `g<`, `g>[count]{motion}` and `g<[count]{motion}`
---@field extended boolean
---@tag comment.config.defaults
---@brief [[
---Following is the default config for the |comment.usage.setup|. If you want to
---override, just modify the option that you want, then it will be merged with the
---default config.
---
--->
--- {
--- padding = true,
--- sticky = true,
--- ignore = nil,
--- toggler = {
--- line = 'gcc',
--- block = 'gbc',
--- },
--- opleader = {
--- line = 'gc',
--- block = 'gb',
--- },
--- extra = {
--- above = 'gcO',
--- below = 'gco',
--- eol = 'gcA',
--- },
--- mappings = {
--- basic = true,
--- extra = true,
--- extended = false,
--- },
--- pre_hook = nil,
--- post_hook = nil,
--- }
---<
---@brief ]]
---@class CommentConfig Plugin's configuration
---@field padding boolean Add a space b/w comment and the line
---Whether the cursor should stay at its position
---NOTE: This only affects NORMAL mode mappings and doesn't work with dot-repeat
---Controls space between the comment
---and the line (default: 'true')
---@field padding boolean|fun():boolean
---Whether cursor should stay at the
---same position. Only works in NORMAL
---mode mappings (default: 'true')
---@field sticky boolean
---Lines to be ignored while comment/uncomment.
---Could be a regex string or a function that returns a regex string.
---Example: Use '^$' to ignore empty lines
---Lua pattern used to ignore lines
---during (un)comment (default: 'nil')
---@field ignore string|fun():string
---@field mappings boolean|Mappings
---Enables |comment.keybindings|
---NOTE: If given 'false', then the
---plugin won't create any mappings
---@field mappings Mappings|false
---@field toggler Toggler
---@field opleader Opleader
---@field extra ExtraMapping
---@field pre_hook fun(ctx:CommentCtx):string Function to be called before comment/uncomment
---@field post_hook fun(ctx:CommentCtx) Function to be called after comment/uncomment
---Function to call before (un)comment.
---It is called with a {ctx} argument
---of type |comment.utils.CommentCtx|
---(default: 'nil')
---@field pre_hook fun(ctx):string
---Function to call after (un)comment.
---It is called with a {ctx} argument
---of type |comment.utils.CommentCtx|
---(default: 'nil')
---@field post_hook fun(ctx)
---@class Mappings Create default mappings
---Enables operator-pending mapping; `gcc`, `gbc`,
---`gc{motion}` and `gb{motion}` (default: 'true')
---@field basic boolean
---Enable extra mapping; `gco`, `gcO` and `gcA`
---(default: 'true')
---@field extra boolean
---Enable extended mapping; `g>`, `g<c`, 'g<b',
---'g<', 'g<c', 'g<b', `g>{motion}` and `g<{motion}`
---(default: 'false')
---@field extended boolean
---@class Toggler LHS of toggle mappings in NORMAL
---@field line string Linewise comment (default: 'gcc')
---@field block string Blockwise comment (default: 'gbc')
---@class Opleader LHS of operator-mode mappings in NORMAL and VISUAL mode
---@field line string Linewise comment (default: 'gc')
---@field block string Blockwise comment (default: 'gb')
---@class ExtraMapping LHS of extra mappings
---@field below string Inserts comment below (default: 'gco')
---@field above string Inserts comment above (default: 'gcO')
---@field eol string Inserts comment at the end of line (default: 'gcA')
---@private
---@class RootConfig
@ -72,9 +119,12 @@ local Config = {
},
}
---Update the config
---@private
---Updates the default config
---@param cfg? CommentConfig
---@return RootConfig
---@see comment.usage.setup
---@usage `require('Comment.config'):set({config})`
function Config:set(cfg)
if cfg then
self.config = vim.tbl_deep_extend('force', self.config, cfg)
@ -84,11 +134,12 @@ end
---Get the config
---@return CommentConfig
---@usage `require('Comment.config'):get()`
function Config:get()
return self.config
end
---@export ft
---@export Config
return setmetatable(Config, {
__index = function(this, k)
return this.state[k]

View File

@ -1,4 +1,7 @@
---@mod comment.extra Extra functions
---@mod comment.extra Extra API
---@brief [[
---Underlying functions that powers the |comment.api.insert| lua API.
---@brief ]]
local U = require('Comment.utils')
local A = vim.api
@ -30,7 +33,7 @@ local function ins_on_line(lnum, ctype, cfg)
local srow = row + lnum
local lcs, rcs = U.parse_cstr(cfg, ctx)
local padding = U.get_pad(cfg.padding)
local padding = U.get_pad(U.is_fn(cfg.padding))
-- We need RHS of cstr, if we are doing block comments or if RHS exists
-- because even in line comment RHS do exists for some filetypes like jsx_element, ocaml
@ -73,7 +76,7 @@ function extra.insert_eol(ctype, cfg)
local lcs, rcs = U.parse_cstr(cfg, ctx)
local line = A.nvim_get_current_line()
local padding = U.get_pad(cfg.padding)
local padding = U.get_pad(U.is_fn(cfg.padding))
-- We need RHS of cstr, if we are doing block comments or if RHS exists
-- because even in line comment RHS do exists for some filetypes like jsx_element, ocaml

View File

@ -1,4 +1,9 @@
---@mod comment.ft Language or Filetype detection
---@mod comment.ft Language/Filetype detection
---@brief [[
---This module is the core of filetype and commentstring detection and uses the
---|lua-treesitter| APIs to accurately detect filetype and gives the corresponding
---commentstring, stored inside the plugin, for the filetype/langauge.
---@brief ]]
local A = vim.api
@ -108,37 +113,71 @@ local L = {
local ft = {}
---@alias CommentLang string Filetype/Language of the buffer
---Sets a commentstring(s) for a filetype/language
---@param lang CommentLang
---@param lang string Filetype/Language of the buffer
---@param val string|string[]
---@return table self Returns itself
---@usage [[
---local ft = require('Comment.ft')
---
-----1. Using method signature
----- Set only line comment or both
----- You can also chain the set calls
---ft.set('yaml', '#%s').set('javascript', {'//%s', '/*%s*/'})
---
----- 2. Metatable magic
---ft.javascript = {'//%s', '/*%s*/'}
---ft.yaml = '#%s'
---
----- 3. Multiple filetypes
---ft({'go', 'rust'}, {'//%s', '/*%s*/'})
---ft({'toml', 'graphql'}, '#%s')
---@usage ]]
function ft.set(lang, val)
L[lang] = type(val) == 'string' and { val } or val --[[ @as string[] ]]
return ft
end
---Get a commentstring from the filtype list
---@param lang CommentLang
---Get line/block commentstring for a given filetype
---@param lang string Filetype/Language of the buffer
---@param ctype integer See |comment.utils.ctype|
---@return string
---@return string _ Commentstring
---@usage [[
---local ft = require('Comment.ft')
---local U = require('Comment.utils')
---print(ft.get(vim.bo.filetype, U.ctype.linewise))
---@usage ]]
function ft.get(lang, ctype)
local l = ft.lang(lang)
local l = L[lang]
return l and l[ctype]
end
---Get the commentstring(s) from the filtype list
---@param lang CommentLang
---@return string[]
---Get a copy of commentstring(s) for a given filetype
---@param lang string Filetype/Language of the buffer
---@return string[] _ Tuple of { line, block } commentstring
---@usage `require('Comment.ft').lang(vim.bo.filetype)`
function ft.lang(lang)
return L[lang]
return vim.deepcopy(L[lang])
end
---Get the tree in range by walking the whole tree recursively
---NOTE: This ignores `comment` parser as this is not needed
---@param tree userdata Tree to be walked
---@param range integer[] Range to check - {start_line, s_col, end_line, end_col}
---@return userdata _ Returns a 'treesitter-languagetree'
---Get a language tree for a given range by walking the parse tree recursively.
---This uses 'lua-treesitter' API under the hood. This can be used to calculate
---language of a particular region which embedded multiple filetypes like html,
---vue, markdown etc.
---
---NOTE: This ignores `tree-sitter-comment` parser, if installed.
---@param tree userdata Parse tree to be walked
---@param range integer[] Range to check for
---{start_row, start_col, end_row, end_col}
---@return userdata _ Returns a |treesitter-languagetree|
---@see treesitter-languagetree
---@see lua-treesitter-core
---@usage [[
---local ok, parser = pcall(vim.treesitter.get_parser, 0)
---assert(ok, "No parser found!")
---local tree = require('Comment.ft').contains(parser, {0, 0, -1, 0})
---print('Lang:', tree:lang())
---@usage ]]
function ft.contains(tree, range)
for lang, child in pairs(tree:children()) do
if lang ~= 'comment' and child:contains(range) then
@ -149,9 +188,10 @@ function ft.contains(tree, range)
return tree
end
---Calculate commentstring w/ the power of treesitter
---Calculate commentstring with the power of treesitter
---@param ctx CommentCtx
---@return string
---@return string _ Commentstring
---@see comment.utils.CommentCtx
function ft.calculate(ctx)
local buf = A.nvim_get_current_buf()
local ok, parser = pcall(vim.treesitter.get_parser, buf)

View File

@ -1,10 +1,91 @@
---@mod comment.nvim Welcome to Comment.nvim
---@brief [[
---*comment-nvim.txt* For Neovim version 0.7 Last change: 2021 July 11
---
--- _____ _ _
--- / ____/ / / (_)
--- / / ___ _ __ ___ _ __ ___ ___ _ __ / /_ _ ____ ___ _ __ ___
--- / / / _ \/ '_ ` _ \/ '_ ` _ \ / _ \ '_ \/ __/ / '_ \ \ / / / '_ ` _ \
--- / /___/ (_) / / / / / / / / / / / __/ / / / /_ _/ / / \ V // / / / / / /
--- \_____\___//_/ /_/ /_/_/ /_/ /_/\___/_/ /_/\__(_)_/ /_/\_/ /_/_/ /_/ /_/
---
--- · Smart and Powerful comment plugin ·
---
---@brief ]]
---@toc comment.contents
---@mod comment-nvim Introduction
---@brief [[
---Comment.nvim is a smart and powerful comment plugin for neovim. It supports
---dot-repeat, counts, line ('//') and block ('/* */') comments, and can be used
---with motion and text-objects. It has native integration with |tressitter| to
---support embedded filetypes like html, vue, markdown with codeblocks etc.
---@brief ]]
---@tag comment.dotrepeat
---@brief [[
---Comment.nvim uses |operatorfunc| combined with |g@| to support dot-repeat, and
---various marks i.e., |'[| |']| |'<| |'>| to deduce the region with the {motion}
---argument provided by 'operatorfunc'. See |comment.api.call|
---@brief ]]
---@tag comment.commentstring
---@brief [[
---Comment.nvim picks commentstring, either linewise/blockwise, from one of the
---following places
---
--- 1. 'pre_hook'
--- If a string is returned from this function then it will be used for
--- (un)commenting. See |comment.config|
---
--- 2. |comment.ft|
--- Using the commentstring table inside the plugin (using treesitter).
--- Fallback to |commentstring|, if not found.
---
--- 3. |commentstring| - Neovim's native commentstring for the filetype
---
---Although Comment.nvim supports native 'commentstring' but unfortunately it has
---the least priority. The caveat with this approach is that if someone sets the
---`commentstring`, without returning it, from the 'pre_hook' and the current
---filetype also exists in the |comment.ft| then the commenting will be done using
---the string in |comment.ft| instead of using 'commentstring'. To override this
---behavior, you have to manually return the 'commentstring' from 'pre_hook'.
---@brief ]]
---@tag comment.sourcecode
---@brief [[
---Comment.nvim is FOSS provided under MIT license. All the source code is avaiable
---at https://github.com/numToStr/Comment.nvim
---@brief ]]
---@mod comment.usage Usage
---@brief [[
---Before using the plugin, you need to call the `setup()` function to create the
---default mappings. If you want, you can also override the default configuration
---by giving it a partial 'comment.config.Config' object, it will then be merged
---with the default config.
---@brief ]]
local C = {}
---Configures the plugin
---@param config? CommentConfig
---@return CommentConfig
---@param config? CommentConfig User configuration
---@return CommentConfig _ Returns the mutated config
---@see comment.config
---@usage [[
----- Use default configuration
---require('Comment').setup()
---
----- or with custom configuration
---require('Comment').setup({
--- ignore = '^$',
--- toggler = {
--- line = '<leader>cc',
--- block = '<leader>bc',
--- },
--- opleader = {
--- line = '<leader>c',
--- block = '<leader>b',
--- },
---})
---@usage ]]
function C.setup(config)
return require('Comment.api').setup(config)
end

View File

@ -1,4 +1,8 @@
---@mod comment.opfunc Operator-mode
---@mod comment.opfunc Operator-mode API
---@brief [[
---Underlying functions that powers the |comment.api.toggle|, |comment.api.comment|,
---and |comment.api.uncomment| lua API.
---@brief ]]
local U = require('Comment.utils')
local Config = require('Comment.config')
@ -6,31 +10,18 @@ local A = vim.api
local Op = {}
---Vim operator-mode motions.
---Read `:h :map-operator`
---Vim operator-mode motion enum. Read |:map-operator|
---@alias OpMotion
---| 'line' # Vertical motion
---| 'char' # Horizontal motion
---| 'v' # Visual Block motion
---| 'V' # Visual Line motion
---@class CommentCtx Comment context
---@field ctype integer See |comment.utils.ctype|
---@field cmode integer See |comment.utils.cmode|
---@field cmotion integer See |comment.utils.cmotion|
---@field range CommentRange
---@class OpFnParams Operator-mode function parameters
---@field cfg CommentConfig
---@field cmode integer See |comment.utils.cmode|
---@field lines string[] List of lines
---@field rcs string RHS of commentstring
---@field lcs string LHS of commentstring
---@field range CommentRange
---Common operatorfunc callback
---This function contains the core logic for comment/uncomment
---@param motion? OpMotion If nil is given, it'll work on the current line
---@param motion? OpMotion
---If given 'nil', it'll only (un)comment
---the current line
---@param cfg CommentConfig
---@param cmode integer See |comment.utils.cmode|
---@param ctype integer See |comment.utils.ctype|
@ -90,6 +81,50 @@ function Op.opfunc(motion, cfg, cmode, ctype)
U.is_fn(cfg.post_hook, ctx)
end
---Line commenting with count
---@param count integer Value of |v:count|
---@param cfg CommentConfig
---@param cmode integer See |comment.utils.cmode|
---@param ctype integer See |comment.utils.ctype|
function Op.count(count, cfg, cmode, ctype)
local lines, range = U.get_count_lines(count)
---@type CommentCtx
local ctx = {
cmode = cmode,
cmotion = U.cmotion.line,
ctype = ctype,
range = range,
}
local lcs, rcs = U.parse_cstr(cfg, ctx)
---@type OpFnParams
local params = {
cfg = cfg,
cmode = ctx.cmode,
lines = lines,
lcs = lcs,
rcs = rcs,
range = range,
}
if ctype == U.ctype.blockwise then
ctx.cmode = Op.blockwise(params)
else
ctx.cmode = Op.linewise(params)
end
U.is_fn(cfg.post_hook, ctx)
end
---@class OpFnParams Operator-mode function parameters
---@field cfg CommentConfig
---@field cmode integer See |comment.utils.cmode|
---@field lines string[] List of lines
---@field rcs string RHS of commentstring
---@field lcs string LHS of commentstring
---@field range CommentRange
---Line commenting
---@param param OpFnParams
---@return integer _ Returns a calculated comment mode
@ -113,7 +148,7 @@ function Op.linewise(param)
for _, line in ipairs(param.lines) do
-- I wish lua had `continue` statement [sad noises]
if not U.ignore(line, pattern) then
if cmode == U.cmode.uncomment and (not check_comment(line)) then
if cmode == U.cmode.uncomment and param.cmode == U.cmode.toggle and (not check_comment(line)) then
cmode = U.cmode.comment
end
@ -129,6 +164,11 @@ function Op.linewise(param)
end
end
-- If the comment mode given is not toggle than force that mode
if param.cmode ~= U.cmode.toggle then
cmode = param.cmode
end
if cmode == U.cmode.uncomment then
local uncomment = U.uncommenter(param.lcs, param.rcs, padding)
for i, line in ipairs(param.lines) do
@ -187,39 +227,4 @@ function Op.blockwise(param, partial)
return cmode
end
---Line commenting with count i.e vim.v.count
---@param count integer Number of lines
---@param cfg CommentConfig
---@param ctype integer See |comment.utils.ctype|
function Op.count(count, cfg, ctype)
local lines, range = U.get_count_lines(count)
---@type CommentCtx
local ctx = {
cmode = U.cmode.toggle,
cmotion = U.cmotion.line,
ctype = ctype,
range = range,
}
local lcs, rcs = U.parse_cstr(cfg, ctx)
---@type OpFnParams
local params = {
cfg = cfg,
cmode = ctx.cmode,
lines = lines,
lcs = lcs,
rcs = rcs,
range = range,
}
if ctype == U.ctype.blockwise then
ctx.cmode = Op.blockwise(params)
else
ctx.cmode = Op.linewise(params)
end
U.is_fn(cfg.post_hook, ctx)
end
return Op

View File

@ -4,7 +4,11 @@ local A = vim.api
local U = {}
---@alias CommentLines string[] List of lines inside the start and end index
---@class CommentCtx Comment context
---@field ctype integer See |comment.utils.ctype|
---@field cmode integer See |comment.utils.cmode|
---@field cmotion integer See |comment.utils.cmotion|
---@field range CommentRange
---@class CommentRange Range of the selection that needs to be commented
---@field srow integer Starting row
@ -124,7 +128,7 @@ end
---Get lines from the current position to the given count
---@param count integer Probably 'vim.v.count'
---@return CommentLines
---@return string[] _ List of lines
---@return CommentRange
function U.get_count_lines(count)
local srow = unpack(A.nvim_win_get_cursor(0))
@ -136,7 +140,7 @@ end
---Get lines from a NORMAL/VISUAL mode
---@param range CommentRange
---@return CommentLines
---@return string[] _ List of lines
function U.get_lines(range)
-- If start and end is same, then just return the current line
if range.srow == range.erow then

View File

@ -1,6 +1,91 @@
local K = vim.keymap.set
local call = require('Comment.api').call
---@mod comment.keybindings Keybindings
---@brief [[
---Comment.nvim provides default keybinds which is used for (un)comment your code.
---These keybinds are enabled upon calling |commen.usage.setup| and can be
---configured or disabled, if desired.
---
---Basic: ~
---
--- *gc*
--- *gb*
--- *gc[count]{motion}*
--- *gb[count]{motion}*
---
--- Toggle comment on a region using linewise/blockwise comment. In 'NORMAL'
--- mode, it uses 'Operator-Pending' mode to listen for an operator/motion.
--- In 'VISUAL' mode it simply comment the selected region.
---
--- *gcc*
--- *gbc*
--- *[count]gcc*
--- *[count]gbc*
---
--- Toggle comment on the current line using linewise/blockwise comment. If
--- prefixed with a 'v:count' then it will comment over the number of lines
--- corresponding to the {count}. These are only available in 'NORMAL' mode.
---
---
---Extra: ~
---
--- *gco* - Inserts comment below and enters INSERT mode
--- *gcO* - Inserts comment above and enters INSERT mode
--- *gcA* - Inserts comment at the end of line and enters INSERT mode
---@brief ]]
---@mod comment.plugmap Plug Mappings
---@brief [[
---Comment.nvim provides <Plug> mappings for most commonly used actions. These
---can be used to make custom keybindings and are enabled by default. All plug
---mappings has support for dot-repeat except VISUAL mode keybindings. To create
---custom comment function, check out 'comment.api' section.
---
--- *<Plug>(comment_toggle_linewise)*
--- *<Plug>(comment_toggle_blockwise)*
---
--- Toggle comment on a region with linewise/blockwise comment in NORMAL mode.
--- using |Operator-Pending| mode (or |g@|) to get the region to comment.
--- These powers the |gc| and |gb| keybindings.
---
--- *<Plug>(comment_toggle_linewise_current)*
--- *<Plug>(comment_toggle_blockwise_current)*
---
--- Toggle comment on the current line with linewise/blockwise comment in
--- NORMAL mode. These powers the |gcc| and 'gbc' keybindings.
---
--- *<Plug>(comment_toggle_linewise_count)*
--- *<Plug>(comment_toggle_blockwise_count)*
---
--- Toggle comment on a region using 'v:count' with linewise/blockwise comment
--- in NORMAL mode. These powers the |[count]gcc| and |[count]gbc| keybindings.
---
--- *<Plug>(comment_toggle_linewise_visual)*
--- *<Plug>(comment_toggle_blockwise_visual)*
---
--- Toggle comment on the selected region with linewise/blockwise comment in
--- NORMAL mode. These powers the |{visual}gc| and |{visual}gb| keybindings.
---
---Usage: ~
---
--->
--- -- Toggle current line or with count
--- vim.keymap.set('n', 'gcc', function()
--- return vim.v.count == 0
--- and '<Plug>(comment_toggle_linewise_current)'
--- or '<Plug>(comment_toggle_linewise_count)'
--- end, { expr = true })
---
--- -- Toggle in Op-pending mode
--- vim.keymap.set('n', 'gc', '<Plug>(comment_toggle_linewise)')
---
--- -- Toggle in VISUAL mode
--- vim.keymap.set('x', 'gc', '<Plug>(comment_toggle_linewise_visual)')
---<
---@brief ]]
---@export plugs
-- Operator-Pending mappings
K(
'n',