Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updated ruby-refactoring.vim

  • Loading branch information...
commit 95bd700f9d4f86bc5f328ad5ab896841034d1379 1 parent dfe5177
@arthurgeek authored
View
5 autoload/common.vim
@@ -39,6 +39,11 @@ function! common#get_range_for_block(pattern_start, flags)
let cursor_position = getpos(".")
let block_start = search(a:pattern_start, a:flags)
+
+ if (match(getline("."), "^\\s*it\\s\\+") == 0)
+ normal $
+ endif
+
normal %
let block_end = line(".")
View
5 doc/rubyrefactoring.txt
@@ -56,6 +56,11 @@ Default bindings:
:vnoremap <leader>rriv :RRenameInstanceVariable<cr>
:vnoremap <leader>rem :RExtractMethod<cr>
+Disable default bindings with:
+>
+ let g:ruby_refactoring_map_keys=0
+<
+
ADDITIONAL USAGE EXAMPLES *rubyrefactoring-usageexamples*
http://justinram.wordpress.com/2010/12/30/vim-ruby-refactoring-series/
View
71 plugin/refactorings/general/extractmethod.vim
@@ -9,7 +9,7 @@ function! ExtractMethod() range
return
endtry
- let [block_start, block_end] = common#get_range_for_block('\<def\>','Wb')
+ let [block_start, block_end] = common#get_range_for_block('\<def\|it\>','Wb')
let pre_selection = join( getline(block_start+1,a:firstline-1), "\n" )
let pre_selection_variables = s:ruby_determine_variables(pre_selection)
@@ -28,13 +28,58 @@ function! ExtractMethod() range
call insert(parameters,var)
endfor
+ let parameters = s:sort_parameters_by_declaration(parameters)
+
for var in selection_variables[0]
if index(post_selection_variables[1], var) != -1
call insert(retvals, var)
endif
endfor
- call s:em_insert_new_method(name, selection, parameters, retvals, block_start)
+ call s:em_insert_new_method(name, selection, parameters, retvals, block_end)
+endfunction
+
+function! s:sort_parameters_by_declaration(parameters)
+ if (len(a:parameters) <= 1)
+ return a:parameters
+ endif
+ let pairs = s:build_parameter_declaration_position_pairs(a:parameters)
+ call sort(pairs, "s:sort_parameter_declaration_position_pairs")
+ return s:parameter_names_of(pairs)
+endfunction
+
+function! s:build_parameter_declaration_position_pairs(parameters)
+ let cursor_position = getpos(".")
+ let pairs = []
+
+ for parm in a:parameters
+ if (searchdecl(parm) == 0) " could find and position cursor at parameter declaration
+ call insert(pairs, [parm, getpos(".")])
+ else
+ call insert(pairs, [parm, getpos("$")]) " use end of file to sink to bottom
+ endif
+ call setpos(".",cursor_position)
+ endfor
+
+ return pairs
+endfunction
+
+function! s:sort_parameter_declaration_position_pairs(pair1, pair2)
+ let lineIndex = 1
+ let colIndex = 2
+ if (a:pair1[1][lineIndex] == a:pair2[1][lineIndex])
+ return a:pair1[1][colIndex] - a:pair2[1][colIndex]
+ else
+ return a:pair1[1][lineIndex] - a:pair2[1][lineIndex]
+ endif
+endfunction
+
+function! s:parameter_names_of(pairs)
+ let sorted_parameters = []
+ for pair in a:pairs
+ call extend(sorted_parameters, [pair[0]])
+ endfor
+ return sorted_parameters
endfunction
function! s:ruby_determine_variables(block)
@@ -175,7 +220,7 @@ function! s:ruby_identify_variables( tuples )
if tuple[0] == "ASSIGN"
let assigned = deepcopy(referenced)
let referenced = []
- elseif tuple[0] == "VAR"
+ elseif tuple[0] == "VAR" && !s:is_target_of_rspec_let(tuple[1])
call add(referenced,tuple[1])
endif
endfor
@@ -183,16 +228,20 @@ function! s:ruby_identify_variables( tuples )
return [assigned, referenced]
endfunction
+function! s:is_target_of_rspec_let(name)
+ return search('^\s*let\s*[(]\s*[:]' . a:name . '\s*[)]', 'Wbn') > 0
+endfunction
+
" Synopsis:
" Do the vim bit of creating the new method, and the call to it.
-function! s:em_insert_new_method(name, selection, parameters, retvals, block_start)
+function! s:em_insert_new_method(name, selection, parameters, retvals, block_end)
" Remove last \n if it exists, as we're adding one on prior to the 'end'
let has_trailing_newline = strridx(a:selection,"\n") == (strlen(a:selection) - 1) ? 1 : 0
" Build new method text, split into a list for easy insertion
let method_params = ""
if len(a:parameters) > 0
- let method_params = "(" . join(a:parameters, ",") . ")"
+ let method_params = "(" . join(a:parameters, ", ") . ")"
endif
let method_retvals = ""
@@ -200,15 +249,9 @@ function! s:em_insert_new_method(name, selection, parameters, retvals, block_sta
let method_retvals = join(a:retvals,", ")
endif
- let method_lines = split("def " . a:name . method_params . "\n" . a:selection . (has_trailing_newline ? "" : "\n") . (len(a:retvals) > 0 ? "return " . method_retvals . "\n" : "") . "end\n", "\n", 1)
+ let method_lines = split( "\ndef " . a:name . method_params . "\n" . a:selection . (has_trailing_newline ? "" : "\n") . (len(a:retvals) > 0 ? "return " . method_retvals . "\n" : "") . "end", "\n", 1)
- " Start a line above, as we're appending, not inserting
- let start_line_number = a:block_start - 1
-
- " Sanity check
- if start_line_number < 0
- let start_line_number = 0
- endif
+ let start_line_number = a:block_end - len(split(a:selection, "\n", 1)) + 1
" Insert new method
call append(start_line_number, method_lines)
@@ -228,7 +271,7 @@ function! s:em_insert_new_method(name, selection, parameters, retvals, block_sta
normal V=
" Indent new codeblock
- exec "normal " . start_line_number . "GV" . len(method_lines) . "j="
+ exec "normal " . (start_line_number+1) . "GV" . len(method_lines) . "j="
" Jump back again,
call setpos(".", cursor_position)
View
16 plugin/refactorings/general/extractvariable.vim
@@ -7,16 +7,26 @@ function! ExtractLocalVariable()
echo v:exception
return
endtry
- " Enter visual mode (not sure why this is needed since we're already in
- " visual mode anyway)
- normal! gv
+
+ call s:select_variable_contents()
" Replace selected text with the variable name
exec "normal c" . name
+
" Define the variable on the line above
exec "normal! O" . name . " = "
+
" Paste the original selected text to be the variable value
normal! $p
endfunction
+function! s:select_variable_contents()
+ " select current word or re-establish selection
+ " (not sure why we need to re-select)
+ if (visualmode() == "")
+ normal! viw
+ else
+ normal! gv
+ endif
+endfunction
View
2  plugin/refactorings/general/inlinetemp.vim
@@ -22,7 +22,7 @@ function! InlineTemp()
" Find the start and end of the current block
" TODO: tidy up if no matching 'def' found (start would be 0 atm)
- let [block_start, block_end] = common#get_range_for_block('\<def\>','Wb')
+ let [block_start, block_end] = common#get_range_for_block('\<def\|it\>','Wb')
" Rename the variable within the range of the block
call common#gsub_all_in_range(current_line, block_end, '\<' . @a . '\>', @b)
View
31 plugin/refactorings/general/introducevariable.vim
@@ -0,0 +1,31 @@
+"Synopsis:
+" Introduce variable from class or method name
+function! IntroduceVariable()
+ let original_a = @a
+
+ normal ^
+
+ call search('\.*(\|{\|\n', 'p')
+ normal hh"ayiw
+
+ let line = @a
+
+ if line == "new"
+ normal ^"ayiw
+ let line = @a
+ endif
+
+ let @a = original_a
+ let var = s:snakecase(line)
+ exec "normal I" . var . " = "
+
+endfunction
+
+function! s:snakecase(word)
+ let word = substitute(a:word,'::','/','g')
+ let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g')
+ let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g')
+ let word = substitute(word,'-','_','g')
+ let word = tolower(word)
+ return word
+endfunction
View
69 plugin/refactorings/general/postconditional.vim
@@ -13,27 +13,58 @@ function! ConvertPostConditional()
" if the first match isn't on the current line, exit.
if current_line != first_match
+ "echo "no match"
return
endif
- " move the cursor to the first found conditional operator
+ " move the cursor *backward* to the first found conditional operator
call search(conditional_operators, 'bW')
- " save original value of buffer a into temp variable
- let original_value = @a
- " delete to the end of the line into buffer a
- normal "ad$
- " insert new line above
- normal O
- " and paste buffer a
- normal "ap
- " indent conditional properly
- normal ==
- " restore original value back to register a
- let @a = original_value
- " move one line down and add 'end'
- exec "normal jo" . "end"
- " move back to the line that you started at
- normal k
- " indent the conditional body
- normal >>
+ let conditional_pos = col(".")
+
+ " move the cursor to the first word char on the line
+ normal ^
+ let line_start_pos = col(".")
+
+ " move the cursor *forward* to the first found conditional operator
+ call search(conditional_operators, 'cW')
+
+ " if conditional starts line (pre-conditional), convert *to* post-conditional
+ let is_pre_conditional = line_start_pos == conditional_pos
+ if is_pre_conditional
+ " convert to post-conditional (e.g. do_stuff() if condition)
+
+ " assert conditional statement takes exactly three lines
+ let first_line = line('.')
+ let last_line = search('^\s*end\s*$', 'nW')
+ let is_three_lines = (last_line - first_line) == 2
+ if is_three_lines
+ " delete third line, cut first, paste after second, join, indent properly
+ normal jjddkkddpkJ==
+ else
+ "echo "multi-line conditional contains 2+ statements, aborting"
+ endif
+ else
+ " convert to pre-conditional (e.g. if condition \n do_stuff() \n end)
+
+ " save original value of buffer a into temp variable
+ let original_value = @a
+ " delete to the end of the line into buffer a
+ normal "ad$
+ " insert new line above
+ normal O
+ " and paste buffer a
+ normal "ap
+ " indent conditional properly
+ normal ==
+ " restore original value back to register a
+ let @a = original_value
+ " move one line down and add 'end'
+ exec "normal jo" . "end"
+ " move back to the line that you started at
+ normal k
+ " indent the conditional body
+ normal >>
+ " remove trailing whitespace from paste operation
+ s/\s*$//g
+ endif
endfunction
View
4 plugin/refactorings/general/rspec_extractlet.vim
@@ -7,8 +7,8 @@ function! ExtractIntoRspecLet()
echo "Can't find an assignment"
return
end
- normal! "bdd
- exec "?^\\<describe\\|context\\>"
+ normal! dd
+ exec "?^\\s*\\<\\(describe\\|context\\)\\>"
normal! $p
exec 's/\v([a-z_][a-zA-Z0-9_]*) \= (.+)/let(:\1) { \2 }'
normal V=
View
32 plugin/ruby-refactoring.vim
@@ -10,6 +10,7 @@
" Contributions from Stuart Gale (@bishboria)
"
" Some support functions borrowed from Luc Hermitte's lh-vim library
+" Also borrowed snake case function from tim popes vim-abloish plugin
" Load all refactoring recipes
exec 'runtime ' . expand('<sfile>:p:h') . '/refactorings/general/*.vim'
@@ -24,6 +25,7 @@ command! RAddParameterNB call AddParameterNB()
command! RInlineTemp call InlineTemp()
command! RExtractLet call ExtractIntoRspecLet()
command! RConvertPostConditional call ConvertPostConditional()
+command! RIntroduceVariable call IntroduceVariable()
command! -range RExtractConstant call ExtractConstant()
command! -range RExtractLocalVariable call ExtractLocalVariable()
@@ -36,15 +38,21 @@ command! -range RExtractMethod call ExtractMethod()
" Default mappings are <leader>r followed by an acronym of the pattern's name
" E.g. Extract Method is mapped to <leader>rem
-nnoremap <leader>rap :RAddParameter<cr>
-nnoremap <leader>rapn :RAddParameterNB<cr>
-nnoremap <leader>rit :RInlineTemp<cr>
-nnoremap <leader>rel :RExtractLet<cr>
-nnoremap <leader>rcpc :RConvertPostConditional<cr>
-
-vnoremap <leader>rec :RExtractConstant<cr>
-vnoremap <leader>relv :RExtractLocalVariable<cr>
-vnoremap <leader>rrlv :RRenameLocalVariable<cr>
-vnoremap <leader>rriv :RRenameInstanceVariable<cr>
-vnoremap <leader>rem :RExtractMethod<cr>
-
+if !exists('g:ruby_refactoring_map_keys')
+ let g:ruby_refactoring_map_keys = 1
+endif
+
+if g:ruby_refactoring_map_keys
+ nnoremap <leader>rap :RAddParameter<cr>
+ nnoremap <leader>rapn :RAddParameterNB<cr>
+ nnoremap <leader>rit :RInlineTemp<cr>
+ nnoremap <leader>rel :RExtractLet<cr>
+ nnoremap <leader>rcpc :RConvertPostConditional<cr>
+ nnoremap <leader>riv :RIntroduceVariable<cr>
+
+ vnoremap <leader>rec :RExtractConstant<cr>
+ vnoremap <leader>relv :RExtractLocalVariable<cr>
+ vnoremap <leader>rrlv :RRenameLocalVariable<cr>
+ vnoremap <leader>rriv :RRenameInstanceVariable<cr>
+ vnoremap <leader>rem :RExtractMethod<cr>
+endif
Please sign in to comment.
Something went wrong with that request. Please try again.