improvement: generalize the hook system

It is still not possible to override an existing hook but with this
system users can create new hooks really simply without having to update
any configuration since they will be autodetected.

The only missing thins is the possibility to disable hook, therefore it
is the responsibility of each hook to provide a way to the user to use
it or not.
This commit is contained in:
Camille Dejoye 2020-06-07 15:26:06 +02:00
parent 18621cafcb
commit 0fc75c596c
5 changed files with 140 additions and 16 deletions

View File

@ -257,15 +257,19 @@ function! argwrap#toggle()
let l:container = argwrap#extractContainer(l:range) let l:container = argwrap#extractContainer(l:range)
if l:range.lineStart == l:range.lineEnd 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) 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 let l:cursor[1] = l:range.lineStart + 1
silent! call argwrap#hooks#{&filetype}#post_wrap(l:range, l:container, l:arguments) call argwrap#hooks#execute('post_wrap', l:range, l:container, l:arguments)
else else
call argwrap#hooks#execute('pre_unwrap', l:range, l:container, l:arguments)
call argwrap#unwrapContainer(l:range, l:container, l:arguments, l:padded) call argwrap#unwrapContainer(l:range, l:container, l:arguments, l:padded)
let l:cursor[1] = l:range.lineStart let l:cursor[1] = l:range.lineStart
silent! call argwrap#hooks#{&filetype}#post_unwrap(l:range, l:container, l:arguments) call argwrap#hooks#execute('post_unwrap', l:range, l:container, l:arguments)
endif endif
call setpos('.', l:cursor) call setpos('.', l:cursor)

View File

@ -0,0 +1,45 @@
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 " {{{
for hook in s:load()
silent! call call(printf('%s#%s', hook, a:name), a:000)
endfor
endfunction " }}}
" vim: ts=2 sw=2 et fdm=marker

View File

@ -10,18 +10,6 @@ function! s:dealWithMethodArguments(container) abort " {{{
return 1 return 1
endfunction " }}} endfunction " }}}
function! argwrap#hooks#php#post_wrap(range, container, arguments) abort " {{{
if argwrap#getSetting('php_smart_brace', 0)
call s:fixMethodOpeningBraceAfterWrap(a:range, a:container, a:arguments)
endif
endfunction " }}}
function! argwrap#hooks#php#post_unwrap(range, container, arguments) abort " {{{
if argwrap#getSetting('php_smart_brace', 0)
call s:fixMethodOpeningBraceAfterUnwrap(a:range, a:container, a:arguments)
endif
endfunction " }}}
function! s:fixMethodOpeningBraceAfterWrap(range, container, arguments) abort " {{{ function! s:fixMethodOpeningBraceAfterWrap(range, container, arguments) abort " {{{
if !s:dealWithMethodArguments(a:container) if !s:dealWithMethodArguments(a:container)
return return
@ -57,4 +45,28 @@ function! s:fixMethodOpeningBraceAfterUnwrap(range, container, arguments) abort
execute printf("undojoin | normal! %dG0%dlct{\<CR>", a:range.lineStart, l:col) execute printf("undojoin | normal! %dG0%dlct{\<CR>", a:range.lineStart, l:col)
endfunction " }}} 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', 0)
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', 0)
call s:fixMethodOpeningBraceAfterUnwrap(a:range, a:container, a:arguments)
endif
endfunction " }}}
" vim: ts=2 sw=2 et fdm=marker " vim: ts=2 sw=2 et fdm=marker

View File

@ -6,8 +6,9 @@ CONTENTS
1. ArgWrap...............................................................................................|argwrap-argwrap| 1. ArgWrap...............................................................................................|argwrap-argwrap|
1.1. Installation...............................................................................|argwrap-installation| 1.1. Installation...............................................................................|argwrap-installation|
1.2. Configuration.............................................................................|argwrap-configuration| 1.2. Configuration.............................................................................|argwrap-configuration|
1.3. Usage.............................................................................................|argwrap-usage| 1.3. Hooks.............................................................................................|argwrap-hooks|
1.4. License.........................................................................................|argwrap-license| 1.4. Usage.............................................................................................|argwrap-usage|
1.5. License.........................................................................................|argwrap-license|
======================================================================================================================== ========================================================================================================================
ARGWRAP *argwrap-argwrap* ARGWRAP *argwrap-argwrap*
@ -197,6 +198,66 @@ file basis using `ftplugin` or `autocmd`. For example, the `argwrap_tail_comma`
) { ) {
< <
------------------------------------------------------------------------------------------------------------------------
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.
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* USAGE *argwrap-usage*
@ -224,3 +285,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 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. 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,7 @@
" IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN " 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. " CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
let g:argwrap_filetype_hooks = {}
command! ArgWrap call argwrap#toggle() command! ArgWrap call argwrap#toggle()