Skip to content

Commit

Permalink
Merge pull request preservim#161 from ElPiloto/master
Browse files Browse the repository at this point in the history
Add ability to create a line of comment characters
  • Loading branch information
alerque committed May 24, 2016
2 parents 2b3714b + 85a020f commit bf4fc06
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 54 deletions.
32 changes: 32 additions & 0 deletions doc/NERD_commenter.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ CONTENTS *NERDCommenterContents*
3.2.11 Use alternate delims map...|NERDComAltDelim|
3.2.12 Comment aligned maps.......|NERDComAlignedComment|
3.2.13 Uncomment line map.........|NERDComUncommentLine|
3.2.14 Comment horiz. line........|NERDComCommentHorizontalRule|
3.4 Sexy Comments.....................|NERDComSexyComments|
3.5 The NERDComment function..........|NERDComNERDComment|
4.Options.................................|NERDComOptions|
Expand Down Expand Up @@ -140,6 +141,9 @@ left side (|<Leader>|cl) or both sides (|<Leader>|cb).
Uncomments the selected line(s).


[count]|<Leader|c_ |NERDComCommentHR|
Will create a line or horizontal rule out of comment characters.

With the optional repeat.vim plugin (vimscript #2136), the mappings can also
be repeated via |.|

Expand Down Expand Up @@ -354,7 +358,21 @@ lines were selected in visual-line mode.
Related options:
|'NERDRemoveAltComs'|
|'NERDRemoveExtraSpaces'|
------------------------------------------------------------------------------
3.2.14 Make horiz. line of comments *NERDComCommentHorizontalRule*

Default mappings: [count]|<Leader>|c_
Mapped to: <plug>NERDCommenterCommentHorizontalRule
Applicable modes: normal visual-line.

Will create a line or horizontal rule out of comment characters. The width of
the rule is determined as follows:
1. If NERDNumCommentCharsHR is defined and greater than 0, use that value.
2. If &wrap is set and &textwidth is greater than 0, use that value.
3. Default to 72

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

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

------------------------------------------------------------------------------
*'NERDNumCommentCharsHR'*
Values: Any number.
Default 0.

When this option is something besides 0, it specifies how many comment
characters we'll use for creating a horizontal rule out of comments i.e. when
we use the |<Leader>|c_. If it is zero, the CommentHorizontalRule command
will determine the number of characters to use by using the &textwidth option
if it is greater than 0 and &wrap is set. Otherwise, it defaults to 72.

------------------------------------------------------------------------------

3.3 Default delimiter customisation *NERDComDefaultDelims*

If you want the NERD commenter to use the alternative delimiters for a
Expand Down
178 changes: 124 additions & 54 deletions plugin/NERD_commenter.vim
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ call s:InitVariable("g:NERDRemoveExtraSpaces", 0)
call s:InitVariable("g:NERDRPlace", "<]")
call s:InitVariable("g:NERDSpaceDelims", 0)
call s:InitVariable("g:NERDDefaultAlign", "none")
call s:InitVariable("g:NERDNumCommentCharsHR", 0)

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

Expand Down Expand Up @@ -725,6 +726,35 @@ function s:CommentBlock(top, bottom, lSide, rSide, forceNested )
endif
endfunction

" Function: s:CommentHorizontalRule(firstLine, lastLine) {{{2
" This function creates a "horizontal rule" out of comment characters for each
" line specified
"
" Args:
" -firstLine/lastLine: the top and bottom lines to comment
function s:CommentHorizontalRule(firstLine, lastLine)
let currentLine = a:firstLine
let lastLine = a:lastLine

while currentLine <= lastLine
let theLine = getline(currentLine)

" if this is a blank line, let's just insert the comment HR
if theLine =~ '\v^\s*$'
call setline(currentLine, s:GetCommentCharsHR())
" 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
else
call setline(currentLine, s:GetCommentCharsHR())
call append(currentLine, theLine)
let currentLine = currentLine + 1
let lastLine = lastLine + 1
endif

let currentLine = currentLine + 1
endwhile

endfunction

" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2
" This function comments a range of lines.
"
Expand Down Expand Up @@ -1207,6 +1237,8 @@ function! NERDComment(mode, type) range
normal! yy
endif
execute firstLine .','. lastLine .'call NERDComment("'. a:mode .'", "Comment")'
elseif a:type ==? 'CommentHorizontalRule'
call s:CommentHorizontalRule(firstLine, lastLine)
endif

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

"get the comment status on the line so we know how it is commented
let lineCommentStatus = s:IsCommentedOutermost(s:Left(), s:Right(), s:Left({'alt': 1}), s:Right({'alt': 1}), line)

"it is commented with s:Left() and s:Right() so remove these delimiters
if lineCommentStatus == 1
let line = s:RemoveDelimiters(s:Left(), s:Right(), line)

"it is commented with s:Left({'alt': 1}) and s:Right({'alt': 1}) so remove these delimiters
elseif lineCommentStatus == 2 && g:NERDRemoveAltComs
let line = s:RemoveDelimiters(s:Left({'alt': 1}), s:Right({'alt': 1}), line)

"it is not properly commented with any delimiters so we check if it has
"any random left or right delimiters on it and remove the outermost ones
else
"remove the outer most left comment delimiter
if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1)
let line = s:RemoveDelimiters(s:Left(), '', line)
elseif indxLeftAlt != -1 && g:NERDRemoveAltComs
let line = s:RemoveDelimiters(s:Left({'alt': 1}), '', line)
endif

