Merge pull request #23 from elythyr/improvement-hooks

improvement: hooks & PHP open brace handling for methods
This commit is contained in:
Alex Yatskov 2020-06-26 20:05:22 -07:00 committed by GitHub
commit 878e9c872d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 247 additions and 17 deletions

View File

@ -219,30 +219,32 @@ function! argwrap#unwrapContainer(range, container, arguments, padded)
exec printf('silent %d,%dd_', a:range.lineStart + 1, a:range.lineEnd)
endfunction
function! argwrap#getSetting(name, default)
function! argwrap#getSetting(name)
let l:bName = 'b:argwrap_' . a:name
let l:gName = 'g:argwrap_' . a:name
if exists(l:bName)
return {l:bName}
elseif exists(l:gName)
return {l:gName}
else
return a:default
return exists(l:bName) ? {l:bName} : {l:gName}
endfunction
function! argwrap#initSetting(name, value) abort
let l:setting = 'g:argwrap_'.a:name
if !exists(l:setting)
let {l:setting} = a:value
endif
endfunction
function! argwrap#toggle()
let l:cursor = getpos('.')
let l:linePrefix = argwrap#getSetting('line_prefix', '')
let l:padded = argwrap#getSetting('padded_braces', '')
let l:tailComma = argwrap#getSetting('tail_comma', 0)
let l:tailCommaBraces = argwrap#getSetting('tail_comma_braces', '')
let l:tailIndentBraces = argwrap#getSetting('tail_indent_braces', '')
let l:wrapBrace = argwrap#getSetting('wrap_closing_brace', 1)
let l:commaFirst = argwrap#getSetting('comma_first', 0)
let l:commaFirstIndent = argwrap#getSetting('comma_first_indent', 0)
let l:linePrefix = argwrap#getSetting('line_prefix')
let l:padded = argwrap#getSetting('padded_braces')
let l:tailComma = argwrap#getSetting('tail_comma')
let l:tailCommaBraces = argwrap#getSetting('tail_comma_braces')
let l:tailIndentBraces = argwrap#getSetting('tail_indent_braces')
let l:wrapBrace = argwrap#getSetting('wrap_closing_brace')
let l:commaFirst = argwrap#getSetting('comma_first')
let l:commaFirstIndent = argwrap#getSetting('comma_first_indent')
let l:range = argwrap#findClosestRange()
if !argwrap#validateRange(l:range)
@ -257,11 +259,19 @@ function! argwrap#toggle()
let l:container = argwrap#extractContainer(l:range)
if l:range.lineStart == l:range.lineEnd
call argwrap#hooks#execute('pre_wrap', l:range, l:container, l:arguments)
call argwrap#wrapContainer(l:range, l:container, l:arguments, l:wrapBrace, l:tailComma, l:tailCommaBraces, l:tailIndentBraces, l:linePrefix, l:commaFirst, l:commaFirstIndent)
let l:cursor[1] = l:range.lineStart + 1
call argwrap#hooks#execute('post_wrap', l:range, l:container, l:arguments)
else
call argwrap#hooks#execute('pre_unwrap', l:range, l:container, l:arguments)
call argwrap#unwrapContainer(l:range, l:container, l:arguments, l:padded)
let l:cursor[1] = l:range.lineStart
call argwrap#hooks#execute('post_unwrap', l:range, l:container, l:arguments)
endif
call setpos('.', l:cursor)

View File

