diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61ead86 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor diff --git a/README.md b/README.md index 8aa4a0d..65e0c96 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ PHP Refactoring Toolbox for VIM * Rename Method * Extract Use * Extract Const +* Extract Variable * Extract Class Property * Extract Method * Create Property @@ -79,6 +80,7 @@ let g:vim_php_refactoring_make_setter_fluent = 2 nnoremap rm :call PhpRenameMethod() nnoremap eu :call PhpExtractUse() vnoremap ec :call PhpExtractConst() + vnoremap ev :call PhpExtractVariable() nnoremap ep :call PhpExtractClassProperty() vnoremap em :call PhpExtractMethod() nnoremap np :call PhpCreateProperty() @@ -250,6 +252,41 @@ class HelloWorld { } ``` +### Extract Variable + +``` php +ev`. +You'll be prompted for a variable name. Enter a variable name and press enter + +``` php +np` will create a new property in your current class. @@ -340,3 +377,12 @@ class Foo { `da` will call your documentation plugin (by default Php Documentor for vim https://github.com/tobyS/pdv) for every uncommented classes, methods, functions and properties. +## Running tests + +``` +bin/test +``` + +### How to write tests? + +See https://github.com/junegunn/vader.vim diff --git a/bin/test b/bin/test new file mode 100755 index 0000000..7314f9e --- /dev/null +++ b/bin/test @@ -0,0 +1,31 @@ +#! /bin/sh -eu + +installVader () +{ + vaderdir='vendor/vader.vim' + vaderCommit='6fff477431ac3191c69a3a5e5f187925466e275a' + + test -d "$vaderdir" || { + { + git clone \ + --branch=master \ + --single-branch \ + https://github.com/junegunn/vader.vim.git \ + "$vaderdir" + + git \ + --work-tree="$vaderdir" \ + --git-dir="$vaderdir/.git" \ + reset --hard \ + "$vaderCommit" -- + } || { + rm -rf "$vaderdir" + + exit 1 + } + } +} + +installVader + +vim -esNu test/fixtures/vimrc -c 'Vader! test/**' diff --git a/doc/refactoring-toolbox.txt b/doc/refactoring-toolbox.txt index 38e6b03..b8db943 100755 --- a/doc/refactoring-toolbox.txt +++ b/doc/refactoring-toolbox.txt @@ -30,6 +30,7 @@ nnoremap rcv :call PhpRenameClassVariable() nnoremap rm :call PhpRenameMethod() nnoremap eu :call PhpExtractUse() vnoremap ec :call PhpExtractConst() +vnoremap ev :call PhpExtractVariable() nnoremap ep :call PhpExtractClassProperty() vnoremap em :call PhpExtractMethod() nnoremap np :call PhpCreateProperty() @@ -47,11 +48,12 @@ Examples *refactoring-to 4. Extract Use Statement........................................|extract-use-statement| 5. Extract Class Property.......................................|extract-class-property| 6. Extract Method...............................................|extract-method| -7. Create Property..............................................|create-property| -8. Detect Unused Use Statements.................................|detect-unused-use| -9. Align assignments............................................|align-assignments| -10. Create Setters and Getters..................................|create-set-get| -11. Document all................................................|document-all| +7. Extract Variable.............................................|extract-variable| +8. Create Property..............................................|create-property| +9. Detect Unused Use Statements.................................|detect-unused-use| +10. Align assignments...........................................|align-assignments| +11. Create Setters and Getters..................................|create-set-get| +12. Document all................................................|document-all| Note: ↑ Is the position of your cursor @@ -191,7 +193,39 @@ class HelloWorld { } =============================================================================== -Create Property *create-property* +Extract Variable *extract-variable* + +ev`. +You'll be prompted for a variable name. Enter a variable name and press enter + +np will create a new property in your current class. diff --git a/playground.php b/playground.php index ffa8a97..f74ca1d 100644 --- a/playground.php +++ b/playground.php @@ -63,6 +63,19 @@ public function testExtractConst() $string = 'FOOBAR'; } + /** + * Select the content you want to place in the content with the visual mode + * (you could use viw on int or va' on string) + * and then press ev to create a variable and replace every occurrences of this + * by the variable usage + */ + public function testExtractVariable() + { + if (!$obj instanceof \Fully\Qualified\Classname) { + Throw new Exception('$obj is not a \Fully\Qualified\Classname'); + } + } + /** * Place your cursor on the "localVariableWanabeAClassVariable" variable * and press ep to promote this variable as class property diff --git a/plugin/php-refactoring-toolbox.vim b/plugin/php-refactoring-toolbox.vim index 36fda35..b4f63c1 100644 --- a/plugin/php-refactoring-toolbox.vim +++ b/plugin/php-refactoring-toolbox.vim @@ -62,6 +62,7 @@ if g:vim_php_refactoring_use_default_mapping == 1 nnoremap eu :call PhpExtractUse() nnoremap rm :call PhpRenameMethod() vnoremap ec :call PhpExtractConst() + vnoremap ev :call PhpExtractVariable() nnoremap ep :call PhpExtractClassProperty() vnoremap em :call PhpExtractMethod() nnoremap np :call PhpCreateProperty() @@ -252,6 +253,88 @@ function! PhpExtractConst() " {{{ endfunction " }}} +function! PhpExtractVariable() " {{{ + if visualmode() != 'v' + call s:PhpEchoError('Extract variable only works in Visual mode, not in Visual Line or Visual block') + return + endif + + " input + let l:name = inputdialog('Name of new variable: ') + let l:defaultUpwardMove = 1 + let l:lineUpwardForAssignment = inputdialog('Line upward for assignment (default is '.l:defaultUpwardMove.'): ') + if empty(l:lineUpwardForAssignment) + let l:lineUpwardForAssignment = l:defaultUpwardMove + endif + + " go to select and copy and delete + normal! gvx + + " add marker + normal! mr + + " type variable name + exec 'normal! i$'.l:name + + " go to start on selection + normal! `r + + let l:startLine = line('.') + let l:startCol = col('.') + + " go to line to write assignment + call cursor(line('.') - l:lineUpwardForAssignment, 0) + let l:indentChars = indent(nextnonblank(line('.') + 1)) + let l:needBlankLineAfter = v:false + + " line ends with , + while ',' == trim(getline(line('.')))[-1:] + " backward one line + call cursor(line('.') - 1, 0) + endwhile + + " line ends with [ + if '[' == trim(getline(line('.')))[-1:] + " backward one line + call cursor(line('.') - 1, 0) + endif + + if empty(trim(getline(line('.')))) + let l:currentLine = line('.') + let l:currentCol = col('.') + + call cursor(nextnonblank(l:currentLine), 0) + let l:indentChars = indent(line('.')) + + call cursor(prevnonblank(l:currentLine), l:currentCol) + + let l:lineUpwardForAssignment = l:currentLine - l:startLine + endif + + if 1 == l:lineUpwardForAssignment + let l:needBlankLineAfter = v:true + endif + + " type variable assignment + let l:prefixAssign = repeat(' ', l:indentChars).'$'.l:name.' = ' + call append(line('.'), l:prefixAssign) + + " move cursor at the after the equal sign + call cursor(line('.') + 1, 0) + normal! $ + + " paste selection and add semi-colon + normal! pa; + + if l:needBlankLineAfter + call append(line('.'), '') + endif + + " go to start on selection + normal! `r +endfunction +" }}} + function! PhpExtractClassProperty() " {{{ normal! mr let l:name = substitute(expand(''), '^\$*', '', '') diff --git a/test/extract_variable/from_array_definition/first_element.vader b/test/extract_variable/from_array_definition/first_element.vader new file mode 100644 index 0000000..bdfc956 --- /dev/null +++ b/test/extract_variable/from_array_definition/first_element.vader @@ -0,0 +1,25 @@ +Given php: + 1234, + ]; + +Do: + /1234\ + viw + ;ev + baz\ + \ + +Expect: + $baz, + ]; diff --git a/test/extract_variable/from_array_definition/second_element.vader b/test/extract_variable/from_array_definition/second_element.vader new file mode 100644 index 0000000..fc7bd81 --- /dev/null +++ b/test/extract_variable/from_array_definition/second_element.vader @@ -0,0 +1,27 @@ +Given php: + 42, + 'bar' => 1234, + ]; + +Do: + /1234\ + viw + ;ev + baz\ + \ + +Expect: + 42, + 'bar' => $baz, + ]; diff --git a/test/extract_variable/from_array_definition/third_element.vader b/test/extract_variable/from_array_definition/third_element.vader new file mode 100644 index 0000000..89653e4 --- /dev/null +++ b/test/extract_variable/from_array_definition/third_element.vader @@ -0,0 +1,29 @@ +Given php: + 42, + 'foo' => 12, + 'bar' => 1234, + ]; + +Do: + /1234\ + viw + ;ev + baz\ + \ + +Expect: + 42, + 'foo' => 12, + 'bar' => $baz, + ]; diff --git a/test/extract_variable/from_array_definition/with_target_line_before_array.vader b/test/extract_variable/from_array_definition/with_target_line_before_array.vader new file mode 100644 index 0000000..5810c8d --- /dev/null +++ b/test/extract_variable/from_array_definition/with_target_line_before_array.vader @@ -0,0 +1,25 @@ +Given php: + 1234, + ]; + +Do: + /1234\ + viw + ;ev + baz\ + 3\ + +Expect: + $baz, + ]; diff --git a/test/extract_variable/from_condition/inside_function/on_top/with_open_brace_alone.vader b/test/extract_variable/from_condition/inside_function/on_top/with_open_brace_alone.vader new file mode 100644 index 0000000..4273c33 --- /dev/null +++ b/test/extract_variable/from_condition/inside_function/on_top/with_open_brace_alone.vader @@ -0,0 +1,32 @@ +Given php (condition on if and on function): + + vi( + ;ev + firstNameIsValid\ + 1\ + +Expect php (variable is extracted): + + vi( + ;ev + firstNameIsValid\ + 1\ + +Expect php (variable is extracted): + + vi( + ;ev + firstNameIsValid\ + 1\ + +Expect php (variable is extracted): + + vi( + ;ev + firstNameIsValid\ + 2\ + +Expect php (variable is extracted): + + vi( + ;ev + firstNameIsValid\ + 2\ + +Expect php (variable is extracted): + + vi( + ;ev + firstNameIsValid\ + 1\ + +Expect php (variable is extracted): + + vi( + ;ev + firstNameIsValid\ + 2\ + +Expect php (variable is extracted): + + vi( + ;ev + foo\ + \ + +Expect php (variable is extracted): + + vi( + ;ev + firstNameIsValid\ + 1\ + +Expect php (variable is extracted): + + vi( + ;ev + foo\ + 2\ + +Expect php (variable is extracted): + + vi( + ;ev + foo\ + \ + +Expect: +