"remove the outer most right comment delimiter
if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1)
let line = s:RemoveDelimiters('', s:Right(), line)
elseif indxRightAlt != -1 && g:NERDRemoveAltComs
let line = s:RemoveDelimiters('', s:Right({'alt': 1}), line)
endif
endif


let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line)
let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)

let right = s:Right()
let left = s:Left()
if !s:Multipart()
let right = s:Right({'alt': 1})
let left = s:Left({'alt': 1})
endif


"if there are place-holders on the line then we check to see if they are
"the outermost delimiters on the line. If so then we replace them with
"real delimiters
if indxLeftPlace != -1
if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
endif
elseif indxRightPlace != -1
if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
endif

endif
" here is an easy scenario for toggling horizontal rules: if the line
" consists solely of repetitions of s:Left(), then just set the entire
" line to be blank
" our comment string
if line =~ '\V\^\s\*\('. escape(s:Left(),'\/') . '\)\+\s\*\$'
let line = ''
else
"get the comment status on the line so we know how it is commented
let lineCommentStatus = s:IsCommentedOutermost(s:Left(), s:Right(), s:Left({'alt': 1}), s:Right({'alt': 1}), line)

"it is commented with s:Left() and s:Right() so remove these delimiters
if lineCommentStatus == 1
let line = s:RemoveDelimiters(s:Left(), s:Right(), line)

"it is commented with s:Left({'alt': 1}) and s:Right({'alt': 1}) so remove these delimiters
elseif lineCommentStatus == 2 && g:NERDRemoveAltComs
let line = s:RemoveDelimiters(s:Left({'alt': 1}), s:Right({'alt': 1}), line)

"it is not properly commented with any delimiters so we check if it has
"any random left or right delimiters on it and remove the outermost ones
else
"remove the outer most left comment delimiter
if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1)
let line = s:RemoveDelimiters(s:Left(), '', line)
elseif indxLeftAlt != -1 && g:NERDRemoveAltComs
let line = s:RemoveDelimiters(s:Left({'alt': 1}), '', line)
endif

"remove the outer most right comment delimiter
if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1)
let line = s:RemoveDelimiters('', s:Right(), line)
elseif indxRightAlt != -1 && g:NERDRemoveAltComs
let line = s:RemoveDelimiters('', s:Right({'alt': 1}), line)
endif
endif


let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line)
let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)

let right = s:Right()
let left = s:Left()
if !s:Multipart()
let right = s:Right({'alt': 1})
let left = s:Left({'alt': 1})
endif


"if there are place-holders on the line then we check to see if they are
"the outermost delimiters on the line. If so then we replace them with
"real delimiters
if indxLeftPlace != -1
if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
endif
elseif indxRightPlace != -1
if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
endif

endif

endif

let line = s:ConvertLeadingWhiteSpace(line)

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

" Function: s:GetCommentCharsHR() {{{2
" returns a string of just left comment characters, the length of which is
" determined via the following rules:
function s:GetCommentCharsHR()
" this width of the horizontal rule gets set in one of three ways:
" 1. NERDCommenter setting: NERDNumCommentCharsHR
" 2. looking at text width variable (only if textwrap is set)
" 3. hard-coded value of 72
if g:NERDNumCommentCharsHR == 0
if &wrap && &textwidth > 0
let numCharsForHR = &textwidth
else
let numCharsForHR = 72
endif
else
let numCharsForHR = g:NERDNumCommentCharsHR
endif
let commentHR = repeat( s:Left(), numCharsForHR)

" this handles the case where s:Left() actually contains more than two
" characters.
if strlen(commentHR) > numCharsForHR
let commentHR = strpart(commentHR, 0, numCharsForHR)
endif

return commentHR
endfunction

" Function: s:NumLinesInBuf() {{{2
" Returns the number of lines in the current buffer
function s:NumLinesInBuf()
Expand Down Expand Up @@ -2877,6 +2946,7 @@ call s:CreateMaps('nx', 'Uncomment', 'Uncomment', 'cu')
call s:CreateMaps('n', 'AltDelims', 'Switch Delimiters', 'ca')
call s:CreateMaps('i', 'Insert', 'Insert Comment Here', '')
call s:CreateMaps('', ':', '-Sep3-', '')
call s:CreateMaps('nx', 'CommentHorizontalRule', 'Make a horizontal rule of comment chars', 'c_')
call s:CreateMaps('', ':help NERDCommenterContents<CR>', 'Help', '')

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

0 comments on commit bf4fc06

Please sign in to comment.