From 921c0c70838181c485359d85acf46bbc66f42917 Mon Sep 17 00:00:00 2001 From: Christopher Voltz Date: Fri, 18 Mar 2016 10:07:26 -0500 Subject: [PATCH 1/3] Fix load error on Linux On Linux systems, the DOS EOL terminators cause the plugin to fail to load. Replace the DOS EOL (LF CR) with UNIX EOL (LF) so the plugin will load correctly on both Linux and Windows. Also, remove trailing whitespace. --- README | 4 +- plugin/refactor.vim | 954 ++++++++++++++++++++++---------------------- 2 files changed, 480 insertions(+), 478 deletions(-) diff --git a/README b/README index ebd45c6..16c0b96 100644 --- a/README +++ b/README @@ -1,8 +1,8 @@ This is a mirror of http://www.vim.org/scripts/script.php?script_id=2087 This plugin contains some basic refactoring commands for C/C++. -For the complexity of C++, instead of really parse the source code, I used -regular expression matches. But it works well as I tested. +For the complexity of C++, instead of really parse the source code, I used +regular expression matches. But it works well as I tested. NOTE: It doesn't work for old style parameter declaratoins! And I admit that it may mess up your code sometime if you occasionally forget the rules. Thanks for the kind man who point out this. diff --git a/plugin/refactor.vim b/plugin/refactor.vim index 0a51bd1..26cc8bc 100644 --- a/plugin/refactor.vim +++ b/plugin/refactor.vim @@ -1,476 +1,478 @@ -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" Refactor for vim -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" INTRODUCTION: -" -" This plugin contains some basic refactoring commands for C/C++(Java, C#). -" For the complexity of C++, instead of really parse the source code, I used -" regular expression matches. But it works well as I tested. -" -" The refactor commands and their default key map currently are: -" 1. e Extract method -" 2. p local variable to Parameter -" 3. r Rename LOCAL variable -" 4. d Delete parameter -" 5. o reOrder parameters -" 6. c introduce Constant -" -" BiDongliang bidongliang_2000@126.com 2007/12/4 -" -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" LIMITATION: -" 1. Parameter with default value is not supported -" 2. Nested template type are limit to 3 layers, and multiple template -" template parameter is not supported. But you can enable them by modify -" the variable s:TemplateParameterPattern. -" list supported -" list > supported -" list > > supported -" list > supported -" list, list > unsuported -" 3. Rename refactor can only perform on local variables. -" 4. Register z is used when extract method. -" 5. 10 parameter supported at most. -" -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" BUGS: -" 1. (Fixed) Can not handle 'int a = 0' like statment in local variable to -" parameter, because s:IdentifierPattern can not start with digit. -" 2. (Fixed) Add word boundary to some patterns. (\<\>) -" 3. (Fixed) will expand to whole expression in introducing constant. -" Thus, abc3def[>4<] will parse to 3. Fixed by iteration. -" 4. (Fixed) Parse error of variable defination with initialization. -" -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -" These are the default key mappings -map e :call ExtractMethod() -map p :call LocalVariableToParameter() -map r :call RenameVariable() -map d :call RemoveParameter() -map o :call ReorderParameters() -map c :call IntroduceConstant() - -" Used to prevent the keywords be parsed as variable name -let s:Keywords = ["auto", "const", "double", "float", "int", "short", "struct", "unsigned", "break", "continue", "else", "for", "long", "signed", "switch", "void", "case", "default", "enum", "goto", "register", "sizeof", "typedef", "volatile", "char", "do", "extern", "if", "return", "static", "union", "while", "asm", "dynamic_cast", "namespace", "reinterpret_cast", "try", "bool", "explicit", "new", "static_cast", "typeid", "catch", "false", "operator", "template", "typename", "class", "friend", "private", "this", "using", "const_cast", "inline", "public", "throw", "virtual", "delete", "mutable", "protected", "true", "wchar_t", "size_t"] - -" Patterns used to match language element -let s:IdentifierPattern = '\<\h\w*\>' -let s:TypePostfixPattern = '\s*[*&]*\s*' -let s:TypeElementPattern = s:IdentifierPattern . s:TypePostfixPattern -let s:TemplateParameterPattern = '\%(<[^<>]*>\|<[^<>]*<[^<>]*>[^<>]\+>\|<[^<>]*<[^<>]*<[^<>]*>[^<>]*>[^<>]\+>\)' "'<\s*' . s:TypeElementPattern . '\%(\s*,\s*' . s:TypeElementPattern . '\)*>' -let s:TypeIdentifierPattern = '\%(' . s:TypeElementPattern . '\%(' . s:TemplateParameterPattern . s:TypePostfixPattern . '\)*' . s:TypePostfixPattern . '\)\+' -let s:MissableSeperatorPattern = '\%(\s*\n*\s*\)' "'\s*\n*\s*' -let s:SeperatorPattern = '\%(\s\+\n*\s*\|\n\+\|\s*\n*\s\+\)' -let s:VariableDeclarationPattern = s:TypeIdentifierPattern . s:MissableSeperatorPattern . s:IdentifierPattern . '\%\(\[\d*\]\)*' -let s:FunctionPerfixPattern = '^\s*\%(' . s:TypeIdentifierPattern . s:SeperatorPattern. '\|' . s:IdentifierPattern . '::\)\+' -let s:ParameterListPattern = '(' . s:MissableSeperatorPattern . '\%(' . s:VariableDeclarationPattern . '\%(\s*,' . s:MissableSeperatorPattern . s:VariableDeclarationPattern . '\)*\)*\s*)' -let s:FunctionPattern = s:FunctionPerfixPattern . s:MissableSeperatorPattern . s:IdentifierPattern . s:MissableSeperatorPattern . s:ParameterListPattern . '[^(){;]*' -let s:FunctionDeclarationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%(;\)\@=' -let s:FunctionDefinationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%({\)\@=' - -function! IntroduceConstant() - let NumberPattern = '\%(\d\+\.\?\d*\|\d*\.\d\+\)\%(f\|F\|L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?' "'\d\+\%(L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?\|\d\+\.\d\+[Ff]\?\|\.\d\+[Ff]\?' - let text = getline('.') - let position = col('.') - 1 - while strpart(text, position) =~ '^' . NumberPattern && position > 0 - let position = position - 1 - endwhile - let matched = matchstr(strpart(text, position), NumberPattern) - if matched == "" - call confirm('Can not parse a constant under cursor!') - return - endif - let constantName = inputdialog('Input the name for ' . matched . ' :') - if constantName != "" - let type = "" - if match(matched, 'ul\|UL\|uL\|Ul') >= 0 - let type = 'unsigned long' - elseif match(matched, '[Uu]') >= 0 - let type = 'unsigned int' - elseif match(matched, '[Ll]') >= 0 - let type = 'long' - elseif match(matched, '[fF]') >= 0 - let type = 'float' - elseif match(matched, '\.') >= 0 - let type = 'double' - else - let type = 'int' - endif - call GotoBeginingBracketOfCurrentFunction() - call search(matched, 'W') - exec 'normal! [{' - exec "normal! oconst " . type . " " . constantName . ' = ' . matched . ";\e" - let startLine = line('.') + 1 - let replace = confirm('Replate all ' . matched .' in this function with "' . constantName . '"?', "&Yes\n&No") - if replace == 1 - call GotoBeginingBracketOfCurrentFunction() - normal! % - let stopLine = line('.') - exec 'normal! :' . startLine . ',' . stopLine . 's/\<' . matched . '\>\%(\.\)\@!/' . constantName . "/g\r" - endif - endif -endfunction - -function! ReorderParameters() - let originLine = line('.') - let originCol = col('.') - let parameterList = GetParameterListOfCurrentFunction() - if len(parameterList) == 1 - if parameterList[0] == 'NONE' - call confirm('There is no parameter to reorder!') - else - call confirm('Can not reorder the only parameter!') - endif - return - endif - if len(parameterList) > 0 - if len(parameterList) > 10 - call confirm('Parameter count should less than 10!') - return - endif - let text = "Parameters of current function are:" - let start = 0 - while start < len(parameterList) - let text = text . "\n" . start . ': ' . parameterList[start] - let start = start + 1 - endwhile - let text = text . "\nInput the index of parameteres in new order:" - let processed = 0 - while processed == 0 - let order = inputdialog(text) - if order != "" - if order =~ '\D' - call confirm('Just input the indexes without seperator, please!') - continue - endif - let processed = 1 - let index = 0 - while index < len(parameterList) - if stridx(order, index) < 0 - call confirm('You missed parameter ' . index) - let processed = 0 - break - endif - let index = index + 1 - endwhile - if processed == 1 - call cursor(originLine, originCol) - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - exec "normal! d/)\ri(\e" - let index = 0 - while index < strlen(order) - let current = strpart(order, index, 1) - exec "normal! a" . parameterList[current] . "\e" - if index < strlen(order) - 1 - exec "normal! a, \e" - let currentCol = col('.') - if currentCol > 80 - exec "normal! a\r\e" - endif - endif - let index = index + 1 - endwhile - endif - else - let processed = 1 - endif - endwhile - endif -endfunction - -function! RemoveParameter() - let parameterList = GetParameterListOfCurrentFunction() - if len(parameterList) == 1 && parameterList[0] == 'NONE' - call confirm('There is no parameter to remove!') - return - endif - - if len(parameterList) > 0 - let text = "Parameters of current function are:" - let start = 0 - while start < len(parameterList) - let text = text . "\n" . start . ': ' . parameterList[start] - let start = start + 1 - endwhile - let text = text . "\nInput the index of parameter to remove:" - let index = inputdialog(text) - if index != "" && index >= 0 && index < len(parameterList) - call search(s:FunctionPattern, 'bW') - let parameter = escape(parameterList[index], '*') - if search(parameter, 'W') > 0 - let text = getline('.') - if match(text, parameter . '\s*,') >= 0 - normal! df, - else - let startCol = match(text, ',\s*' . parameter) - let matched = matchstr(text, '\(,\s*\)*' . parameter) - if startCol >= 0 - let text = strpart(text, 0, startCol) . strpart(text, startCol + strlen(matched)) - call setline('.', text) - endif - endif - endif - endif - else - call confirm("Sorry, I can not parse the function parameter list!") - endif -endfunction - -function! RenameVariable() - let originRow = line('.') - let originCol = col('.') - let variableName = expand('') - let variableType = GetCurrentVariableType(0) - if variableType == "" - call confirm("Can not rename because ". variableName . " is not a local variable!") - return - endif - let newName = inputdialog("Input new name for ". variableName . ":") - if newName != "" - call GotoBeginingBracketOfCurrentFunction() - let startLine = line('.') - exec "normal! %" - let stopLine = line('.') - exec startLine . ',' . stopLine . ':s/\<' . variableName . '\>/'. newName .'/g' - endif - call cursor(originRow, originCol) -endfunction - -function! LocalVariableToParameter() - let variableName = expand('') - let variableType = GetCurrentVariableType(0) - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - if match(getline('.'), '(\s*)') >= 0 - call search(')') - exec "normal! i" . variableType . ' ' . variableName . "\e" - else - call search(')') - exec "normal! i, " . variableType . ' ' . variableName . "\e" - endif - call search('{') - call search('\<' . variableName . '\>') - let currentLine = getline('.') - if match(currentLine, variableType . '\s*\<' . variableName . '\>\s*;') >= 0 - call search(variableType, 'bW') - exec "normal! df;" - if match(getline('.'), '^\s*$') >= 0 - exec "normal! dd" - endif - else - if match(currentLine, '\<' . variableName . '\>\s*=') >= 0 - let variableDefination = matchstr(currentLine, '\<' . variableName . '\>\s*=\s*.\{-\}\([,;]\)\@=') - let remainStart = match(currentLine, '\<' . variableName . '\>\s*=\s*\((.*)\)*') + strlen(variableDefination) - let remain = strpart(currentLine, remainStart) - if match(remain, s:IdentifierPattern) >= 0 - call setline('.', variableType . strpart(remain, stridx(remain, ',') + 1)) - exec "normal! O" . variableDefination . ';' - exec "normal! 2==" - else - call setline('.', variableDefination . ';') - exec "normal! ==" - endif - else - if match(currentLine, '\<' . variableName . '\>\s*,') <0 - call confirm("I can not erase the variable defination, \nplease do it yourself!") - else - exec "normal! cf," - exec "normal! ==" - endif - endif - endif -endfunction - -function! ExtractMethod() range - let scopeIdentifier = GetScopeIdentifierOfCurrentMethod() - let variableList = [] - let varableLocalScopeType = [] - let variableParentScopeType = [] - while 1 - let variableName = MoveToNextVariable(a:lastline) - if variableName == "" - break - endif - if index(variableList, variableName) < 0 - call add(variableList, variableName) - let type = GetCurrentVariableType(0) - call add(variableParentScopeType, type) - let type = GetCurrentVariableType(a:firstline) - call add(varableLocalScopeType, type) - endif - endwhile - let methodName = inputdialog("Input the function name:") - if methodName != "" - " use register z to yank the texts - exec "normal! " . a:firstline ."G0\"zy" . a:lastline . "G" - if scopeIdentifier == "" - call GotoBeginingBracketOfCurrentFunction() - exec "normal! %" - exec "normal! 2o\ei//\e78a-\eo\eccvoid ". methodName . "(\e" - else - call GotoBeginingBracketOfCurrentFunction() - exec "normal! %" - exec "normal! 2o\ei//\e78a-\eo\eccvoid ". scopeIdentifier . "::" . methodName . "(\e" - endif - let idx = 0 - let parameterCount = 0 - while idx < len(variableList) - if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" - if parameterCount > 0 - exec "normal! a, \e" - endif - if col('.') > 80 && idx < len(variableList) - 1 - exec "normal! ==A\r\e" - endif - if variableParentScopeType[idx] =~ '\[\d*\]' - let postfix = matchstr(variableParentScopeType[idx], '\[\d*\]') - let type = strpart(variableParentScopeType[idx], 0, match(variableParentScopeType[idx], '\[\d*\]')) - exec "normal! a" . type . " " . variableList[idx] . postfix . "\e" - else - exec "normal! a" . variableParentScopeType[idx] . " " . variableList[idx] . "\e" - endif - let parameterCount = parameterCount + 1 - endif - let idx = idx + 1 - endwhile - exec "normal! a)\e==A\r{\r}\ek\"zp=']" - - if confirm("Replace selection with function call?", "&Yes\n&No", 1) == 1 - exec "normal! " . a:firstline ."G0c" . a:lastline . "G" - exec "normal! a" . methodName . "(" - let idx = 0 - let parameterCount = 0 - while idx < len(variableList) - if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" - if parameterCount > 0 - exec "normal! a, \e" - endif - exec "normal! a" . variableList[idx] . "\e" - let parameterCount = parameterCount + 1 - endif - let idx = idx + 1 - endwhile - exec "normal! a);\e==" - endif - endif -endfunction - -function! MoveToNextVariable(endLine) - let identifier = "" - while search('\([)]\s*\)\@ 0 - let identifier = expand('') - if index(s:Keywords, expand('')) >= 0 - let identifier = "" - continue - endif - break - endwhile - return identifier -endfunction - -" search variable defination in current function scope -function! GetCurrentVariableType(topestLine) - let variableType = "" - let startRow = line('.') - let startCol = col('.') - let variableName = expand("") - normal! e - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - let stopRow = line('.') - if a:topestLine > stopRow - let stopRow = a:topestLine - endif - call cursor(startRow, 1000) - - - let DeclarationPattern = s:TypeIdentifierPattern . '\s*\%(' . s:IdentifierPattern . '[^()]*,\s*\)*\<' . variableName . '\>\%(\[\d*\]\)*' - while search(DeclarationPattern, "bW", stopRow) > 0 - if expand('') =~ 'return' - continue - endif - let currentLine = getline('.') - let commentStart = match(currentLine, '//') - if commentStart >= 0 && commentStart < match(currentLine, DeclarationPattern) - continue - endif - let matched = matchstr(currentLine, DeclarationPattern) - let typeend = match(matched, '\(\s*' . s:IdentifierPattern . '\s*[=,][^<>]*\)*\<'. variableName . '\>') - let variableType = strpart(matched, 0, typeend) - if matched =~ '\[\d*\]' - let postfix = matchstr(matched, '\[\d*\]') - let variableType = variableType . postfix - endif - break - endwhile - call cursor(startRow, startCol) - return variableType -endfunction - -function! GetScopeIdentifierOfCurrentMethod() - let scopeIdentifier = "" - let originRow = line('.') - let originCol = col('.') - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - if search(s:IdentifierPattern . '::', 'bW', line('.') - 2) > 0 - let scopeIdentifier = expand('') - endif - call cursor(originRow, originCol) - return scopeIdentifier -endfunction - -function! GotoBeginingBracketOfCurrentFunction() - if search(s:FunctionPattern, 'bW') > 0 - if search('{', 'W') <= 0 - exec 'normal! [[' - endif - endif -endfunction - -function! GetParameterListOfCurrentFunction() - let parameterList = [] - if search(s:FunctionPattern, 'bW') > 0 - call search('(') - let startLine = line('.') - let startCol = col('.') - normal! % - let stopLine = line('.') - let stopCol = col('.') - - let closeBraceIndex = 0 - let lineIter = startLine - let text = "" - while lineIter < stopLine - let text = text . getline(lineIter) - let closeBraceIndex = closeBraceIndex + strlen(getline(lineIter)) - let lineIter = lineIter + 1 - endwhile - let text = text . getline(stopLine) - let closeBraceIndex = closeBraceIndex + stopCol - - let emptyPair = match(text, '(\s*)') - if emptyPair >= 0 && emptyPair <= startCol + 2 - call add(parameterList, 'NONE') - return parameterList - endif - - let start = startCol - 1 - while 1 - let parameter = matchstr(text, s:VariableDeclarationPattern, start) - let start = match(text, s:VariableDeclarationPattern, start) - let start = start + strlen(parameter) - if start >= closeBraceIndex || start < 0 - break - endif - if parameter != "" - call add(parameterList, parameter) - else - break - endif - endwhile - endif - return parameterList -endfunction +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Refactor for vim +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" INTRODUCTION: +" +" This plugin contains some basic refactoring commands for C/C++(Java, C#). +" For the complexity of C++, instead of really parse the source code, I used +" regular expression matches. But it works well as I tested. +" +" The refactor commands and their default key map currently are: +" 1. e Extract method +" 2. p local variable to Parameter +" 3. r Rename LOCAL variable +" 4. d Delete parameter +" 5. o reOrder parameters +" 6. c introduce Constant +" +" BiDongliang bidongliang_2000@126.com 2007/12/4 +" +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" LIMITATION: +" 1. Parameter with default value is not supported +" 2. Nested template type are limit to 3 layers, and multiple template +" template parameter is not supported. But you can enable them by modify +" the variable s:TemplateParameterPattern. +" list supported +" list > supported +" list > > supported +" list > supported +" list, list > unsuported +" 3. Rename refactor can only perform on local variables. +" 4. Register z is used when extract method. +" 5. 10 parameter supported at most. +" +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" BUGS: +" 1. (Fixed) Can not handle 'int a = 0' like statment in local variable to +" parameter, because s:IdentifierPattern can not start with digit. +" 2. (Fixed) Add word boundary to some patterns. (\<\>) +" 3. (Fixed) will expand to whole expression in introducing constant. +" Thus, abc3def[>4<] will parse to 3. Fixed by iteration. +" 4. (Fixed) Parse error of variable defination with initialization. +" 5. (Fixed) DOS EOL terminations cause the plugin to fail to load on +" Linux. +" +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" These are the default key mappings +map e :call ExtractMethod() +map p :call LocalVariableToParameter() +map r :call RenameVariable() +map d :call RemoveParameter() +map o :call ReorderParameters() +map c :call IntroduceConstant() + +" Used to prevent the keywords be parsed as variable name +let s:Keywords = ["auto", "const", "double", "float", "int", "short", "struct", "unsigned", "break", "continue", "else", "for", "long", "signed", "switch", "void", "case", "default", "enum", "goto", "register", "sizeof", "typedef", "volatile", "char", "do", "extern", "if", "return", "static", "union", "while", "asm", "dynamic_cast", "namespace", "reinterpret_cast", "try", "bool", "explicit", "new", "static_cast", "typeid", "catch", "false", "operator", "template", "typename", "class", "friend", "private", "this", "using", "const_cast", "inline", "public", "throw", "virtual", "delete", "mutable", "protected", "true", "wchar_t", "size_t"] + +" Patterns used to match language element +let s:IdentifierPattern = '\<\h\w*\>' +let s:TypePostfixPattern = '\s*[*&]*\s*' +let s:TypeElementPattern = s:IdentifierPattern . s:TypePostfixPattern +let s:TemplateParameterPattern = '\%(<[^<>]*>\|<[^<>]*<[^<>]*>[^<>]\+>\|<[^<>]*<[^<>]*<[^<>]*>[^<>]*>[^<>]\+>\)' "'<\s*' . s:TypeElementPattern . '\%(\s*,\s*' . s:TypeElementPattern . '\)*>' +let s:TypeIdentifierPattern = '\%(' . s:TypeElementPattern . '\%(' . s:TemplateParameterPattern . s:TypePostfixPattern . '\)*' . s:TypePostfixPattern . '\)\+' +let s:MissableSeperatorPattern = '\%(\s*\n*\s*\)' "'\s*\n*\s*' +let s:SeperatorPattern = '\%(\s\+\n*\s*\|\n\+\|\s*\n*\s\+\)' +let s:VariableDeclarationPattern = s:TypeIdentifierPattern . s:MissableSeperatorPattern . s:IdentifierPattern . '\%\(\[\d*\]\)*' +let s:FunctionPerfixPattern = '^\s*\%(' . s:TypeIdentifierPattern . s:SeperatorPattern. '\|' . s:IdentifierPattern . '::\)\+' +let s:ParameterListPattern = '(' . s:MissableSeperatorPattern . '\%(' . s:VariableDeclarationPattern . '\%(\s*,' . s:MissableSeperatorPattern . s:VariableDeclarationPattern . '\)*\)*\s*)' +let s:FunctionPattern = s:FunctionPerfixPattern . s:MissableSeperatorPattern . s:IdentifierPattern . s:MissableSeperatorPattern . s:ParameterListPattern . '[^(){;]*' +let s:FunctionDeclarationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%(;\)\@=' +let s:FunctionDefinationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%({\)\@=' + +function! IntroduceConstant() + let NumberPattern = '\%(\d\+\.\?\d*\|\d*\.\d\+\)\%(f\|F\|L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?' "'\d\+\%(L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?\|\d\+\.\d\+[Ff]\?\|\.\d\+[Ff]\?' + let text = getline('.') + let position = col('.') - 1 + while strpart(text, position) =~ '^' . NumberPattern && position > 0 + let position = position - 1 + endwhile + let matched = matchstr(strpart(text, position), NumberPattern) + if matched == "" + call confirm('Can not parse a constant under cursor!') + return + endif + let constantName = inputdialog('Input the name for ' . matched . ' :') + if constantName != "" + let type = "" + if match(matched, 'ul\|UL\|uL\|Ul') >= 0 + let type = 'unsigned long' + elseif match(matched, '[Uu]') >= 0 + let type = 'unsigned int' + elseif match(matched, '[Ll]') >= 0 + let type = 'long' + elseif match(matched, '[fF]') >= 0 + let type = 'float' + elseif match(matched, '\.') >= 0 + let type = 'double' + else + let type = 'int' + endif + call GotoBeginingBracketOfCurrentFunction() + call search(matched, 'W') + exec 'normal! [{' + exec "normal! oconst " . type . " " . constantName . ' = ' . matched . ";\e" + let startLine = line('.') + 1 + let replace = confirm('Replate all ' . matched .' in this function with "' . constantName . '"?', "&Yes\n&No") + if replace == 1 + call GotoBeginingBracketOfCurrentFunction() + normal! % + let stopLine = line('.') + exec 'normal! :' . startLine . ',' . stopLine . 's/\<' . matched . '\>\%(\.\)\@!/' . constantName . "/g\r" + endif + endif +endfunction + +function! ReorderParameters() + let originLine = line('.') + let originCol = col('.') + let parameterList = GetParameterListOfCurrentFunction() + if len(parameterList) == 1 + if parameterList[0] == 'NONE' + call confirm('There is no parameter to reorder!') + else + call confirm('Can not reorder the only parameter!') + endif + return + endif + if len(parameterList) > 0 + if len(parameterList) > 10 + call confirm('Parameter count should less than 10!') + return + endif + let text = "Parameters of current function are:" + let start = 0 + while start < len(parameterList) + let text = text . "\n" . start . ': ' . parameterList[start] + let start = start + 1 + endwhile + let text = text . "\nInput the index of parameteres in new order:" + let processed = 0 + while processed == 0 + let order = inputdialog(text) + if order != "" + if order =~ '\D' + call confirm('Just input the indexes without seperator, please!') + continue + endif + let processed = 1 + let index = 0 + while index < len(parameterList) + if stridx(order, index) < 0 + call confirm('You missed parameter ' . index) + let processed = 0 + break + endif + let index = index + 1 + endwhile + if processed == 1 + call cursor(originLine, originCol) + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + exec "normal! d/)\ri(\e" + let index = 0 + while index < strlen(order) + let current = strpart(order, index, 1) + exec "normal! a" . parameterList[current] . "\e" + if index < strlen(order) - 1 + exec "normal! a, \e" + let currentCol = col('.') + if currentCol > 80 + exec "normal! a\r\e" + endif + endif + let index = index + 1 + endwhile + endif + else + let processed = 1 + endif + endwhile + endif +endfunction + +function! RemoveParameter() + let parameterList = GetParameterListOfCurrentFunction() + if len(parameterList) == 1 && parameterList[0] == 'NONE' + call confirm('There is no parameter to remove!') + return + endif + + if len(parameterList) > 0 + let text = "Parameters of current function are:" + let start = 0 + while start < len(parameterList) + let text = text . "\n" . start . ': ' . parameterList[start] + let start = start + 1 + endwhile + let text = text . "\nInput the index of parameter to remove:" + let index = inputdialog(text) + if index != "" && index >= 0 && index < len(parameterList) + call search(s:FunctionPattern, 'bW') + let parameter = escape(parameterList[index], '*') + if search(parameter, 'W') > 0 + let text = getline('.') + if match(text, parameter . '\s*,') >= 0 + normal! df, + else + let startCol = match(text, ',\s*' . parameter) + let matched = matchstr(text, '\(,\s*\)*' . parameter) + if startCol >= 0 + let text = strpart(text, 0, startCol) . strpart(text, startCol + strlen(matched)) + call setline('.', text) + endif + endif + endif + endif + else + call confirm("Sorry, I can not parse the function parameter list!") + endif +endfunction + +function! RenameVariable() + let originRow = line('.') + let originCol = col('.') + let variableName = expand('') + let variableType = GetCurrentVariableType(0) + if variableType == "" + call confirm("Can not rename because ". variableName . " is not a local variable!") + return + endif + let newName = inputdialog("Input new name for ". variableName . ":") + if newName != "" + call GotoBeginingBracketOfCurrentFunction() + let startLine = line('.') + exec "normal! %" + let stopLine = line('.') + exec startLine . ',' . stopLine . ':s/\<' . variableName . '\>/'. newName .'/g' + endif + call cursor(originRow, originCol) +endfunction + +function! LocalVariableToParameter() + let variableName = expand('') + let variableType = GetCurrentVariableType(0) + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + if match(getline('.'), '(\s*)') >= 0 + call search(')') + exec "normal! i" . variableType . ' ' . variableName . "\e" + else + call search(')') + exec "normal! i, " . variableType . ' ' . variableName . "\e" + endif + call search('{') + call search('\<' . variableName . '\>') + let currentLine = getline('.') + if match(currentLine, variableType . '\s*\<' . variableName . '\>\s*;') >= 0 + call search(variableType, 'bW') + exec "normal! df;" + if match(getline('.'), '^\s*$') >= 0 + exec "normal! dd" + endif + else + if match(currentLine, '\<' . variableName . '\>\s*=') >= 0 + let variableDefination = matchstr(currentLine, '\<' . variableName . '\>\s*=\s*.\{-\}\([,;]\)\@=') + let remainStart = match(currentLine, '\<' . variableName . '\>\s*=\s*\((.*)\)*') + strlen(variableDefination) + let remain = strpart(currentLine, remainStart) + if match(remain, s:IdentifierPattern) >= 0 + call setline('.', variableType . strpart(remain, stridx(remain, ',') + 1)) + exec "normal! O" . variableDefination . ';' + exec "normal! 2==" + else + call setline('.', variableDefination . ';') + exec "normal! ==" + endif + else + if match(currentLine, '\<' . variableName . '\>\s*,') <0 + call confirm("I can not erase the variable defination, \nplease do it yourself!") + else + exec "normal! cf," + exec "normal! ==" + endif + endif + endif +endfunction + +function! ExtractMethod() range + let scopeIdentifier = GetScopeIdentifierOfCurrentMethod() + let variableList = [] + let varableLocalScopeType = [] + let variableParentScopeType = [] + while 1 + let variableName = MoveToNextVariable(a:lastline) + if variableName == "" + break + endif + if index(variableList, variableName) < 0 + call add(variableList, variableName) + let type = GetCurrentVariableType(0) + call add(variableParentScopeType, type) + let type = GetCurrentVariableType(a:firstline) + call add(varableLocalScopeType, type) + endif + endwhile + let methodName = inputdialog("Input the function name:") + if methodName != "" + " use register z to yank the texts + exec "normal! " . a:firstline ."G0\"zy" . a:lastline . "G" + if scopeIdentifier == "" + call GotoBeginingBracketOfCurrentFunction() + exec "normal! %" + exec "normal! 2o\ei//\e78a-\eo\eccvoid ". methodName . "(\e" + else + call GotoBeginingBracketOfCurrentFunction() + exec "normal! %" + exec "normal! 2o\ei//\e78a-\eo\eccvoid ". scopeIdentifier . "::" . methodName . "(\e" + endif + let idx = 0 + let parameterCount = 0 + while idx < len(variableList) + if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" + if parameterCount > 0 + exec "normal! a, \e" + endif + if col('.') > 80 && idx < len(variableList) - 1 + exec "normal! ==A\r\e" + endif + if variableParentScopeType[idx] =~ '\[\d*\]' + let postfix = matchstr(variableParentScopeType[idx], '\[\d*\]') + let type = strpart(variableParentScopeType[idx], 0, match(variableParentScopeType[idx], '\[\d*\]')) + exec "normal! a" . type . " " . variableList[idx] . postfix . "\e" + else + exec "normal! a" . variableParentScopeType[idx] . " " . variableList[idx] . "\e" + endif + let parameterCount = parameterCount + 1 + endif + let idx = idx + 1 + endwhile + exec "normal! a)\e==A\r{\r}\ek\"zp=']" + + if confirm("Replace selection with function call?", "&Yes\n&No", 1) == 1 + exec "normal! " . a:firstline ."G0c" . a:lastline . "G" + exec "normal! a" . methodName . "(" + let idx = 0 + let parameterCount = 0 + while idx < len(variableList) + if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" + if parameterCount > 0 + exec "normal! a, \e" + endif + exec "normal! a" . variableList[idx] . "\e" + let parameterCount = parameterCount + 1 + endif + let idx = idx + 1 + endwhile + exec "normal! a);\e==" + endif + endif +endfunction + +function! MoveToNextVariable(endLine) + let identifier = "" + while search('\([)]\s*\)\@ 0 + let identifier = expand('') + if index(s:Keywords, expand('')) >= 0 + let identifier = "" + continue + endif + break + endwhile + return identifier +endfunction + +" search variable defination in current function scope +function! GetCurrentVariableType(topestLine) + let variableType = "" + let startRow = line('.') + let startCol = col('.') + let variableName = expand("") + normal! e + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + let stopRow = line('.') + if a:topestLine > stopRow + let stopRow = a:topestLine + endif + call cursor(startRow, 1000) + + + let DeclarationPattern = s:TypeIdentifierPattern . '\s*\%(' . s:IdentifierPattern . '[^()]*,\s*\)*\<' . variableName . '\>\%(\[\d*\]\)*' + while search(DeclarationPattern, "bW", stopRow) > 0 + if expand('') =~ 'return' + continue + endif + let currentLine = getline('.') + let commentStart = match(currentLine, '//') + if commentStart >= 0 && commentStart < match(currentLine, DeclarationPattern) + continue + endif + let matched = matchstr(currentLine, DeclarationPattern) + let typeend = match(matched, '\(\s*' . s:IdentifierPattern . '\s*[=,][^<>]*\)*\<'. variableName . '\>') + let variableType = strpart(matched, 0, typeend) + if matched =~ '\[\d*\]' + let postfix = matchstr(matched, '\[\d*\]') + let variableType = variableType . postfix + endif + break + endwhile + call cursor(startRow, startCol) + return variableType +endfunction + +function! GetScopeIdentifierOfCurrentMethod() + let scopeIdentifier = "" + let originRow = line('.') + let originCol = col('.') + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + if search(s:IdentifierPattern . '::', 'bW', line('.') - 2) > 0 + let scopeIdentifier = expand('') + endif + call cursor(originRow, originCol) + return scopeIdentifier +endfunction + +function! GotoBeginingBracketOfCurrentFunction() + if search(s:FunctionPattern, 'bW') > 0 + if search('{', 'W') <= 0 + exec 'normal! [[' + endif + endif +endfunction + +function! GetParameterListOfCurrentFunction() + let parameterList = [] + if search(s:FunctionPattern, 'bW') > 0 + call search('(') + let startLine = line('.') + let startCol = col('.') + normal! % + let stopLine = line('.') + let stopCol = col('.') + + let closeBraceIndex = 0 + let lineIter = startLine + let text = "" + while lineIter < stopLine + let text = text . getline(lineIter) + let closeBraceIndex = closeBraceIndex + strlen(getline(lineIter)) + let lineIter = lineIter + 1 + endwhile + let text = text . getline(stopLine) + let closeBraceIndex = closeBraceIndex + stopCol + + let emptyPair = match(text, '(\s*)') + if emptyPair >= 0 && emptyPair <= startCol + 2 + call add(parameterList, 'NONE') + return parameterList + endif + + let start = startCol - 1 + while 1 + let parameter = matchstr(text, s:VariableDeclarationPattern, start) + let start = match(text, s:VariableDeclarationPattern, start) + let start = start + strlen(parameter) + if start >= closeBraceIndex || start < 0 + break + endif + if parameter != "" + call add(parameterList, parameter) + else + break + endif + endwhile + endif + return parameterList +endfunction From b014d0fafe37a240f3ba4c4de514a9ca0e761d6e Mon Sep 17 00:00:00 2001 From: Christopher Voltz Date: Fri, 18 Mar 2016 10:34:38 -0500 Subject: [PATCH 2/3] Fix documentation Modify the text in the README and the plugin to be the same. Looks like they were originally the same but drifted apart over time. Fix several grammar and spelling mistakes. Modify layout of text in a few places to line things up better. --- README | 14 ++++++++------ plugin/refactor.vim | 30 +++++++++++++++--------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/README b/README index 16c0b96..2c6ee47 100644 --- a/README +++ b/README @@ -1,16 +1,18 @@ This is a mirror of http://www.vim.org/scripts/script.php?script_id=2087 -This plugin contains some basic refactoring commands for C/C++. -For the complexity of C++, instead of really parse the source code, I used -regular expression matches. But it works well as I tested. +This plugin contains some basic refactoring commands for C and C++. Due to the +complexity of C++, instead of actually parsing the source code, I used regular +expression matching--but, based on my testing, it works well. -NOTE: It doesn't work for old style parameter declaratoins! And I admit that it may mess up your code sometime if you occasionally forget the rules. Thanks for the kind man who point out this. +NOTE: It doesn't work for old-style parameter declarations! I admit that it may +mess up your code sometime if you occasionally forget the rules. Thanks to the +kind man who pointed this out. -The refactor commands and their default key map currently are: +The refactor commands and their default key mappings are: 1. e Extract method 2. p local variable to Parameter - 3. r Rename local variable + 3. r Rename local variable 4. d Delete parameter 5. o reOrder parameters 6. c introduce Constant diff --git a/plugin/refactor.vim b/plugin/refactor.vim index 26cc8bc..f1677f2 100644 --- a/plugin/refactor.vim +++ b/plugin/refactor.vim @@ -3,14 +3,14 @@ """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " INTRODUCTION: " -" This plugin contains some basic refactoring commands for C/C++(Java, C#). -" For the complexity of C++, instead of really parse the source code, I used -" regular expression matches. But it works well as I tested. +" This plugin contains some basic refactoring commands for C and C++. Due to +" the complexity of C++, instead of actually parsing the source code, I used +" regular expression matching--but, based on my testing, it works well. " -" The refactor commands and their default key map currently are: +" The refactor commands and their default key mappings are: " 1. e Extract method " 2. p local variable to Parameter -" 3. r Rename LOCAL variable +" 3. r Rename local variable " 4. d Delete parameter " 5. o reOrder parameters " 6. c introduce Constant @@ -18,19 +18,19 @@ " BiDongliang bidongliang_2000@126.com 2007/12/4 " """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" LIMITATION: -" 1. Parameter with default value is not supported -" 2. Nested template type are limit to 3 layers, and multiple template -" template parameter is not supported. But you can enable them by modify -" the variable s:TemplateParameterPattern. +" LIMITATIONS: +" 1. Parameters with a default value are not supported +" 2. Nested template types are limited to 3 layers, and multiple template +" parameters are not supported; but, you can enable them by modifying +" the variable s:TemplateParameterPattern. " list supported " list > supported " list > > supported " list > supported -" list, list > unsuported -" 3. Rename refactor can only perform on local variables. -" 4. Register z is used when extract method. -" 5. 10 parameter supported at most. +" list, list > unsupported +" 3. Rename refactor only works on local variables. +" 4. Register z is used when extracting a method. +" 5. Functions with more than 10 parameters are not supported. " """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " BUGS: @@ -38,7 +38,7 @@ " parameter, because s:IdentifierPattern can not start with digit. " 2. (Fixed) Add word boundary to some patterns. (\<\>) " 3. (Fixed) will expand to whole expression in introducing constant. -" Thus, abc3def[>4<] will parse to 3. Fixed by iteration. +" Thus, abc3def[>4<] will parse to 3. Fixed by iteration. " 4. (Fixed) Parse error of variable defination with initialization. " 5. (Fixed) DOS EOL terminations cause the plugin to fail to load on " Linux. From 9d4f64057e2a9e26c21a83bde52c3abdab0a7fa5 Mon Sep 17 00:00:00 2001 From: Christopher Voltz Date: Fri, 18 Mar 2016 10:42:03 -0500 Subject: [PATCH 3/3] Convert tabs to spaces Convert tabs to spaces so the files will look the same in all editors irrespective of the user's editor preferences. The original files used 4 space tabs but that wasn't documented anywhere. --- README | 14 +- plugin/refactor.vim | 810 ++++++++++++++++++++++---------------------- 2 files changed, 412 insertions(+), 412 deletions(-) diff --git a/README b/README index 2c6ee47..c79d213 100644 --- a/README +++ b/README @@ -10,11 +10,11 @@ kind man who pointed this out. The refactor commands and their default key mappings are: - 1. e Extract method - 2. p local variable to Parameter - 3. r Rename local variable - 4. d Delete parameter - 5. o reOrder parameters - 6. c introduce Constant + 1. e Extract method + 2. p local variable to Parameter + 3. r Rename local variable + 4. d Delete parameter + 5. o reOrder parameters + 6. c introduce Constant -BiDongliang bidongliang_2000@126.com 2007/12/4 +BiDongliang bidongliang_2000@126.com 2007/12/4 diff --git a/plugin/refactor.vim b/plugin/refactor.vim index f1677f2..427bf8d 100644 --- a/plugin/refactor.vim +++ b/plugin/refactor.vim @@ -8,40 +8,40 @@ " regular expression matching--but, based on my testing, it works well. " " The refactor commands and their default key mappings are: -" 1. e Extract method -" 2. p local variable to Parameter -" 3. r Rename local variable -" 4. d Delete parameter -" 5. o reOrder parameters -" 6. c introduce Constant +" 1. e Extract method +" 2. p local variable to Parameter +" 3. r Rename local variable +" 4. d Delete parameter +" 5. o reOrder parameters +" 6. c introduce Constant " -" BiDongliang bidongliang_2000@126.com 2007/12/4 +" BiDongliang bidongliang_2000@126.com 2007/12/4 " """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " LIMITATIONS: -" 1. Parameters with a default value are not supported -" 2. Nested template types are limited to 3 layers, and multiple template -" parameters are not supported; but, you can enable them by modifying -" the variable s:TemplateParameterPattern. -" list supported -" list > supported -" list > > supported -" list > supported -" list, list > unsupported -" 3. Rename refactor only works on local variables. -" 4. Register z is used when extracting a method. -" 5. Functions with more than 10 parameters are not supported. +" 1. Parameters with a default value are not supported +" 2. Nested template types are limited to 3 layers, and multiple template +" parameters are not supported; but, you can enable them by modifying +" the variable s:TemplateParameterPattern. +" list supported +" list > supported +" list > > supported +" list > supported +" list, list > unsupported +" 3. Rename refactor only works on local variables. +" 4. Register z is used when extracting a method. +" 5. Functions with more than 10 parameters are not supported. " """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " BUGS: -" 1. (Fixed) Can not handle 'int a = 0' like statment in local variable to -" parameter, because s:IdentifierPattern can not start with digit. -" 2. (Fixed) Add word boundary to some patterns. (\<\>) -" 3. (Fixed) will expand to whole expression in introducing constant. -" Thus, abc3def[>4<] will parse to 3. Fixed by iteration. -" 4. (Fixed) Parse error of variable defination with initialization. -" 5. (Fixed) DOS EOL terminations cause the plugin to fail to load on -" Linux. +" 1. (Fixed) Can not handle 'int a = 0' like statment in local variable to +" parameter, because s:IdentifierPattern can not start with digit. +" 2. (Fixed) Add word boundary to some patterns. (\<\>) +" 3. (Fixed) will expand to whole expression in introducing constant. +" Thus, abc3def[>4<] will parse to 3. Fixed by iteration. +" 4. (Fixed) Parse error of variable defination with initialization. +" 5. (Fixed) DOS EOL terminations cause the plugin to fail to load on +" Linux. " """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -57,422 +57,422 @@ map c :call IntroduceConstant() let s:Keywords = ["auto", "const", "double", "float", "int", "short", "struct", "unsigned", "break", "continue", "else", "for", "long", "signed", "switch", "void", "case", "default", "enum", "goto", "register", "sizeof", "typedef", "volatile", "char", "do", "extern", "if", "return", "static", "union", "while", "asm", "dynamic_cast", "namespace", "reinterpret_cast", "try", "bool", "explicit", "new", "static_cast", "typeid", "catch", "false", "operator", "template", "typename", "class", "friend", "private", "this", "using", "const_cast", "inline", "public", "throw", "virtual", "delete", "mutable", "protected", "true", "wchar_t", "size_t"] " Patterns used to match language element -let s:IdentifierPattern = '\<\h\w*\>' -let s:TypePostfixPattern = '\s*[*&]*\s*' -let s:TypeElementPattern = s:IdentifierPattern . s:TypePostfixPattern -let s:TemplateParameterPattern = '\%(<[^<>]*>\|<[^<>]*<[^<>]*>[^<>]\+>\|<[^<>]*<[^<>]*<[^<>]*>[^<>]*>[^<>]\+>\)' "'<\s*' . s:TypeElementPattern . '\%(\s*,\s*' . s:TypeElementPattern . '\)*>' -let s:TypeIdentifierPattern = '\%(' . s:TypeElementPattern . '\%(' . s:TemplateParameterPattern . s:TypePostfixPattern . '\)*' . s:TypePostfixPattern . '\)\+' -let s:MissableSeperatorPattern = '\%(\s*\n*\s*\)' "'\s*\n*\s*' -let s:SeperatorPattern = '\%(\s\+\n*\s*\|\n\+\|\s*\n*\s\+\)' -let s:VariableDeclarationPattern = s:TypeIdentifierPattern . s:MissableSeperatorPattern . s:IdentifierPattern . '\%\(\[\d*\]\)*' -let s:FunctionPerfixPattern = '^\s*\%(' . s:TypeIdentifierPattern . s:SeperatorPattern. '\|' . s:IdentifierPattern . '::\)\+' -let s:ParameterListPattern = '(' . s:MissableSeperatorPattern . '\%(' . s:VariableDeclarationPattern . '\%(\s*,' . s:MissableSeperatorPattern . s:VariableDeclarationPattern . '\)*\)*\s*)' -let s:FunctionPattern = s:FunctionPerfixPattern . s:MissableSeperatorPattern . s:IdentifierPattern . s:MissableSeperatorPattern . s:ParameterListPattern . '[^(){;]*' -let s:FunctionDeclarationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%(;\)\@=' -let s:FunctionDefinationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%({\)\@=' +let s:IdentifierPattern = '\<\h\w*\>' +let s:TypePostfixPattern = '\s*[*&]*\s*' +let s:TypeElementPattern = s:IdentifierPattern . s:TypePostfixPattern +let s:TemplateParameterPattern = '\%(<[^<>]*>\|<[^<>]*<[^<>]*>[^<>]\+>\|<[^<>]*<[^<>]*<[^<>]*>[^<>]*>[^<>]\+>\)' "'<\s*' . s:TypeElementPattern . '\%(\s*,\s*' . s:TypeElementPattern . '\)*>' +let s:TypeIdentifierPattern = '\%(' . s:TypeElementPattern . '\%(' . s:TemplateParameterPattern . s:TypePostfixPattern . '\)*' . s:TypePostfixPattern . '\)\+' +let s:MissableSeperatorPattern = '\%(\s*\n*\s*\)' "'\s*\n*\s*' +let s:SeperatorPattern = '\%(\s\+\n*\s*\|\n\+\|\s*\n*\s\+\)' +let s:VariableDeclarationPattern = s:TypeIdentifierPattern . s:MissableSeperatorPattern . s:IdentifierPattern . '\%\(\[\d*\]\)*' +let s:FunctionPerfixPattern = '^\s*\%(' . s:TypeIdentifierPattern . s:SeperatorPattern. '\|' . s:IdentifierPattern . '::\)\+' +let s:ParameterListPattern = '(' . s:MissableSeperatorPattern . '\%(' . s:VariableDeclarationPattern . '\%(\s*,' . s:MissableSeperatorPattern . s:VariableDeclarationPattern . '\)*\)*\s*)' +let s:FunctionPattern = s:FunctionPerfixPattern . s:MissableSeperatorPattern . s:IdentifierPattern . s:MissableSeperatorPattern . s:ParameterListPattern . '[^(){;]*' +let s:FunctionDeclarationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%(;\)\@=' +let s:FunctionDefinationPattern = s:FunctionPattern . s:MissableSeperatorPattern . '\%({\)\@=' function! IntroduceConstant() - let NumberPattern = '\%(\d\+\.\?\d*\|\d*\.\d\+\)\%(f\|F\|L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?' "'\d\+\%(L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?\|\d\+\.\d\+[Ff]\?\|\.\d\+[Ff]\?' - let text = getline('.') - let position = col('.') - 1 - while strpart(text, position) =~ '^' . NumberPattern && position > 0 - let position = position - 1 - endwhile - let matched = matchstr(strpart(text, position), NumberPattern) - if matched == "" - call confirm('Can not parse a constant under cursor!') - return - endif - let constantName = inputdialog('Input the name for ' . matched . ' :') - if constantName != "" - let type = "" - if match(matched, 'ul\|UL\|uL\|Ul') >= 0 - let type = 'unsigned long' - elseif match(matched, '[Uu]') >= 0 - let type = 'unsigned int' - elseif match(matched, '[Ll]') >= 0 - let type = 'long' - elseif match(matched, '[fF]') >= 0 - let type = 'float' - elseif match(matched, '\.') >= 0 - let type = 'double' - else - let type = 'int' - endif - call GotoBeginingBracketOfCurrentFunction() - call search(matched, 'W') - exec 'normal! [{' - exec "normal! oconst " . type . " " . constantName . ' = ' . matched . ";\e" - let startLine = line('.') + 1 - let replace = confirm('Replate all ' . matched .' in this function with "' . constantName . '"?', "&Yes\n&No") - if replace == 1 - call GotoBeginingBracketOfCurrentFunction() - normal! % - let stopLine = line('.') - exec 'normal! :' . startLine . ',' . stopLine . 's/\<' . matched . '\>\%(\.\)\@!/' . constantName . "/g\r" - endif - endif + let NumberPattern = '\%(\d\+\.\?\d*\|\d*\.\d\+\)\%(f\|F\|L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?' "'\d\+\%(L\|l\|U\|u\|ul\|UL\|uL\|Ul\)\?\|\d\+\.\d\+[Ff]\?\|\.\d\+[Ff]\?' + let text = getline('.') + let position = col('.') - 1 + while strpart(text, position) =~ '^' . NumberPattern && position > 0 + let position = position - 1 + endwhile + let matched = matchstr(strpart(text, position), NumberPattern) + if matched == "" + call confirm('Can not parse a constant under cursor!') + return + endif + let constantName = inputdialog('Input the name for ' . matched . ' :') + if constantName != "" + let type = "" + if match(matched, 'ul\|UL\|uL\|Ul') >= 0 + let type = 'unsigned long' + elseif match(matched, '[Uu]') >= 0 + let type = 'unsigned int' + elseif match(matched, '[Ll]') >= 0 + let type = 'long' + elseif match(matched, '[fF]') >= 0 + let type = 'float' + elseif match(matched, '\.') >= 0 + let type = 'double' + else + let type = 'int' + endif + call GotoBeginingBracketOfCurrentFunction() + call search(matched, 'W') + exec 'normal! [{' + exec "normal! oconst " . type . " " . constantName . ' = ' . matched . ";\e" + let startLine = line('.') + 1 + let replace = confirm('Replate all ' . matched .' in this function with "' . constantName . '"?', "&Yes\n&No") + if replace == 1 + call GotoBeginingBracketOfCurrentFunction() + normal! % + let stopLine = line('.') + exec 'normal! :' . startLine . ',' . stopLine . 's/\<' . matched . '\>\%(\.\)\@!/' . constantName . "/g\r" + endif + endif endfunction function! ReorderParameters() - let originLine = line('.') - let originCol = col('.') - let parameterList = GetParameterListOfCurrentFunction() - if len(parameterList) == 1 - if parameterList[0] == 'NONE' - call confirm('There is no parameter to reorder!') - else - call confirm('Can not reorder the only parameter!') - endif - return - endif - if len(parameterList) > 0 - if len(parameterList) > 10 - call confirm('Parameter count should less than 10!') - return - endif - let text = "Parameters of current function are:" - let start = 0 - while start < len(parameterList) - let text = text . "\n" . start . ': ' . parameterList[start] - let start = start + 1 - endwhile - let text = text . "\nInput the index of parameteres in new order:" - let processed = 0 - while processed == 0 - let order = inputdialog(text) - if order != "" - if order =~ '\D' - call confirm('Just input the indexes without seperator, please!') - continue - endif - let processed = 1 - let index = 0 - while index < len(parameterList) - if stridx(order, index) < 0 - call confirm('You missed parameter ' . index) - let processed = 0 - break - endif - let index = index + 1 - endwhile - if processed == 1 - call cursor(originLine, originCol) - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - exec "normal! d/)\ri(\e" - let index = 0 - while index < strlen(order) - let current = strpart(order, index, 1) - exec "normal! a" . parameterList[current] . "\e" - if index < strlen(order) - 1 - exec "normal! a, \e" - let currentCol = col('.') - if currentCol > 80 - exec "normal! a\r\e" - endif - endif - let index = index + 1 - endwhile - endif - else - let processed = 1 - endif - endwhile - endif + let originLine = line('.') + let originCol = col('.') + let parameterList = GetParameterListOfCurrentFunction() + if len(parameterList) == 1 + if parameterList[0] == 'NONE' + call confirm('There is no parameter to reorder!') + else + call confirm('Can not reorder the only parameter!') + endif + return + endif + if len(parameterList) > 0 + if len(parameterList) > 10 + call confirm('Parameter count should less than 10!') + return + endif + let text = "Parameters of current function are:" + let start = 0 + while start < len(parameterList) + let text = text . "\n" . start . ': ' . parameterList[start] + let start = start + 1 + endwhile + let text = text . "\nInput the index of parameteres in new order:" + let processed = 0 + while processed == 0 + let order = inputdialog(text) + if order != "" + if order =~ '\D' + call confirm('Just input the indexes without seperator, please!') + continue + endif + let processed = 1 + let index = 0 + while index < len(parameterList) + if stridx(order, index) < 0 + call confirm('You missed parameter ' . index) + let processed = 0 + break + endif + let index = index + 1 + endwhile + if processed == 1 + call cursor(originLine, originCol) + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + exec "normal! d/)\ri(\e" + let index = 0 + while index < strlen(order) + let current = strpart(order, index, 1) + exec "normal! a" . parameterList[current] . "\e" + if index < strlen(order) - 1 + exec "normal! a, \e" + let currentCol = col('.') + if currentCol > 80 + exec "normal! a\r\e" + endif + endif + let index = index + 1 + endwhile + endif + else + let processed = 1 + endif + endwhile + endif endfunction function! RemoveParameter() - let parameterList = GetParameterListOfCurrentFunction() - if len(parameterList) == 1 && parameterList[0] == 'NONE' - call confirm('There is no parameter to remove!') - return - endif + let parameterList = GetParameterListOfCurrentFunction() + if len(parameterList) == 1 && parameterList[0] == 'NONE' + call confirm('There is no parameter to remove!') + return + endif - if len(parameterList) > 0 - let text = "Parameters of current function are:" - let start = 0 - while start < len(parameterList) - let text = text . "\n" . start . ': ' . parameterList[start] - let start = start + 1 - endwhile - let text = text . "\nInput the index of parameter to remove:" - let index = inputdialog(text) - if index != "" && index >= 0 && index < len(parameterList) - call search(s:FunctionPattern, 'bW') - let parameter = escape(parameterList[index], '*') - if search(parameter, 'W') > 0 - let text = getline('.') - if match(text, parameter . '\s*,') >= 0 - normal! df, - else - let startCol = match(text, ',\s*' . parameter) - let matched = matchstr(text, '\(,\s*\)*' . parameter) - if startCol >= 0 - let text = strpart(text, 0, startCol) . strpart(text, startCol + strlen(matched)) - call setline('.', text) - endif - endif - endif - endif - else - call confirm("Sorry, I can not parse the function parameter list!") - endif + if len(parameterList) > 0 + let text = "Parameters of current function are:" + let start = 0 + while start < len(parameterList) + let text = text . "\n" . start . ': ' . parameterList[start] + let start = start + 1 + endwhile + let text = text . "\nInput the index of parameter to remove:" + let index = inputdialog(text) + if index != "" && index >= 0 && index < len(parameterList) + call search(s:FunctionPattern, 'bW') + let parameter = escape(parameterList[index], '*') + if search(parameter, 'W') > 0 + let text = getline('.') + if match(text, parameter . '\s*,') >= 0 + normal! df, + else + let startCol = match(text, ',\s*' . parameter) + let matched = matchstr(text, '\(,\s*\)*' . parameter) + if startCol >= 0 + let text = strpart(text, 0, startCol) . strpart(text, startCol + strlen(matched)) + call setline('.', text) + endif + endif + endif + endif + else + call confirm("Sorry, I can not parse the function parameter list!") + endif endfunction function! RenameVariable() - let originRow = line('.') - let originCol = col('.') - let variableName = expand('') - let variableType = GetCurrentVariableType(0) - if variableType == "" - call confirm("Can not rename because ". variableName . " is not a local variable!") - return - endif - let newName = inputdialog("Input new name for ". variableName . ":") - if newName != "" - call GotoBeginingBracketOfCurrentFunction() - let startLine = line('.') - exec "normal! %" - let stopLine = line('.') - exec startLine . ',' . stopLine . ':s/\<' . variableName . '\>/'. newName .'/g' - endif - call cursor(originRow, originCol) + let originRow = line('.') + let originCol = col('.') + let variableName = expand('') + let variableType = GetCurrentVariableType(0) + if variableType == "" + call confirm("Can not rename because ". variableName . " is not a local variable!") + return + endif + let newName = inputdialog("Input new name for ". variableName . ":") + if newName != "" + call GotoBeginingBracketOfCurrentFunction() + let startLine = line('.') + exec "normal! %" + let stopLine = line('.') + exec startLine . ',' . stopLine . ':s/\<' . variableName . '\>/'. newName .'/g' + endif + call cursor(originRow, originCol) endfunction function! LocalVariableToParameter() - let variableName = expand('') - let variableType = GetCurrentVariableType(0) - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - if match(getline('.'), '(\s*)') >= 0 - call search(')') - exec "normal! i" . variableType . ' ' . variableName . "\e" - else - call search(')') - exec "normal! i, " . variableType . ' ' . variableName . "\e" - endif - call search('{') - call search('\<' . variableName . '\>') - let currentLine = getline('.') - if match(currentLine, variableType . '\s*\<' . variableName . '\>\s*;') >= 0 - call search(variableType, 'bW') - exec "normal! df;" - if match(getline('.'), '^\s*$') >= 0 - exec "normal! dd" - endif - else - if match(currentLine, '\<' . variableName . '\>\s*=') >= 0 - let variableDefination = matchstr(currentLine, '\<' . variableName . '\>\s*=\s*.\{-\}\([,;]\)\@=') - let remainStart = match(currentLine, '\<' . variableName . '\>\s*=\s*\((.*)\)*') + strlen(variableDefination) - let remain = strpart(currentLine, remainStart) - if match(remain, s:IdentifierPattern) >= 0 - call setline('.', variableType . strpart(remain, stridx(remain, ',') + 1)) - exec "normal! O" . variableDefination . ';' - exec "normal! 2==" - else - call setline('.', variableDefination . ';') - exec "normal! ==" - endif - else - if match(currentLine, '\<' . variableName . '\>\s*,') <0 - call confirm("I can not erase the variable defination, \nplease do it yourself!") - else - exec "normal! cf," - exec "normal! ==" - endif - endif - endif + let variableName = expand('') + let variableType = GetCurrentVariableType(0) + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + if match(getline('.'), '(\s*)') >= 0 + call search(')') + exec "normal! i" . variableType . ' ' . variableName . "\e" + else + call search(')') + exec "normal! i, " . variableType . ' ' . variableName . "\e" + endif + call search('{') + call search('\<' . variableName . '\>') + let currentLine = getline('.') + if match(currentLine, variableType . '\s*\<' . variableName . '\>\s*;') >= 0 + call search(variableType, 'bW') + exec "normal! df;" + if match(getline('.'), '^\s*$') >= 0 + exec "normal! dd" + endif + else + if match(currentLine, '\<' . variableName . '\>\s*=') >= 0 + let variableDefination = matchstr(currentLine, '\<' . variableName . '\>\s*=\s*.\{-\}\([,;]\)\@=') + let remainStart = match(currentLine, '\<' . variableName . '\>\s*=\s*\((.*)\)*') + strlen(variableDefination) + let remain = strpart(currentLine, remainStart) + if match(remain, s:IdentifierPattern) >= 0 + call setline('.', variableType . strpart(remain, stridx(remain, ',') + 1)) + exec "normal! O" . variableDefination . ';' + exec "normal! 2==" + else + call setline('.', variableDefination . ';') + exec "normal! ==" + endif + else + if match(currentLine, '\<' . variableName . '\>\s*,') <0 + call confirm("I can not erase the variable defination, \nplease do it yourself!") + else + exec "normal! cf," + exec "normal! ==" + endif + endif + endif endfunction function! ExtractMethod() range - let scopeIdentifier = GetScopeIdentifierOfCurrentMethod() - let variableList = [] - let varableLocalScopeType = [] - let variableParentScopeType = [] - while 1 - let variableName = MoveToNextVariable(a:lastline) - if variableName == "" - break - endif - if index(variableList, variableName) < 0 - call add(variableList, variableName) - let type = GetCurrentVariableType(0) - call add(variableParentScopeType, type) - let type = GetCurrentVariableType(a:firstline) - call add(varableLocalScopeType, type) - endif - endwhile - let methodName = inputdialog("Input the function name:") - if methodName != "" - " use register z to yank the texts - exec "normal! " . a:firstline ."G0\"zy" . a:lastline . "G" - if scopeIdentifier == "" - call GotoBeginingBracketOfCurrentFunction() - exec "normal! %" - exec "normal! 2o\ei//\e78a-\eo\eccvoid ". methodName . "(\e" - else - call GotoBeginingBracketOfCurrentFunction() - exec "normal! %" - exec "normal! 2o\ei//\e78a-\eo\eccvoid ". scopeIdentifier . "::" . methodName . "(\e" - endif - let idx = 0 - let parameterCount = 0 - while idx < len(variableList) - if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" - if parameterCount > 0 - exec "normal! a, \e" - endif - if col('.') > 80 && idx < len(variableList) - 1 - exec "normal! ==A\r\e" - endif - if variableParentScopeType[idx] =~ '\[\d*\]' - let postfix = matchstr(variableParentScopeType[idx], '\[\d*\]') - let type = strpart(variableParentScopeType[idx], 0, match(variableParentScopeType[idx], '\[\d*\]')) - exec "normal! a" . type . " " . variableList[idx] . postfix . "\e" - else - exec "normal! a" . variableParentScopeType[idx] . " " . variableList[idx] . "\e" - endif - let parameterCount = parameterCount + 1 - endif - let idx = idx + 1 - endwhile - exec "normal! a)\e==A\r{\r}\ek\"zp=']" + let scopeIdentifier = GetScopeIdentifierOfCurrentMethod() + let variableList = [] + let varableLocalScopeType = [] + let variableParentScopeType = [] + while 1 + let variableName = MoveToNextVariable(a:lastline) + if variableName == "" + break + endif + if index(variableList, variableName) < 0 + call add(variableList, variableName) + let type = GetCurrentVariableType(0) + call add(variableParentScopeType, type) + let type = GetCurrentVariableType(a:firstline) + call add(varableLocalScopeType, type) + endif + endwhile + let methodName = inputdialog("Input the function name:") + if methodName != "" + " use register z to yank the texts + exec "normal! " . a:firstline ."G0\"zy" . a:lastline . "G" + if scopeIdentifier == "" + call GotoBeginingBracketOfCurrentFunction() + exec "normal! %" + exec "normal! 2o\ei//\e78a-\eo\eccvoid ". methodName . "(\e" + else + call GotoBeginingBracketOfCurrentFunction() + exec "normal! %" + exec "normal! 2o\ei//\e78a-\eo\eccvoid ". scopeIdentifier . "::" . methodName . "(\e" + endif + let idx = 0 + let parameterCount = 0 + while idx < len(variableList) + if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" + if parameterCount > 0 + exec "normal! a, \e" + endif + if col('.') > 80 && idx < len(variableList) - 1 + exec "normal! ==A\r\e" + endif + if variableParentScopeType[idx] =~ '\[\d*\]' + let postfix = matchstr(variableParentScopeType[idx], '\[\d*\]') + let type = strpart(variableParentScopeType[idx], 0, match(variableParentScopeType[idx], '\[\d*\]')) + exec "normal! a" . type . " " . variableList[idx] . postfix . "\e" + else + exec "normal! a" . variableParentScopeType[idx] . " " . variableList[idx] . "\e" + endif + let parameterCount = parameterCount + 1 + endif + let idx = idx + 1 + endwhile + exec "normal! a)\e==A\r{\r}\ek\"zp=']" - if confirm("Replace selection with function call?", "&Yes\n&No", 1) == 1 - exec "normal! " . a:firstline ."G0c" . a:lastline . "G" - exec "normal! a" . methodName . "(" - let idx = 0 - let parameterCount = 0 - while idx < len(variableList) - if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" - if parameterCount > 0 - exec "normal! a, \e" - endif - exec "normal! a" . variableList[idx] . "\e" - let parameterCount = parameterCount + 1 - endif - let idx = idx + 1 - endwhile - exec "normal! a);\e==" - endif - endif + if confirm("Replace selection with function call?", "&Yes\n&No", 1) == 1 + exec "normal! " . a:firstline ."G0c" . a:lastline . "G" + exec "normal! a" . methodName . "(" + let idx = 0 + let parameterCount = 0 + while idx < len(variableList) + if varableLocalScopeType[idx] == "" && variableParentScopeType[idx] != "" + if parameterCount > 0 + exec "normal! a, \e" + endif + exec "normal! a" . variableList[idx] . "\e" + let parameterCount = parameterCount + 1 + endif + let idx = idx + 1 + endwhile + exec "normal! a);\e==" + endif + endif endfunction function! MoveToNextVariable(endLine) - let identifier = "" - while search('\([)]\s*\)\@ 0 - let identifier = expand('') - if index(s:Keywords, expand('')) >= 0 - let identifier = "" - continue - endif - break - endwhile - return identifier + let identifier = "" + while search('\([)]\s*\)\@ 0 + let identifier = expand('') + if index(s:Keywords, expand('')) >= 0 + let identifier = "" + continue + endif + break + endwhile + return identifier endfunction " search variable defination in current function scope function! GetCurrentVariableType(topestLine) - let variableType = "" - let startRow = line('.') - let startCol = col('.') - let variableName = expand("") - normal! e - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - let stopRow = line('.') - if a:topestLine > stopRow - let stopRow = a:topestLine - endif - call cursor(startRow, 1000) + let variableType = "" + let startRow = line('.') + let startCol = col('.') + let variableName = expand("") + normal! e + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + let stopRow = line('.') + if a:topestLine > stopRow + let stopRow = a:topestLine + endif + call cursor(startRow, 1000) - let DeclarationPattern = s:TypeIdentifierPattern . '\s*\%(' . s:IdentifierPattern . '[^()]*,\s*\)*\<' . variableName . '\>\%(\[\d*\]\)*' - while search(DeclarationPattern, "bW", stopRow) > 0 - if expand('') =~ 'return' - continue - endif - let currentLine = getline('.') - let commentStart = match(currentLine, '//') - if commentStart >= 0 && commentStart < match(currentLine, DeclarationPattern) - continue - endif - let matched = matchstr(currentLine, DeclarationPattern) - let typeend = match(matched, '\(\s*' . s:IdentifierPattern . '\s*[=,][^<>]*\)*\<'. variableName . '\>') - let variableType = strpart(matched, 0, typeend) - if matched =~ '\[\d*\]' - let postfix = matchstr(matched, '\[\d*\]') - let variableType = variableType . postfix - endif - break - endwhile - call cursor(startRow, startCol) - return variableType + let DeclarationPattern = s:TypeIdentifierPattern . '\s*\%(' . s:IdentifierPattern . '[^()]*,\s*\)*\<' . variableName . '\>\%(\[\d*\]\)*' + while search(DeclarationPattern, "bW", stopRow) > 0 + if expand('') =~ 'return' + continue + endif + let currentLine = getline('.') + let commentStart = match(currentLine, '//') + if commentStart >= 0 && commentStart < match(currentLine, DeclarationPattern) + continue + endif + let matched = matchstr(currentLine, DeclarationPattern) + let typeend = match(matched, '\(\s*' . s:IdentifierPattern . '\s*[=,][^<>]*\)*\<'. variableName . '\>') + let variableType = strpart(matched, 0, typeend) + if matched =~ '\[\d*\]' + let postfix = matchstr(matched, '\[\d*\]') + let variableType = variableType . postfix + endif + break + endwhile + call cursor(startRow, startCol) + return variableType endfunction function! GetScopeIdentifierOfCurrentMethod() - let scopeIdentifier = "" - let originRow = line('.') - let originCol = col('.') - call GotoBeginingBracketOfCurrentFunction() - exec "normal! ?(\r" - if search(s:IdentifierPattern . '::', 'bW', line('.') - 2) > 0 - let scopeIdentifier = expand('') - endif - call cursor(originRow, originCol) - return scopeIdentifier + let scopeIdentifier = "" + let originRow = line('.') + let originCol = col('.') + call GotoBeginingBracketOfCurrentFunction() + exec "normal! ?(\r" + if search(s:IdentifierPattern . '::', 'bW', line('.') - 2) > 0 + let scopeIdentifier = expand('') + endif + call cursor(originRow, originCol) + return scopeIdentifier endfunction function! GotoBeginingBracketOfCurrentFunction() - if search(s:FunctionPattern, 'bW') > 0 - if search('{', 'W') <= 0 - exec 'normal! [[' - endif - endif + if search(s:FunctionPattern, 'bW') > 0 + if search('{', 'W') <= 0 + exec 'normal! [[' + endif + endif endfunction function! GetParameterListOfCurrentFunction() - let parameterList = [] - if search(s:FunctionPattern, 'bW') > 0 - call search('(') - let startLine = line('.') - let startCol = col('.') - normal! % - let stopLine = line('.') - let stopCol = col('.') + let parameterList = [] + if search(s:FunctionPattern, 'bW') > 0 + call search('(') + let startLine = line('.') + let startCol = col('.') + normal! % + let stopLine = line('.') + let stopCol = col('.') - let closeBraceIndex = 0 - let lineIter = startLine - let text = "" - while lineIter < stopLine - let text = text . getline(lineIter) - let closeBraceIndex = closeBraceIndex + strlen(getline(lineIter)) - let lineIter = lineIter + 1 - endwhile - let text = text . getline(stopLine) - let closeBraceIndex = closeBraceIndex + stopCol + let closeBraceIndex = 0 + let lineIter = startLine + let text = "" + while lineIter < stopLine + let text = text . getline(lineIter) + let closeBraceIndex = closeBraceIndex + strlen(getline(lineIter)) + let lineIter = lineIter + 1 + endwhile + let text = text . getline(stopLine) + let closeBraceIndex = closeBraceIndex + stopCol - let emptyPair = match(text, '(\s*)') - if emptyPair >= 0 && emptyPair <= startCol + 2 - call add(parameterList, 'NONE') - return parameterList - endif + let emptyPair = match(text, '(\s*)') + if emptyPair >= 0 && emptyPair <= startCol + 2 + call add(parameterList, 'NONE') + return parameterList + endif - let start = startCol - 1 - while 1 - let parameter = matchstr(text, s:VariableDeclarationPattern, start) - let start = match(text, s:VariableDeclarationPattern, start) - let start = start + strlen(parameter) - if start >= closeBraceIndex || start < 0 - break - endif - if parameter != "" - call add(parameterList, parameter) - else - break - endif - endwhile - endif - return parameterList + let start = startCol - 1 + while 1 + let parameter = matchstr(text, s:VariableDeclarationPattern, start) + let start = match(text, s:VariableDeclarationPattern, start) + let start = start + strlen(parameter) + if start >= closeBraceIndex || start < 0 + break + endif + if parameter != "" + call add(parameterList, parameter) + else + break + endif + endwhile + endif + return parameterList endfunction