Skip to content

Commit bf4fc06

Browse files
committed
Merge pull request preservim#161 from ElPiloto/master
Add ability to create a line of comment characters
2 parents 2b3714b + 85a020f commit bf4fc06

File tree

2 files changed

+156
-54
lines changed

2 files changed

+156
-54
lines changed

doc/NERD_commenter.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ CONTENTS *NERDCommenterContents*
2828
3.2.11 Use alternate delims map...|NERDComAltDelim|
2929
3.2.12 Comment aligned maps.......|NERDComAlignedComment|
3030
3.2.13 Uncomment line map.........|NERDComUncommentLine|
31+
3.2.14 Comment horiz. line........|NERDComCommentHorizontalRule|
3132
3.4 Sexy Comments.....................|NERDComSexyComments|
3233
3.5 The NERDComment function..........|NERDComNERDComment|
3334
4.Options.................................|NERDComOptions|
@@ -140,6 +141,9 @@ left side (|<Leader>|cl) or both sides (|<Leader>|cb).
140141
Uncomments the selected line(s).
141142

142143

144+
[count]|<Leader|c_ |NERDComCommentHR|
145+
Will create a line or horizontal rule out of comment characters.
146+
143147
With the optional repeat.vim plugin (vimscript #2136), the mappings can also
144148
be repeated via |.|
145149

@@ -354,7 +358,21 @@ lines were selected in visual-line mode.
354358
Related options:
355359
|'NERDRemoveAltComs'|
356360
|'NERDRemoveExtraSpaces'|
361+
------------------------------------------------------------------------------
362+
3.2.14 Make horiz. line of comments *NERDComCommentHorizontalRule*
363+
364+
Default mappings: [count]|<Leader>|c_
365+
Mapped to: <plug>NERDCommenterCommentHorizontalRule
366+
Applicable modes: normal visual-line.
367+
368+
Will create a line or horizontal rule out of comment characters. The width of
369+
the rule is determined as follows:
370+
1. If NERDNumCommentCharsHR is defined and greater than 0, use that value.
371+
2. If &wrap is set and &textwidth is greater than 0, use that value.
372+
3. Default to 72
357373

374+
Related options:
375+
|'NERDNumCommentCharsHR'|
358376
------------------------------------------------------------------------------
359377
3.3 Sexy Comments *NERDComSexyComments*
360378
These are comments that use one set of multipart comment delimiters as well as
@@ -436,6 +454,8 @@ then the script would do a sexy comment on the last visual selection.
436454
|'NERDDefaultAlign'| Specifies the default alignment to use,
437455
one of 'none', 'left', 'start', or
438456
'both'.
457+
|'NERDNumCommentCharsHR'| Specifies how many comment characters to
458+
use to create a horizontal rule.
439459

440460
------------------------------------------------------------------------------
441461
4.3 Options details *NERDComOptionsDetails*
@@ -732,6 +752,18 @@ you hit |<Leader>|cc on a line that is already commented it will be commented
732752
again.
733753

734754
------------------------------------------------------------------------------
755+
*'NERDNumCommentCharsHR'*
756+
Values: Any number.
757+
Default 0.
758+
759+
When this option is something besides 0, it specifies how many comment
760+
characters we'll use for creating a horizontal rule out of comments i.e. when
761+
we use the |<Leader>|c_. If it is zero, the CommentHorizontalRule command
762+
will determine the number of characters to use by using the &textwidth option
763+
if it is greater than 0 and &wrap is set. Otherwise, it defaults to 72.
764+
765+
------------------------------------------------------------------------------
766+
735767
3.3 Default delimiter customisation *NERDComDefaultDelims*
736768

737769
If you want the NERD commenter to use the alternative delimiters for a

plugin/NERD_commenter.vim

Lines changed: 124 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ call s:InitVariable("g:NERDRemoveExtraSpaces", 0)
6464
call s:InitVariable("g:NERDRPlace", "<]")
6565
call s:InitVariable("g:NERDSpaceDelims", 0)
6666
call s:InitVariable("g:NERDDefaultAlign", "none")
67+
call s:InitVariable("g:NERDNumCommentCharsHR", 0)
6768

6869
let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\"
6970

@@ -725,6 +726,35 @@ function s:CommentBlock(top, bottom, lSide, rSide, forceNested )
725726
endif
726727
endfunction
727728

729+
" Function: s:CommentHorizontalRule(firstLine, lastLine) {{{2
730+
" This function creates a "horizontal rule" out of comment characters for each
731+
" line specified
732+
"
733+
" Args:
734+
" -firstLine/lastLine: the top and bottom lines to comment
735+
function s:CommentHorizontalRule(firstLine, lastLine)
736+
let currentLine = a:firstLine
737+
let lastLine = a:lastLine
738+
739+
while currentLine <= lastLine
740+
let theLine = getline(currentLine)
741+
742+
" if this is a blank line, let's just insert the comment HR
743+
if theLine =~ '\v^\s*$'
744+
call setline(currentLine, s:GetCommentCharsHR())
745+
" if the line isn't blank, we insert our comment HR, and then add the existing line just below this one and increment our currentLine AND our lastLine counter by one so that we don't end up repeating lines
746+
else
747+
call setline(currentLine, s:GetCommentCharsHR())
748+
call append(currentLine, theLine)
749+
let currentLine = currentLine + 1
750+
let lastLine = lastLine + 1
751+
endif
752+
753+
let currentLine = currentLine + 1
754+
endwhile
755+
756+
endfunction
757+
728758
" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2
729759
" This function comments a range of lines.
730760
"
@@ -1207,6 +1237,8 @@ function! NERDComment(mode, type) range
12071237
normal! yy
12081238
endif
12091239
execute firstLine .','. lastLine .'call NERDComment("'. a:mode .'", "Comment")'
1240+
elseif a:type ==? 'CommentHorizontalRule'
1241+
call s:CommentHorizontalRule(firstLine, lastLine)
12101242
endif
12111243

12121244
call s:RecoverStateAfterLineComment(state)
@@ -1540,60 +1572,69 @@ function s:UncommentLineNormal(line)
15401572
let indxRight = s:FindDelimiterIndex(s:Right(), line)
15411573
let indxRightAlt = s:FindDelimiterIndex(s:Right({'alt': 1}), line)
15421574

1543-
"get the comment status on the line so we know how it is commented
1544-
let lineCommentStatus = s:IsCommentedOutermost(s:Left(), s:Right(), s:Left({'alt': 1}), s:Right({'alt': 1}), line)
1545-
1546-
"it is commented with s:Left() and s:Right() so remove these delimiters
1547-
if lineCommentStatus == 1
1548-
let line = s:RemoveDelimiters(s:Left(), s:Right(), line)
1549-
1550-
"it is commented with s:Left({'alt': 1}) and s:Right({'alt': 1}) so remove these delimiters
1551-
elseif lineCommentStatus == 2 && g:NERDRemoveAltComs
1552-
let line = s:RemoveDelimiters(s:Left({'alt': 1}), s:Right({'alt': 1}), line)
1553-
1554-
"it is not properly commented with any delimiters so we check if it has
1555-
"any random left or right delimiters on it and remove the outermost ones
1556-
else
1557-
"remove the outer most left comment delimiter
1558-
if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1)
1559-
let line = s:RemoveDelimiters(s:Left(), '', line)
1560-
elseif indxLeftAlt != -1 && g:NERDRemoveAltComs
1561-
let line = s:RemoveDelimiters(s:Left({'alt': 1}), '', line)
1562-
endif
1563-
1564-
"remove the outer most right comment delimiter
1565-
if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1)
1566-
let line = s:RemoveDelimiters('', s:Right(), line)
1567-
elseif indxRightAlt != -1 && g:NERDRemoveAltComs
1568-
let line = s:RemoveDelimiters('', s:Right({'alt': 1}), line)
1569-
endif
1570-
endif
1571-
1572-
1573-
let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line)
1574-
let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)
1575-
1576-
let right = s:Right()
1577-
let left = s:Left()
1578-
if !s:Multipart()
1579-
let right = s:Right({'alt': 1})
1580-
let left = s:Left({'alt': 1})
1581-
endif
1582-
1583-
1584-
"if there are place-holders on the line then we check to see if they are
1585-
"the outermost delimiters on the line. If so then we replace them with
1586-
"real delimiters
1587-
if indxLeftPlace != -1
1588-
if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
1589-
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
1590-
endif
1591-
elseif indxRightPlace != -1
1592-
if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
1593-
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
1594-
endif
1595-
1596-
endif
1575+
" here is an easy scenario for toggling horizontal rules: if the line
1576+
" consists solely of repetitions of s:Left(), then just set the entire
1577+
" line to be blank
1578+
" our comment string
1579+
if line =~ '\V\^\s\*\('. escape(s:Left(),'\/') . '\)\+\s\*\$'
1580+
let line = ''
1581+
else
1582+
"get the comment status on the line so we know how it is commented
1583+
let lineCommentStatus = s:IsCommentedOutermost(s:Left(), s:Right(), s:Left({'alt': 1}), s:Right({'alt': 1}), line)
1584+
1585+
"it is commented with s:Left() and s:Right() so remove these delimiters
1586+
if lineCommentStatus == 1
1587+
let line = s:RemoveDelimiters(s:Left(), s:Right(), line)
1588+
1589+
"it is commented with s:Left({'alt': 1}) and s:Right({'alt': 1}) so remove these delimiters
1590+
elseif lineCommentStatus == 2 && g:NERDRemoveAltComs
1591+
let line = s:RemoveDelimiters(s:Left({'alt': 1}), s:Right({'alt': 1}), line)
1592+
1593+
"it is not properly commented with any delimiters so we check if it has
1594+
"any random left or right delimiters on it and remove the outermost ones
1595+
else
1596+
"remove the outer most left comment delimiter
1597+
if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1)
1598+
let line = s:RemoveDelimiters(s:Left(), '', line)
1599+
elseif indxLeftAlt != -1 && g:NERDRemoveAltComs
1600+
let line = s:RemoveDelimiters(s:Left({'alt': 1}), '', line)
1601+
endif
1602+
1603+
"remove the outer most right comment delimiter
1604+
if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1)
1605+
let line = s:RemoveDelimiters('', s:Right(), line)
1606+
elseif indxRightAlt != -1 && g:NERDRemoveAltComs
1607+
let line = s:RemoveDelimiters('', s:Right({'alt': 1}), line)
1608+
endif
1609+
endif
1610+
1611+
1612+
let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line)
1613+
let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)
1614+
1615+
let right = s:Right()
1616+
let left = s:Left()
1617+
if !s:Multipart()
1618+
let right = s:Right({'alt': 1})
1619+
let left = s:Left({'alt': 1})
1620+
endif
1621+
1622+
1623+
"if there are place-holders on the line then we check to see if they are
1624+
"the outermost delimiters on the line. If so then we replace them with
1625+
"real delimiters
1626+
if indxLeftPlace != -1
1627+
if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
1628+
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
1629+
endif
1630+
elseif indxRightPlace != -1
1631+
if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
1632+
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
1633+
endif
1634+
1635+
endif
1636+
1637+
endif
15971638

