Skip to content

Commit 89e860a

Browse files
authored
feat: auto calculate commentstring (#62)
Adding 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. See #62 (comment) For more advance use cases you should use https://github.com/JoosepAlviste/nvim-ts-context-commentstring. See hooks section.
1 parent 620445b commit 89e860a

File tree

6 files changed

+185
-124
lines changed

6 files changed

+185
-124
lines changed

README.md

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55

66
### ✨ Features
77

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

1919
### 🚀 Installation
2020

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

2323
```lua
2424
use {
@@ -29,7 +29,7 @@ use {
2929
}
3030
```
3131

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

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

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

47-
- Lua
47+
- Lua
4848

4949
```lua
5050
require('Comment').setup()
5151
```
5252

53-
- VimL
53+
- VimL
5454

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

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

141-
- NORMAL mode
141+
- NORMAL mode
142142

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

153153
> NOTE: Dot repeat is not supported with `[count]gcc`
154154
155-
- VISUAL mode
155+
- VISUAL mode
156156

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

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

166-
- NORMAL mode
166+
- NORMAL mode
167167

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

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

178-
- NORMAL mode
178+
- NORMAL mode
179179

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

189-
- VISUAL mode
189+
- VISUAL mode
190190

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

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

237+
<a id="treesitter"></a>
238+
239+
### 🌳 Treesitter
240+
241+
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.
242+
243+
1. No `jsx/tsx` support. Its implementation was quite complicated.
244+
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)
245+
246+
For more advance use cases you should use [nvim-ts-context-commentstring](https://github.com/JoosepAlviste/nvim-ts-context-commentstring). See [hooks](#hooks) section.
247+
237248
<a id="hooks"></a>
238249

239250
### 🎣 Hooks
240251

241252
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).
242253

243-
- `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.
254+
- `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.
244255

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

288-
- `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`.
299+
- `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`.
289300

290301
> 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
291302
@@ -316,7 +327,7 @@ You can use `ignore` to ignore certain lines during comment/uncomment. It can ta
316327

317328
> NOTE: Ignore only works when with linewise comment. This is by design. As ignoring lines in block comments doesn't make that much sense.
318329
319-
- With `string`
330+
- With `string`
320331

321332
```lua
322333
-- ignores empty lines
@@ -329,7 +340,7 @@ ignore = '^(%s*)local'
329340
ignore = '^const(.*)=(%s?)%((.*)%)(%s?)=>'
330341
```
331342

332-
- With `function`
343+
- With `function`
333344

334345
```lua
335346
{
@@ -391,11 +402,11 @@ ft({'toml', 'graphql'}, '#%s')
391402

392403
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.
393404

394-
- [`pre_hook`](#hooks) - If a string is returned from this method then it will be used for commenting.
405+
- [`pre_hook`](#hooks) - If a string is returned from this method then it will be used for commenting.
395406

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

398-
- `commentstring` - Neovim's native commentstring for the filetype
409+
- `commentstring` - Neovim's native commentstring for the filetype
399410

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

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

434446
### 💐 Credits
435447

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

440452
### 🚗 Roadmap
441453

442-
- Live upto the expectation of `tcomment`
443-
- Basic INSERT mode mappings
444-
- Doc comment i.e `/**%s*/` (js), `///%s` (rust)
445-
446-
- Inbuilt context commentstring using treesitter
447-
448-
```lua
449-
{
450-
pre_hook = function()
451-
return require('Comment.ts').commentstring()
452-
end
453-
}
454-
```
455-
456-
- Header comment
454+
- Doc comment i.e `/**%s*/` (js), `///%s` (rust)
455+
- Header comment
457456

