Skip to content

feat: Auto calculate commentstring #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Nov 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 43 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@

### ✨ Features

- Supports `commentstring`. [Read more](#commentstring)
- Prefers single-line/linewise comments
- Supports line (`//`) and block (`/* */`) comments
- Dot (`.`) repeat support for `gcc`, `gbc` and friends
- Count support (`[count]gcc` only)
- Left-right (`gcw` `gc$`) and Up-Down (`gc2j` `gc4k`) motions
- Use with text-objects (`gci{` `gbat`)
- Supports pre and post hooks
- Custom language/filetype support
- Ignore certain lines, powered by Lua regex
- Supports treesitter. [Read more](#treesitter)
- Supports `commentstring`. [Read more](#commentstring)
- Prefers single-line/linewise comments
- Supports line (`//`) and block (`/* */`) comments
- Dot (`.`) repeat support for `gcc`, `gbc` and friends
- Count support (`[count]gcc` only)
- Left-right (`gcw` `gc$`) and Up-Down (`gc2j` `gc4k`) motions
- Use with text-objects (`gci{` `gbat`)
- Supports pre and post hooks
- Ignore certain lines, powered by Lua regex

### 🚀 Installation

- With [packer.nvim](https://github.com/wbthomason/packer.nvim)
- With [packer.nvim](https://github.com/wbthomason/packer.nvim)

```lua
use {
Expand All @@ -29,7 +29,7 @@ use {
}
```

- With [vim-plug](https://github.com/junegunn/vim-plug)
- With [vim-plug](https://github.com/junegunn/vim-plug)

```vim
Plug 'numToStr/Comment.nvim'
Expand All @@ -44,13 +44,13 @@ lua require('Comment').setup()

First you need to call the `setup()` method to create the default mappings.

- Lua
- Lua

```lua
require('Comment').setup()
```

- VimL
- VimL

```vim
lua << EOF
Expand Down Expand Up @@ -138,7 +138,7 @@ When you call [`setup()`](#setup) method, `Comment.nvim` sets up some basic mapp

These mappings are enabled by default. (config: `mappings.basic`)

- NORMAL mode
- NORMAL mode

```help
`gcc` - Toggles the current line using linewise comment
Expand All @@ -152,7 +152,7 @@ These mappings are enabled by default. (config: `mappings.basic`)

> NOTE: Dot repeat is not supported with `[count]gcc`

- VISUAL mode
- VISUAL mode

```help
`gc` - Toggles the region using linewise comment
Expand All @@ -163,7 +163,7 @@ These mappings are enabled by default. (config: `mappings.basic`)

These mappings are enabled by default. (config: `mappings.extra`)

- NORMAL mode
- NORMAL mode

```help
`gco` - Insert comment to the next line and enters INSERT mode
Expand All @@ -175,7 +175,7 @@ These mappings are enabled by default. (config: `mappings.extra`)

These mappings are disabled by default. (config: `mappings.extended`)

- NORMAL mode
- NORMAL mode

```help
`g>[count]{motion}` - (Op-pending) Comments the region using linewise comment
Expand All @@ -186,7 +186,7 @@ These mappings are disabled by default. (config: `mappings.extended`)
`g<b`- Uncomments the current line using blockwise comment
```

- VISUAL mode
- VISUAL mode

```help
`g>` - Comments the region using single line
Expand Down Expand Up @@ -234,13 +234,24 @@ require('Comment').toggle()

Read [API](./API.md) for more crazy stuff.

<a id="treesitter"></a>

### 🌳 Treesitter

This plugin also has the basic support of treesitter for calculating `commentstring` which works most of the time and might be all that someone needs. But due to the nature of the parsed tree, this implementation has some known limitations.

1. No `jsx/tsx` support. Its implementation was quite complicated.
2. Invalid comment on the region where one language ends and the other starts. [Read more](https://github.com/numToStr/Comment.nvim/pull/62#issuecomment-972790418)

For more advance use cases you should use [nvim-ts-context-commentstring](https://github.com/JoosepAlviste/nvim-ts-context-commentstring). See [hooks](#hooks) section.

<a id="hooks"></a>

### 🎣 Hooks

There are two hook methods i.e `pre_hook` and `post_hook` which are called before comment and after comment respectively. Both should be provided during [`setup()`](#setup).

- `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` - 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.

```lua
-- NOTE: The example below is a proper integration and it is RECOMMENDED.
Expand Down Expand Up @@ -285,7 +296,7 @@ Also, you can set the `commentstring` from here but [**i won't recommend it**](#
}
```

- `post_hook` - This method is called after commenting is done. It receives the same 1) [`ctx`](#comment-context), the lines range 2) `start_row` 3) `end_row` 4) `start_col` 5) `end_col`.
- `post_hook` - This method is called after commenting is done. It receives the same 1) [`ctx`](#comment-context), the lines range 2) `start_row` 3) `end_row` 4) `start_col` 5) `end_col`.

> NOTE: If [methods](#methods) are used, then `post_hook` will receives only two arguments 1) [`ctx`](#comment-context) and 2) `-1` indicating the current line

Expand Down Expand Up @@ -316,7 +327,7 @@ You can use `ignore` to ignore certain lines during comment/uncomment. It can ta

> NOTE: Ignore only works when with linewise comment. This is by design. As ignoring lines in block comments doesn't make that much sense.

- With `string`
- With `string`

```lua
-- ignores empty lines
Expand All @@ -329,7 +340,7 @@ ignore = '^(%s*)local'
ignore = '^const(.*)=(%s?)%((.*)%)(%s?)=>'
```

- With `function`
- With `function`

```lua
{
Expand Down Expand Up @@ -391,11 +402,11 @@ ft({'toml', 'graphql'}, '#%s')

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.
- [`pre_hook`](#hooks) - If a string is returned from this method then it will be used for commenting.

- [`ft_table`](#languages) - If the current filetype is found in the table, then the string there will be used.
- [`ft_table`](#languages) - If the current filetype is found in the table, then the string there will be used.

- `commentstring` - Neovim's native commentstring for the filetype
- `commentstring` - Neovim's native commentstring for the filetype

<a id="commentstring-caveat"></a>

Expand All @@ -412,6 +423,7 @@ The following object is provided as an argument to `pre_hook` and `post_hook` fu
```lua
---Comment context
---@class Ctx
---@field lang string: The name of the language where the cursor is
---@field ctype CType
---@field cmode CMode
---@field cmotion CMotion
Expand All @@ -433,27 +445,14 @@ There are multiple ways to contribute reporting/fixing bugs, feature requests. Y

### 💐 Credits

- [tcomment]() - To be with me forever and motivated me to write this.
- [nvim-comment](https://github.com/terrortylor/nvim-comment) - Little and less powerful cousin. Also I took some code from it.
- [kommentary](https://github.com/b3nj5m1n/kommentary) - Nicely done plugin but lacks some features. But it helped me to design this plugin.
- [tcomment]() - To be with me forever and motivated me to write this.
- [nvim-comment](https://github.com/terrortylor/nvim-comment) - Little and less powerful cousin. Also I took some code from it.
- [kommentary](https://github.com/b3nj5m1n/kommentary) - Nicely done plugin but lacks some features. But it helped me to design this plugin.

### 🚗 Roadmap

- Live upto the expectation of `tcomment`
- Basic INSERT mode mappings
- Doc comment i.e `/**%s*/` (js), `///%s` (rust)

- Inbuilt context commentstring using treesitter

```lua
{
pre_hook = function()
return require('Comment.ts').commentstring()
end
}
```

- Header comment
- Doc comment i.e `/**%s*/` (js), `///%s` (rust)
- Header comment

```lua
----------------------
Expand Down
18 changes: 9 additions & 9 deletions lua/Comment/comment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,23 @@ local C = {
config = nil,
}

---Comment context
---@class Ctx
---@field ctype CType
---@field cmode CMode
---@field cmotion CMotion

---Comments the current line
function C.comment()
local line = A.nvim_get_current_line()

local pattern = U.get_pattern(C.config.ignore)
if not U.ignore(line, pattern) then
local srow, scol = unpack(A.nvim_win_get_cursor(0))
---@type Ctx
local ctx = {
cmode = U.cmode.comment,
cmotion = U.cmotion.line,
ctype = U.ctype.line,
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
}
local lcs, rcs = U.parse_cstr(C.config, ctx)

local padding, _ = U.get_padding(C.config.padding)
local lcs, rcs = U.parse_cstr(C.config, ctx)
A.nvim_set_current_line(U.comment_str(line, lcs, rcs, padding))
U.is_fn(C.config.post_hook, ctx, -1)
end
Expand All @@ -39,14 +35,16 @@ function C.uncomment()

local pattern = U.get_pattern(C.config.ignore)
if not U.ignore(line, pattern) then
local srow, scol = unpack(A.nvim_win_get_cursor(0))
---@type Ctx
local ctx = {
cmode = U.cmode.uncomment,
cmotion = U.cmotion.line,
ctype = U.ctype.line,
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
}

local lcs, rcs = U.parse_cstr(C.config, ctx)

local _, pp = U.get_padding(C.config.padding)
local lcs_esc, rcs_esc = U.escape(lcs), U.escape(rcs)

Expand All @@ -64,14 +62,16 @@ function C.toggle()

local pattern = U.get_pattern(C.config.ignore)
if not U.ignore(line, pattern) then
local srow, scol = unpack(A.nvim_win_get_cursor(0))
---@type Ctx
local ctx = {
cmode = U.cmode.toggle,
cmotion = U.cmotion.line,
ctype = U.ctype.line,
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
}

local lcs, rcs = U.parse_cstr(C.config, ctx)

local lcs_esc, rcs_esc = U.escape(lcs), U.escape(rcs)
local padding, pp = U.get_padding(C.config.padding)
local is_cmt = U.is_commented(lcs_esc, rcs_esc, pp)(line)
Expand Down
17 changes: 10 additions & 7 deletions lua/Comment/extra.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,31 @@ local E = {}
---@param ctype CType
---@param cfg Config
local function ins_on_line(count, ctype, cfg)
local row, col = unpack(A.nvim_win_get_cursor(0))

---@type Ctx
local ctx = {
cmode = U.cmode.comment,
cmotion = U.cmotion.line,
ctype = ctype,
range = { srow = row, scol = col, erow = row, ecol = col },
}
local lcs, rcs = U.parse_cstr(cfg, ctx)

local pos = A.nvim_win_get_cursor(0)
local srow, scol = pos[1] + count, pos[2]
local line = A.nvim_get_current_line()
local indent = U.grab_indent(line)
local lcs, rcs = U.parse_cstr(cfg, ctx)
local padding = U.get_padding(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
local if_rcs = (ctype == U.ctype.block or rcs) and padding .. rcs or ''

local srow = row + count
local ll = indent .. lcs .. padding
A.nvim_buf_set_lines(0, srow, srow, false, { ll .. if_rcs })
local erow, ecol = srow + 1, #ll - 1
U.move_n_insert(erow, ecol)
U.is_fn(cfg.post_hook, ctx, srow, erow, scol, ecol)
U.is_fn(cfg.post_hook, ctx, srow, erow, col, ecol)
end

---Add a comment below the current line and goes to INSERT mode
Expand All @@ -50,16 +52,18 @@ end
---@param ctype CType
---@param cfg Config
function E.norm_A(ctype, cfg)
local srow, scol = unpack(A.nvim_win_get_cursor(0))

---@type Ctx
local ctx = {
cmode = U.cmode.comment,
cmotion = U.cmotion.line,
ctype = ctype,
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
}
local lcs, rcs = U.parse_cstr(cfg, ctx)

local pos = A.nvim_win_get_cursor(0)
local line = A.nvim_get_current_line()
local lcs, rcs = U.parse_cstr(cfg, ctx)
local padding = U.get_padding(cfg.padding)

-- NOTE:
Expand All @@ -72,7 +76,6 @@ function E.norm_A(ctype, cfg)
-- because even in line comment RHS do exists for some filetypes like jsx_element, ocaml
local if_rcs = (ctype == U.ctype.block or rcs) and padding .. rcs or ''

local srow, scol = pos[1], pos[2]
local erow, ecol = srow - 1, #ll - 1
A.nvim_buf_set_lines(0, erow, srow, false, { ll .. if_rcs })
U.move_n_insert(srow, ecol)
Expand Down
Loading