Skip to content
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

Add ability to create a line of comment characters #161

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
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 @@ -433,6 +451,8 @@ then the script would do a sexy comment on the last visual selection.
uncommenting.
|'NERDCompactSexyComs'| Specifies whether to use the compact
style sexy comments.
|'NERDNumCommentCharsHR'| Specifies how many comment characters to
use to create a horizontal rule.

------------------------------------------------------------------------------
4.3 Options details *NERDComOptionsDetails*
Expand Down Expand Up @@ -710,6 +730,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 @@ -61,6 +61,7 @@ call s:InitVariable("g:NERDRemoveAltComs", 1)
call s:InitVariable("g:NERDRemoveExtraSpaces", 0)
call s:InitVariable("g:NERDRPlace", "<]")
call s:InitVariable("g:NERDSpaceDelims", 0)
call s:InitVariable("g:NERDNumCommentCharsHR", 0)

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

Expand Down Expand Up @@ -671,6 +672,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 @@ -1139,6 +1169,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

let &ignorecase = oldIgnoreCase
Expand Down Expand Up @@ -1427,60 +1459,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:IsCommentedOuttermost(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 delims
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 delims
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 delims so we check if it has
"any random left or right delims on it and remove the outtermost ones
else
"remove the outter most left comment delim
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 outter most right comment delim
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 outtermost 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:IsCommentedOuttermost(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 delims
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 delims
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 delims so we check if it has
"any random left or right delims on it and remove the outtermost ones
else
"remove the outter most left comment delim
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 outter most right comment delim
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 outtermost 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 @@ -2465,6 +2506,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 @@ -2763,6 +2832,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