458457
```lua
459458
----------------------

lua/Comment/comment.lua

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,23 @@ local C = {
77
config = nil,
88
}
99

10-
---Comment context
11-
---@class Ctx
12-
---@field ctype CType
13-
---@field cmode CMode
14-
---@field cmotion CMotion
15-
1610
---Comments the current line
1711
function C.comment()
1812
local line = A.nvim_get_current_line()
1913

2014
local pattern = U.get_pattern(C.config.ignore)
2115
if not U.ignore(line, pattern) then
16+
local srow, scol = unpack(A.nvim_win_get_cursor(0))
2217
---@type Ctx
2318
local ctx = {
2419
cmode = U.cmode.comment,
2520
cmotion = U.cmotion.line,
2621
ctype = U.ctype.line,
22+
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
2723
}
24+
local lcs, rcs = U.parse_cstr(C.config, ctx)
2825

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

4036
local pattern = U.get_pattern(C.config.ignore)
4137
if not U.ignore(line, pattern) then
38+
local srow, scol = unpack(A.nvim_win_get_cursor(0))
4239
---@type Ctx
4340
local ctx = {
4441
cmode = U.cmode.uncomment,
4542
cmotion = U.cmotion.line,
4643
ctype = U.ctype.line,
44+
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
4745
}
48-
4946
local lcs, rcs = U.parse_cstr(C.config, ctx)
47+
5048
local _, pp = U.get_padding(C.config.padding)
5149
local lcs_esc, rcs_esc = U.escape(lcs), U.escape(rcs)
5250

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

6563
local pattern = U.get_pattern(C.config.ignore)
6664
if not U.ignore(line, pattern) then
65+
local srow, scol = unpack(A.nvim_win_get_cursor(0))
6766
---@type Ctx
6867
local ctx = {
6968
cmode = U.cmode.toggle,
7069
cmotion = U.cmotion.line,
7170
ctype = U.ctype.line,
71+
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
7272
}
73-
7473
local lcs, rcs = U.parse_cstr(C.config, ctx)
74+
7575
local lcs_esc, rcs_esc = U.escape(lcs), U.escape(rcs)
7676
local padding, pp = U.get_padding(C.config.padding)
7777
local is_cmt = U.is_commented(lcs_esc, rcs_esc, pp)(line)

lua/Comment/extra.lua

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,31 @@ local E = {}
77
---@param ctype CType
88
---@param cfg Config
99
local function ins_on_line(count, ctype, cfg)
10+
local row, col = unpack(A.nvim_win_get_cursor(0))
11+
1012
---@type Ctx
1113
local ctx = {
1214
cmode = U.cmode.comment,
1315
cmotion = U.cmotion.line,
1416
ctype = ctype,
17+
range = { srow = row, scol = col, erow = row, ecol = col },
1518
}
19+
local lcs, rcs = U.parse_cstr(cfg, ctx)
1620

17-
local pos = A.nvim_win_get_cursor(0)
18-
local srow, scol = pos[1] + count, pos[2]
1921
local line = A.nvim_get_current_line()
2022
local indent = U.grab_indent(line)
21-
local lcs, rcs = U.parse_cstr(cfg, ctx)
2223
local padding = U.get_padding(cfg.padding)
2324

2425
-- We need RHS of cstr, if we are doing block comments or if RHS exists
2526
-- because even in line comment RHS do exists for some filetypes like jsx_element, ocaml
2627
local if_rcs = (ctype == U.ctype.block or rcs) and padding .. rcs or ''
2728

29+
local srow = row + count
2830
local ll = indent .. lcs .. padding
2931
A.nvim_buf_set_lines(0, srow, srow, false, { ll .. if_rcs })
3032
local erow, ecol = srow + 1, #ll - 1
3133
U.move_n_insert(erow, ecol)
32-
U.is_fn(cfg.post_hook, ctx, srow, erow, scol, ecol)
34+
U.is_fn(cfg.post_hook, ctx, srow, erow, col, ecol)
3335
end
3436

3537
---Add a comment below the current line and goes to INSERT mode
@@ -50,16 +52,18 @@ end
5052
---@param ctype CType
5153
---@param cfg Config
5254
function E.norm_A(ctype, cfg)
55+
local srow, scol = unpack(A.nvim_win_get_cursor(0))
56+
5357
---@type Ctx
5458
local ctx = {
5559
cmode = U.cmode.comment,
5660
cmotion = U.cmotion.line,
5761
ctype = ctype,
62+
range = { srow = srow, scol = scol, erow = srow, ecol = scol },
5863
}
64+
local lcs, rcs = U.parse_cstr(cfg, ctx)
5965

60-
local pos = A.nvim_win_get_cursor(0)
6166
local line = A.nvim_get_current_line()
62-
local lcs, rcs = U.parse_cstr(cfg, ctx)
6367
local padding = U.get_padding(cfg.padding)
6468

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

75-
local srow, scol = pos[1], pos[2]
7679
local erow, ecol = srow - 1, #ll - 1
7780
A.nvim_buf_set_lines(0, erow, srow, false, { ll .. if_rcs })
7881
U.move_n_insert(srow, ecol)

0 commit comments

Comments
 (0)