From 70b5b933cd838f8a4fa5d90d074c47a3c8336429 Mon Sep 17 00:00:00 2001 From: li-zhaoyang Date: Mon, 20 Jan 2020 19:49:52 +0800 Subject: [PATCH 1/3] First version of 'NERDCommentIsCharCommented' API (Untested) --- plugin/NERD_commenter.vim | 95 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/plugin/NERD_commenter.vim b/plugin/NERD_commenter.vim index a844474..5c78574 100644 --- a/plugin/NERD_commenter.vim +++ b/plugin/NERD_commenter.vim @@ -1356,6 +1356,101 @@ function! NERDComment(mode, type) range endfunction +" Function: NERDCommentIsCharCommented(line, col) abort +" Check if the character at [line, col] is inside a comment +" Note the Comment delimeter it self is considered as part of the comment +" +" Args: +" -line the line number of the character +" -col the column number of the character +" Return: Number, 1 if the character is inside a comment, 0 if is not +function! NERDCommentIsCharCommented(line, col) abort + " Function: searchfor(str, line, col, direction, [maxline]) + " search str in the buffer, including the character at [line, col] + " Args: + " -str: the string for search + " -line: the line number where search begins + " -col: the column number where search begins + " -direction: 0 if forward, and 1 if backward + " -maxline: the max lines the search would look up + " 1 if search only one line + " if not given, search until reaches the begining or end of file + " Return: List, in the format of [line, col], where line and col is the + " position of first found result; If str cannot be found, returns + " [0, 0] + function! l:searchfor(str, line, col, direction, ...) abort + let l:curlinenr = a:line + let l:maxline = (a:0 > 4) ? a:5 : (direction ? a:line : line('$') - a:line + 1) + while abs(curlinenr - a:line) < maxline + let linestr = getline(a:line) + if curlinenr == a:line + if direction == 0 + let l:partstr = strpart(linestr, a:col - strlen(a:str)) + else + let l:partstr = strpart(linestr, 0, a:col + strlen(a:str) - 1) + endif + else + let l:partstr = linestr + endif + if !direction + let idx = stridx(a:str, partstr) + if idx != -1 + return [curlinenr, idx + 1] + endif + else + let idx = strridx(a:str, partstr) + if idx != -1 + return [curlinenr, idx + 1] + endif + endif + let curlinenr += direction ? 1 : -1 + endwhile + return [0, 0] + endfunction + function! l:checkwith(left, right, line, col) abort + let linecommented = 0 + let blockcommented = 0 + if a:right ==# '' + let leftpos = searchfor(a:left, a:line, a:col, 1, 1) + if leftpos == [0, 0] + if !linecommented | let linecommented = 0 | endif + else + if !linecommented | let linecommented = 1 | endif + endif + else + let leftpos = searchfor(a:left, a:line, a:col, 1) + if leftpos == [0, 0] + if !blockcommented | let linecommented = 0 | endif + else + call searchfor(a:right, a:line, a:col, 0) + let rightpos = searchfor(a:right, a:line, a:col, 0) + if rightpos != [0, 0] + if rightpos[0] < a:line + if !blockcommented | let blockcommented = 0 | endif + else + if !blockcommented + let blockcommented = (rightpos[1] + strlen(a:right) >= a:col) ? 0 : 1 + endif + endif + else + if !blockcommented | let blockcommented = 1 | endif + endif + endif + endif + return linecommented || blockcommented + endfunction + return checkwith( + \ b:NERDCommenterDelims['left'], + \ b:NERDCommenterDelims['right'], + \ a:line, + \ a:col) || + checkwith( + \ b:NERDCommenterDelims['leftAlt'], + \ b:NERDCommenterDelims['rightAlt'], + \ a:line, + \ a:col) +endfunction + " Function: s:PlaceDelimitersAndInsBetween() function {{{2 " This is function is called to place comment delimiters down and place the " cursor between them From eb6243c0c8566d4fc164e5c9da99faae9482117b Mon Sep 17 00:00:00 2001 From: li-zhaoyang Date: Tue, 21 Jan 2020 04:16:18 +0800 Subject: [PATCH 2/3] Finished and tested NERDCommentIsCharCommented() --- plugin/NERD_commenter.vim | 54 +++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/plugin/NERD_commenter.vim b/plugin/NERD_commenter.vim index 5c78574..a001455 100644 --- a/plugin/NERD_commenter.vim +++ b/plugin/NERD_commenter.vim @@ -1365,7 +1365,7 @@ endfunction " -col the column number of the character " Return: Number, 1 if the character is inside a comment, 0 if is not function! NERDCommentIsCharCommented(line, col) abort - " Function: searchfor(str, line, col, direction, [maxline]) + " Function: s:searchfor(str, line, col, direction, [maxline]) " search str in the buffer, including the character at [line, col] " Args: " -str: the string for search @@ -1378,13 +1378,13 @@ function! NERDCommentIsCharCommented(line, col) abort " Return: List, in the format of [line, col], where line and col is the " position of first found result; If str cannot be found, returns " [0, 0] - function! l:searchfor(str, line, col, direction, ...) abort + function! s:searchfor(str, line, col, direction, ...) abort let l:curlinenr = a:line - let l:maxline = (a:0 > 4) ? a:5 : (direction ? a:line : line('$') - a:line + 1) + let l:maxline = (a:0 > 0) ? a:1 : (a:direction ? a:line : line('$') - a:line + 1) while abs(curlinenr - a:line) < maxline - let linestr = getline(a:line) + let linestr = getline(curlinenr) if curlinenr == a:line - if direction == 0 + if !a:direction let l:partstr = strpart(linestr, a:col - strlen(a:str)) else let l:partstr = strpart(linestr, 0, a:col + strlen(a:str) - 1) @@ -1392,45 +1392,61 @@ function! NERDCommentIsCharCommented(line, col) abort else let l:partstr = linestr endif - if !direction - let idx = stridx(a:str, partstr) + if !a:direction + " forward + let idx = stridx(partstr, a:str) if idx != -1 + if curlinenr == a:line + let idx += a:col - strlen(a:str) + else + endif return [curlinenr, idx + 1] endif else - let idx = strridx(a:str, partstr) + " backward + let idx = strridx(partstr, a:str) if idx != -1 return [curlinenr, idx + 1] endif endif - let curlinenr += direction ? 1 : -1 + let curlinenr += a:direction ? -1 : 1 endwhile return [0, 0] endfunction - function! l:checkwith(left, right, line, col) abort + " Function: s:checkwith(left, right, line, col) abort + " check if the char at [line, col] is commented using [left, right] pair + " Args: + " -left: the string begins a comment + " -right: the string ends a comment + " -line: the line position of the character + " -col: the column position of the character + " Return: Number, 1 if is in a comment, 0 else + function! s:checkwith(left, right, line, col) abort let linecommented = 0 let blockcommented = 0 if a:right ==# '' - let leftpos = searchfor(a:left, a:line, a:col, 1, 1) + let leftpos = s:searchfor(a:left, a:line, a:col, 1, 1) if leftpos == [0, 0] if !linecommented | let linecommented = 0 | endif else if !linecommented | let linecommented = 1 | endif endif else - let leftpos = searchfor(a:left, a:line, a:col, 1) + let leftpos = s:searchfor(a:left, a:line, a:col, 1) if leftpos == [0, 0] - if !blockcommented | let linecommented = 0 | endif + if !blockcommented | let blockcommented = 0 | endif else - call searchfor(a:right, a:line, a:col, 0) - let rightpos = searchfor(a:right, a:line, a:col, 0) + " call s:searchfor(a:right, a:line, a:col, 0) + let rightpos = s:searchfor(a:right, leftpos[0], leftpos[1] + strlen(a:right) + 1, 0) if rightpos != [0, 0] if rightpos[0] < a:line if !blockcommented | let blockcommented = 0 | endif - else + elseif rightpos[0] == a:line if !blockcommented - let blockcommented = (rightpos[1] + strlen(a:right) >= a:col) ? 0 : 1 + let blockcommented = (rightpos[1] + strlen(a:right) > a:col) ? 1 : 0 endif + else " rightpos > a:line + if !blockcommented | let blockcommented = 1 | endif endif else if !blockcommented | let blockcommented = 1 | endif @@ -1439,12 +1455,12 @@ function! NERDCommentIsCharCommented(line, col) abort endif return linecommented || blockcommented endfunction - return checkwith( + return s:checkwith( \ b:NERDCommenterDelims['left'], \ b:NERDCommenterDelims['right'], \ a:line, \ a:col) || - checkwith( + \ s:checkwith( \ b:NERDCommenterDelims['leftAlt'], \ b:NERDCommenterDelims['rightAlt'], \ a:line, From 53f5710627c0c2230dccbbfeb08a7c080f9e545d Mon Sep 17 00:00:00 2001 From: li-zhaoyang Date: Tue, 21 Jan 2020 14:42:18 +0800 Subject: [PATCH 3/3] Added 'Interface' section to the documention --- .gitignore | 1 + doc/NERD_commenter.txt | 64 ++++++++++++++++++++++++++++++--------- plugin/NERD_commenter.vim | 6 ++++ 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 3698c0e..fcfaaec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *~ *.swp tags +DEBUG diff --git a/doc/NERD_commenter.txt b/doc/NERD_commenter.txt index 0ae7582..55fea8a 100644 --- a/doc/NERD_commenter.txt +++ b/doc/NERD_commenter.txt @@ -38,13 +38,14 @@ CONTENTS *NERDCommenterContents* 4.2 Options details...................|NERDCommenterOptionsDetails| 4.3 Default delimiter Options.........|NERDCommenterDefaultDelims| 5. Customising key mappings...............|NERDCommenterMappings| - 6. Issues with the script.................|NERDCommenterIssues| - 6.1 Delimiter detection heuristics....|NERDCommenterHeuristics| - 6.2 Nesting issues....................|NERDCommenterNesting| - 7.About.. ............................|NERDCommenterAbout| - 8.Changelog...............................|NERDCommenterChangelog| - 9.Credits.................................|NERDCommenterCredits| - 10.License................................|NERDCommenterLicense| + 6. Interfaces............................. NERDCommenterInterfaces + 7. Issues with the script.................|NERDCommenterIssues| + 7.1 Delimiter detection heuristics....|NERDCommenterHeuristics| + 7.2 Nesting issues....................|NERDCommenterNesting| + 8.About.. ............................|NERDCommenterAbout| + 9.Changelog...............................|NERDCommenterChangelog| + 10.Credits................................|NERDCommenterCredits| + 11.License................................|NERDCommenterLicense| ============================================================================== 1. Intro *NERDCommenter* @@ -883,11 +884,46 @@ map to. See also |'NERDCreateDefaultMappings'|. ============================================================================== -6. Issues with the script *NERDCommenterIssues* +6. Interfaces *NERDCommenterInterfaces* + +NERDCommentIsLineCommented({lineNo}) *NERDCommentIsLineCommented()* + Check if the line is a comment + Note this function checks if the line is **completely** a comment + Args: + {lineNo}: the line number of the line to check + Return: Number, 1 if the line is a comment, 0 else + + +NERDComment({mode}, {type}) *NERDComment()* + This function is a Wrapper for the main commenting functions + + Args: + {mode}: character indicating the mode in which the comment + is requested: + 'n' for Normal mode, 'x' for Visual mode + {type}: the type of commenting requested. Can be 'Sexy', + 'Invert', 'Minimal', 'Toggle', 'AlignLeft', + 'AlignBoth', 'Comment', 'Nested', 'ToEOL', 'Append', + 'Insert', 'Uncomment', 'Yank' + + +NERDCommentIsCharCommented({line}, {col}) *NERDCommentIsCharCommented()* + Check if the character at [{line}, {col}] is inside a comment + Note the Comment delimeter it self is considered as part of the + comment + + Args: + {line} the line number of the character + {col} the column number of the character + Return: Number, 1 if the character is inside a comment, 0 else + + +============================================================================== +7. Issues with the script *NERDCommenterIssues* ------------------------------------------------------------------------------ -6.1 Delimiter detection heuristics *NERDCommenterHeuristics* +7.1 Delimiter detection heuristics *NERDCommenterHeuristics* Heuristics are used to distinguish the real comment delimiters @@ -907,7 +943,7 @@ string. These heuristics, while usually pretty accurate, will not work for all cases. ------------------------------------------------------------------------------ -6.2 Nesting issues *NERDCommenterNesting* +7.2 Nesting issues *NERDCommenterNesting* If we have some line of code like this: > /*int foo */ = /*5 + 9;*/ @@ -927,7 +963,7 @@ will become: > for simplicity) ============================================================================== -7. About *NERDCommenterAbout* +8. About *NERDCommenterAbout* The author of the NERD commenter is Martyzillatron --- the half robot, half dinosaur bastard son of Megatron and Godzilla. He enjoys destroying @@ -944,7 +980,7 @@ The latest dev versions are on github http://github.com/preservim/nerdcommenter ============================================================================== -8. Changelog *NERDCommenterChangelog* +9. Changelog *NERDCommenterChangelog* 2.3.0 - remove all filetypes which have a &commentstring in the standard vim @@ -1010,7 +1046,7 @@ The latest dev versions are on github NERDCommenterInsert if you wish to restore it ============================================================================== -9. Credits *NERDCommenterCredits* +10. Credits *NERDCommenterCredits* Thanks to the follow people for suggestions and patches: @@ -1149,7 +1185,7 @@ Ivan Devat javascript.jquery tpope cucumber,pdf Lyude Paul piglit shader_test ============================================================================== -10. License *NERDCommenterLicense* +11. License *NERDCommenterLicense* The NERD commenter is released under the wtfpl. See http://sam.zoy.org/wtfpl/COPYING. diff --git a/plugin/NERD_commenter.vim b/plugin/NERD_commenter.vim index a001455..a6583e7 100644 --- a/plugin/NERD_commenter.vim +++ b/plugin/NERD_commenter.vim @@ -1209,6 +1209,12 @@ function s:InvertComment(firstLine, lastLine) endwhile endfunction +" Function: NERDCommentIsLineCommented(lineNo) +" Check if the line is a comment +" Note this function checks if the line is **completely** a comment +" Args: +" -lineNo: the line number of the line to check +" Return: Number, 1 if the line is a comment, 0 else function! NERDCommentIsLineCommented(lineNo) let theLine = getline(a:lineNo) return s:IsInSexyComment(a:lineNo) || s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)