@ -0,0 +1,53 @@
function! s:loadGlobalHooks() abort " {{{
if !exists('g:argwrap_global_hooks')
let g:argwrap_global_hooks = []
for hook in globpath(&runtimepath, 'autoload/argwrap/hooks/*.vim', 0, 1)
let l:filename = matchstr(hook, '\vhooks/\zs.+\ze\.vim$')
call add(g:argwrap_global_hooks, printf('argwrap#hooks#%s', l:filename))
endfor
endif
return g:argwrap_global_hooks
endfunction " }}}
function! s:loadFiletypeHooks(filetype) abort " {{{
if !exists('g:argwrap_filetype_hooks.'.a:filetype)
let g:argwrap_filetype_hooks[a:filetype] = []
let l:hooks = g:argwrap_filetype_hooks[a:filetype]
for filetypeHook in globpath(&runtimepath, 'autoload/argwrap/hooks/filetype/*/*.vim', 0, 1)
let l:filetype = matchstr(filetypeHook, '\vhooks/filetype/\zs.+\ze/.+\.vim$')
let l:filename = matchstr(filetypeHook, '\vhooks/filetype/.+/\zs.+\ze\.vim$')
call add(l:hooks, printf('argwrap#hooks#filetype#%s#%s', l:filetype, l:filename))
endfor
endif
return g:argwrap_filetype_hooks[a:filetype]
endfunction " }}}
function! s:load() abort " {{{
if !exists('b:argwrap_hooks')
let b:argwrap_hooks = s:loadGlobalHooks() + s:loadFiletypeHooks(&filetype)
endif
return b:argwrap_hooks
endfunction " }}}
function! argwrap#hooks#execute(name, ...) abort " {{{
" Reverse the order of the hooks for post hooks so that a pre hook with a
" low priority is executed before and a post hook is executed after
" For instance for a hook responsible to preserve the cursor position it
" must be the first to be executed to save the position of the cursor but
" the last to be executed to restore it after all other hooks have been
" executed
let l:hooks = a:name =~? '\v^post' ? reverse(copy(s:load())) : s:load()
for hook in l:hooks
silent! call call(printf('%s#%s', hook, a:name), a:000)
endfor
endfunction " }}}
" vim: ts=2 sw=2 et fdm=marker

View File

@ -0,0 +1,66 @@
function! s:dealWithMethodArguments(container) abort " {{{
if a:container.suffix !~ '\v^\)'
return 0
endif
if a:container.prefix !~? '\v^%(public|protected|private)\s+function\s+\S+\s*\($'
return 0
endif
return 1
endfunction " }}}
function! s:fixMethodOpeningBraceAfterWrap(range, container, arguments) abort " {{{
if !s:dealWithMethodArguments(a:container)
return
endif
let l:lineEnd = a:range.lineEnd + len(a:arguments)
" Add 1 more line if the brace is also wrapped
if 0 != argwrap#getSetting('wrap_closing_brace')
let l:lineEnd += 1
endif
if getline(l:lineEnd + 1) =~ '\v^\s*\{'
execute printf('undojoin | normal! %dGJ', l:lineEnd)
endif
endfunction " }}}
function! s:fixMethodOpeningBraceAfterUnwrap(range, container, arguments) abort " {{{
if !s:dealWithMethodArguments(a:container)
return
endif
if a:container.suffix !~ '\v^\).*\{\s*$'
return
endif
execute printf("undojoin | normal! %dG$F{i\<CR>", a:range.lineStart)
endfunction " }}}
function! argwrap#hooks#filetype#php#200_smart_brace#pre_wrap(range, container, arguments) abort " {{{
" Do nothing but prevent the file to be loaded more than once
" When calling an autoload function that is not define the script that
" should contain it is sourced every time the function is called
endfunction " }}}
function! argwrap#hooks#filetype#php#200_smart_brace#pre_unwrap(range, container, arguments) abort " {{{
" Do nothing but prevent the file to be loaded more than once
" When calling an autoload function that is not define the script that
" should contain it is sourced every time the function is called
endfunction " }}}
function! argwrap#hooks#filetype#php#200_smart_brace#post_wrap(range, container, arguments) abort " {{{
if argwrap#getSetting('php_smart_brace')
call s:fixMethodOpeningBraceAfterWrap(a:range, a:container, a:arguments)
endif
endfunction " }}}
function! argwrap#hooks#filetype#php#200_smart_brace#post_unwrap(range, container, arguments) abort " {{{
if argwrap#getSetting('php_smart_brace')
call s:fixMethodOpeningBraceAfterUnwrap(a:range, a:container, a:arguments)
endif
endfunction " }}}
" vim: ts=2 sw=2 et fdm=marker

View File

