Skip to content

Instantly share code, notes, and snippets.

@arnaud-lb
Last active April 17, 2018 08:16
Show Gist options
  • Save arnaud-lb/2634715564301e3edb0a50fe2bc90404 to your computer and use it in GitHub Desktop.
Save arnaud-lb/2634715564301e3edb0a50fe2bc90404 to your computer and use it in GitHub Desktop.
" ftplugin/php.vim
if !exists("*s:JumpToTest")
function s:isTestFile()
return expand("%s") =~ "/Tests/.*Test.php$"
endfunction
function s:testFile()
if s:isTestFile()
return expand("%")
else
return substitute(expand("%"), "\\(.*Bundle\\)/\\(.*\\)\\(\\.php\\)$", "\\1/Tests/\\2Test\\3", "")
endif
endfunction
function s:JumpToTest()
let file = s:testFile()
let dir = substitute(file, "/[^/]\\+$", "", "")
if !isdirectory(dir)
execute "silent! !mkdir -p ".shellescape(dir, 1)
endif
exec ":edit " . file
endfunction
function s:JumpToImpl()
let file = substitute(expand("%"), "\\(.*Bundle\\)/Tests/\\(.*\\)Test\\(\\.php\\)$", "\\1/\\2\\3", "")
exec ":edit " . file
endfunction
function s:ToggleJumpToTest()
if s:isTestFile()
call s:JumpToImpl()
else
call s:JumpToTest()
endif
endfunction
function s:RunTest()
let file = s:testFile()
call neoterm#do("./run-tests.sh " . shellescape(file, 1))
endfunction
function s:AddProperty()
let name = expand("<cword>")
return s:addPropertyName(name, '')
endfunction
function s:addPropertyName(name, type)
normal G
let addBlankLine = 'top'
if search('\(private\|protected\|public\)\s\+\$', 'b') == 0
if search('^\s*\%(/\*.*\*/\s*\)\?\%(\%(abstract\|final\)\_s\+\)*\%(class\|interface\|trait\)', 'b') == 0
throw "Can not find where to insert the property (no class or property found)"
endif
if search('{') == 0
throw "Can not find { after class keyword"
end
let addBlankLine = 'bottom'
endif
if addBlankLine == 'bottom'
call append(line("."), "")
endif
call append(line("."), " private $".a:name.";")
if a:type isnot ''
call append(line("."), " /** @var " . a:type . " */")
endif
if addBlankLine == 'top'
call append(line("."), "")
endif
" move cursor to property name
normal j2w
endfunction
function s:moveToConstructorInsertPosition()
normal G
if search('\(private\|protected\|public\)\s\+\$', 'b') > 0
call append(line("."), "")
normal j
return
endif
if search('^\s*\%(/\*.*\*/\s*\)\?\%(\%(abstract\|final\)\_s\+\)*\%(class\|interface\|trait\)\_.\{-}{', 'be') == 0
throw "Can not find class declaraction"
else
return
endif
endfunction
" Moves to constructor, or create one
" Leaves the cursor on the last char of '__construct'
function s:moveToConstructorOrCreateOne()
if search('function\s\+__construct\>', 'e') > 0
return
endif
call s:moveToConstructorInsertPosition()
call append(line('.'), [" public function __construct()", " {", " }", ""])
call search('function\s\+__construct', 'we')
endfunction
function s:AddDependency()
normal mz
let decl = input("Please enter argument declaration:\nExample: \"Foobar \$foo\" or just \"\$bar\n\n")
let l = matchlist(decl, '^\(\([\\A-Za-z0-9_]\+\)\s\+\)\?\$\(\w\+\)')
if len(l) == 0
throw "Invalid argument declaration: " . decl
endif
let type = l[2]
let name = l[3]
call s:addConstructorArgument(name, decl)
call s:addPropertyName(name, type)
normal 'z
endfunction
" Add argument 'decl' to function under the cursor
" Cursor must be on function name
function s:addFunctionArgument(decl)
normal f(
if search('\%#(\s*)') > 0
substitute /(\s*)/\="(".a:decl.")"/
normal t)
elseif search('\%#(.*)') > 0
substitute /)/\=", ".a:decl.")"/
normal t)
elseif search('\%#(\_.\{-})', 'e') > 0
normal k
substitute /\([^,]\)$/\1,/e
call append(line('.'), a:decl)
normal j==
normal $
else
throw "Can not find where to insert argument"
endif
if search('\w\+ \$\w\+\%#', 'b') > 0
call PhpInsertUse()
endif
endfunction
function s:addConstructorArgument(name, decl)
call s:moveToConstructorOrCreateOne()
call s:addFunctionArgument(a:decl)
if search('\_.\{-}{', 'e') == 0
throw "Can not find { after constructor signature"
endif
normal %
call append(line('.')-1, '$this->' . a:name . ' = $' . a:name . ';')
normal k==
endfunction
function s:BreakSignature()
substitute /\(\(?\?[a-zA-Z0-9_\\]\+ \)\?\$[a-zA-Z0-9_\\]\+[,)]\)\s*/\r\1/g
substitute /)\_s*\(:[a-zA-Z0-9_\\]\+\)\?\_s*{/\r)\1 {/
normal! v%=
endfunction
endif
command! JumpToTest call s:JumpToTest()
command! JumpToImpl call s:JumpToImpl()
command! ToggleJumpToTest call s:ToggleJumpToTest()
command! BreakSignature call s:BreakSignature()
command! RunTest call s:RunTest()
command! AddProperty call s:AddProperty()
command! AddDependency call s:AddDependency()
nmap <buffer><leader>t :ToggleJumpToTest<CR>
nmap <buffer><leader>r :RunTest<CR>
nmap <buffer><leader>ad :AddDependency<CR>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment