patch 9.1.1229: the comment plugin can be improved

Problem:  the comment plugin can be improved
Solution: add comment text objects "ic" and "ac"
          (Maxim Kim)

closes: #16938

Signed-off-by: Maxim Kim <habamax@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Maxim Kim
2025-03-21 18:02:56 +01:00
committed by Christian Brabandt
parent 51a06ecee0
commit 9712a2534f
6 changed files with 451 additions and 8 deletions

View File

@ -1,7 +1,7 @@
vim9script
# Maintainer: Maxim Kim <habamax@gmail.com>
# Last Update: 2024 Oct 05
# Last Update: 2025 Mar 21
#
# Toggle comments
# Usage:
@ -76,3 +76,88 @@ export def Toggle(...args: list<string>): string
noautocmd keepjumps setline(lnum1, lines)
return ''
enddef
# Comment text object
# Usage:
# import autoload 'dist/comment.vim'
# onoremap <silent>ic <scriptcmd>comment.ObjComment(v:true)<CR>
# onoremap <silent>ac <scriptcmd>comment.ObjComment(v:false)<CR>
# xnoremap <silent>ic <esc><scriptcmd>comment.ObjComment(v:true)<CR>
# xnoremap <silent>ac <esc><scriptcmd>comment.ObjComment(v:false)<CR>
export def ObjComment(inner: bool)
def IsComment(): bool
var stx = map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')->join()
return stx =~? 'Comment'
enddef
# requires syntax support
if !exists("g:syntax_on")
return
endif
var pos_init = getcurpos()
# If not in comment, search next one,
if !IsComment()
if search('\v\k+', 'W', line(".") + 100, 100, () => !IsComment()) <= 0
return
endif
endif
# Search for the beginning of the comment block
if IsComment()
if search('\v%(\S+)|$', 'bW', 0, 200, IsComment) > 0
search('\v%(\S)|$', 'W', 0, 200, () => !IsComment())
else
cursor(1, 1)
search('\v\S+', 'cW', 0, 200)
endif
endif
var pos_start = getcurpos()
if !inner
var col = pos_start[2]
var prefix = getline(pos_start[1])[ : col - 2]
while col > 0 && prefix[col - 2] =~ '\s'
col -= 1
endwhile
pos_start[2] = col
endif
# Search for the comment end.
if pos_init[1] > pos_start[1]
cursor(pos_init[1], pos_init[2])
endif
if search('\v%(\S+)|$', 'W', 0, 200, IsComment) > 0
search('\S', 'beW', 0, 200, () => !IsComment())
else
if search('\%$', 'W', 0, 200) > 0
search('\ze\S', 'beW', 0, 200, () => !IsComment())
endif
endif
var pos_end = getcurpos()
if !inner
var spaces = matchstr(getline(pos_end[1]), '\%>.c\s*')
pos_end[2] += spaces->len()
if getline(pos_end[1])[pos_end[2] : ] =~ '^\s*$'
&& (pos_start[2] == 1 || getline(pos_start[1])[ : pos_start[2]] =~ '^\s*$')
if search('\v\s*\_$(\s*\n)+', 'eW', 0, 200) > 0
pos_end = getcurpos()
endif
endif
endif
if (pos_end[2] == (getline(pos_end[1])->len() ?? 1)) && pos_start[2] == 1
cursor(pos_end[1], 1)
normal! V
cursor(pos_start[1], 1)
else
cursor(pos_end[1], pos_end[2])
normal! v
cursor(pos_start[1], pos_start[2])
endif
enddef

View File

@ -1,4 +1,4 @@
*comment.txt* For Vim version 9.1. Last change: 2024 Oct 01
*comment.txt* For Vim version 9.1. Last change: 2025 Mar 21
VIM REFERENCE MANUAL
@ -32,11 +32,20 @@ back to `gcc` otherwise, add the following mapping to your vimrc: >
Note: using `gC` may not always result in valid comment markers depending on
the language used.
Additionally, the plugin defines a comment text-object which requires syntax
highlighting to be enabled.
*v_ac* *ac*
ac "a comment", select current or next comment.
Leading and trailing white space is included.
Trailing newlines are included too.
*v_ic* *ic*
ic "inner comment", select current or next comment.
This plugin uses the buffer-local 'commentstring' option value to add or remove
comment markers to the selected lines. Whether it will comment or un-comment
depends on the first line of the range of lines to act upon. When it matches
a comment marker, the line will be un-commented, if it doesn't, the line will
be commented out. Blank and empty lines are ignored.
depends on the range of lines to act upon. When all of the lines in range
have comment markers, all lines will be un-commented, if it doesn't, the lines
will be commented out. Blank and empty lines are ignored.
The value of 'commentstring' is the same for the entire buffer and determined
by its filetype (|filetypes|). To adapt it within the buffer for embedded

View File

@ -1,6 +1,10 @@
ac comment.txt /*ac*
b:comment_first_col comment.txt /*b:comment_first_col*
comment.txt comment.txt /*comment.txt*
g:comment_first_col comment.txt /*g:comment_first_col*
gcc comment.txt /*gcc*
ic comment.txt /*ic*
o_gc comment.txt /*o_gc*
v_ac comment.txt /*v_ac*
v_gc comment.txt /*v_gc*
v_ic comment.txt /*v_ic*

View File

@ -1,9 +1,15 @@
vim9script
# Maintainer: Maxim Kim <habamax@gmail.com>
# Last Update: 2024-04-26
# Last Update: 2025 Mar 21
import autoload 'comment.vim'
nnoremap <silent> <expr> gc comment.Toggle()
xnoremap <silent> <expr> gc comment.Toggle()
nnoremap <silent> <expr> gcc comment.Toggle() .. '_'
onoremap <silent>ic <scriptcmd>comment.ObjComment(v:true)<CR>
onoremap <silent>ac <scriptcmd>comment.ObjComment(v:false)<CR>
xnoremap <silent>ic <esc><scriptcmd>comment.ObjComment(v:true)<CR>
xnoremap <silent>ac <esc><scriptcmd>comment.ObjComment(v:false)<CR>