@ -6,8 +6,9 @@ CONTENTS
1. ArgWrap...............................................................................................|argwrap-argwrap|
1.1. Installation...............................................................................|argwrap-installation|
1.2. Configuration.............................................................................|argwrap-configuration|
1.3. Usage.............................................................................................|argwrap-usage|
1.4. License.........................................................................................|argwrap-license|
1.3. Hooks.............................................................................................|argwrap-hooks|
1.4. Usage.............................................................................................|argwrap-usage|
1.5. License.........................................................................................|argwrap-license|
========================================================================================================================
ARGWRAP *argwrap-argwrap*
@ -179,7 +180,96 @@ file basis using `ftplugin` or `autocmd`. For example, the `argwrap_tail_comma`
, wubble
)
<
* argwrap_php_smart_brace
Specifies if the opening brace of PHP methods should be wrap/unwrap as well.
PHP smart brace disabled (default)
>
public function foo(
int $x,
int $y
)
{
<
PHP smart brace enabled ()
>
public function foo(
int $x,
int $y
) {
<
------------------------------------------------------------------------------------------------------------------------
HOOKS *argwrap-hooks*
It is possible to hook before or after a wrap/unwrap operation using
autoloaded functions, the hooks are named:
- `pre_wrap`
- `pre_unwrap`
- `post_wrap`
- `post_unwrap`
For example to do something after any wrap create a function: >
argwrap#hooks#my_hook#post_wrap(range, container, arguments)
<
It is also possible to create a hook for a specific filetype: >
argwrap#hooks#filetype#vim#my_hook#post_wrap(range, container, arguments)
<
Global hooks are loaded on the first time a wrap/unwrap operation is done.
Filetype hooks however are only loaded for the current filetype.
You can see the list of loaded hooks with: >
echo g:argwrap_global_hooks
echo g:argwrap_filetype_hooks
echo b:argwrap_hooks
<
The hooks are loaded from any directory specified in the |runtimepath|.
Global hooks will be executed before filetype ones.
Global and filetype hooks are sorted by the |globpath()| function. Meaning you
can control the execution order of the hooks by prefixing them with a
priority.
Post hooks order is reversed in order to keep the execution order logical.
For example if there two hooks named `000_cursor` and `200_anything` , the
cursor hook being responsible to preserve the cursor position it must be
executed first to ensure no modification of the cursor position has been done
yet so it receive the lowest priority.
The execution stack for a wrap operation would then be:
- `000_cursor#pre_wrap`
- `000_anything#pre_wrap`
- `wrap operation`
- `000_anything#post_wrap`
- `000_cursor#post_wrap`
An important things to know when writing a new hook is that calling an
|autoload| function which does not exist will source the file that should
contain the function every time.
So even if you do not need one of the hook, always define them all. This is a
template you can use to get started: >
function! argwrap#hooks#my_hook#pre_wrap(range, container, arguments) abort " {{{
" Do nothing but prevent the file to be loaded more than once
" When calling an autoload function that is not define the script that
" should contain it is sourced every time the function is called
endfunction " }}}
function! argwrap#hooks#my_hook#pre_unwrap(range, container, arguments) abort " {{{
" Do nothing but prevent the file to be loaded more than once
" When calling an autoload function that is not define the script that
" should contain it is sourced every time the function is called
endfunction " }}}
function! argwrap#hooks#my_hook#post_wrap(range, container, arguments) abort " {{{
" Do nothing but prevent the file to be loaded more than once
" When calling an autoload function that is not define the script that
" should contain it is sourced every time the function is called
endfunction " }}}
function! argwrap#hooks#my_hook#post_unwrap(range, container, arguments) abort " {{{
" Do nothing but prevent the file to be loaded more than once
" When calling an autoload function that is not define the script that
" should contain it is sourced every time the function is called
endfunction " }}}
<
------------------------------------------------------------------------------------------------------------------------
USAGE *argwrap-usage*
@ -207,3 +297,4 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vim:tw=78:sw=4:ft=help:norl:

View File

@ -17,6 +17,16 @@
" IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
" CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
call argwrap#initSetting('line_prefix', '')
call argwrap#initSetting('padded_braces', '')
call argwrap#initSetting('tail_comma', 0)
call argwrap#initSetting('tail_comma_braces', '')
call argwrap#initSetting('tail_indent_braces', '')
call argwrap#initSetting('wrap_closing_brace', 1)
call argwrap#initSetting('comma_first', 0)
call argwrap#initSetting('comma_first_indent', 0)
call argwrap#initSetting('filetype_hooks', {})
call argwrap#initSetting('php_smart_brace', 0)
command! ArgWrap call argwrap#toggle()