15981639
let line = s:ConvertLeadingWhiteSpace(line)
15991640

@@ -2579,6 +2620,34 @@ function s:NumberOfLeadingTabs(s)
25792620
return strlen(substitute(a:s, '^\(\t*\).*$', '\1', ""))
25802621
endfunction
25812622

2623+
" Function: s:GetCommentCharsHR() {{{2
2624+
" returns a string of just left comment characters, the length of which is
2625+
" determined via the following rules:
2626+
function s:GetCommentCharsHR()
2627+
" this width of the horizontal rule gets set in one of three ways:
2628+
" 1. NERDCommenter setting: NERDNumCommentCharsHR
2629+
" 2. looking at text width variable (only if textwrap is set)
2630+
" 3. hard-coded value of 72
2631+
if g:NERDNumCommentCharsHR == 0
2632+
if &wrap && &textwidth > 0
2633+
let numCharsForHR = &textwidth
2634+
else
2635+
let numCharsForHR = 72
2636+
endif
2637+
else
2638+
let numCharsForHR = g:NERDNumCommentCharsHR
2639+
endif
2640+
let commentHR = repeat( s:Left(), numCharsForHR)
2641+
2642+
" this handles the case where s:Left() actually contains more than two
2643+
" characters.
2644+
if strlen(commentHR) > numCharsForHR
2645+
let commentHR = strpart(commentHR, 0, numCharsForHR)
2646+
endif
2647+
2648+
return commentHR
2649+
endfunction
2650+
25822651
" Function: s:NumLinesInBuf() {{{2
25832652
" Returns the number of lines in the current buffer
25842653
function s:NumLinesInBuf()
@@ -2877,6 +2946,7 @@ call s:CreateMaps('nx', 'Uncomment', 'Uncomment', 'cu')
28772946
call s:CreateMaps('n', 'AltDelims', 'Switch Delimiters', 'ca')
28782947
call s:CreateMaps('i', 'Insert', 'Insert Comment Here', '')
28792948
call s:CreateMaps('', ':', '-Sep3-', '')
2949+
call s:CreateMaps('nx', 'CommentHorizontalRule', 'Make a horizontal rule of comment chars', 'c_')
28802950
call s:CreateMaps('', ':help NERDCommenterContents<CR>', 'Help', '')
28812951

28822952
inoremap <silent> <plug>NERDCommenterInsert <SPACE><BS><ESC>:call NERDComment('i', "insert")<CR>

0 commit comments

Comments
 (0)