Closed mwgkgk closed 5 years ago
Try this example with vim --clean
or vim -Nu NONE
; `%` jumps to (
(format t "cursor_position")
Does it work the same way as with match-up? The goal is that match-up will emulate the behavior of vim whenever possible.
I think the match-up documentation is very unclear. This is how it is described in the vim help:
*%*
% Find the next item in this line after or under the
cursor and jump to its match. |inclusive| motion.
So the precise behavior is: 1) search forward for an active word or symbol and 2) go to its match.
The if/else/fi
example should work similarly, except with three instead of two.
Perhaps the behavior of g%
should be changed?
Indeed, the naked vim's %
does jump backward, I didn't think to check that. Seems like Vim's stance on this is to first, find the next matching item, and then jump to it's match. Which is exactly what you said. That explains different behaviors from outside and inside the brackets.
It does seem like g%
acts as a duplicate of %
, both outside and inside of brackets. In matchup#motion#find_matching_pair
, the a:down
switch seems to be used in 3 different places, so the difference is probably something I couldn't easily observe.
Doesn't seem like making %
/ g%
behave consistently from outside and inside the brackets, and keeping consistent with Vim default behavior, can be reconciled. Probably the motions that I really want are indeed ]%
and [%
, it's just that the repeated keypresses will lead further out, instead of iterating between both. A separate key for iteration (%
) solves that.
(Edit: With the exception that ]%
and [%
skip over the inner groups like if-else-fi
).
If you don't mind explaining the difference between current (or planned?) behavior of %
and g%
, I would appreciate that :) Otherwise, this issue can be closed. Thank you for your time :)
Can you perhaps clarify which exact motion you are looking for, or expect? If I think it is sensible and simple to implement it could maybe be added as another (optional) map.
Your suspicion is totally correct; for matches with only two components (such as parentheses) %
and g%
behave identically. The difference is only for higher-order matches like if-else-endif
, where %
goes forwards and g%
goes backwards. So my idea is that in cases where %
and g%
would be identical, make g%
do the opposite of what %
would do.
cursor ( )
^ ^
g% %
( cursor )
^ ^
% g%
(proposed behavior, not current). However, this might be even more confusing than the current situation, which is consistent although g%
is useless for parentheses.
Oh, wow :) Yeah, the proposed reverse g%
is indeed confusing, while making sense at the same time.
Thank you for explaining. I now understand the need for g%
in higher-order-matches.
What I originally had in mind for %
/g%
was to have a consistent motion to kill/move to the right side or left side of the nearest pair, and, in normal mode, cycle down/up when on top of a match. This would involve not skipping over inner matches in if-else-fi
, being able to consistently jump up/down from inside else-fi
to else
or fi
, treating the match exclusively when used with motions (currently we kill till the right-matching bracket on ]%
, but including on [%
and %
); Also, prioritizing outer matches over nearest-not-entered-pairs (currently % will jump to a nearest bracketed call inside of if-else-fi, rather than if-else-fi itself. ]% and [% however do act on the "outer" matches).
So something like a ]%
/ [%
that does not skip higher-order matches, iterates when on top of a match (like %
/g%
), is consistent up/down with regards to killing/yanking only text and not the match itself.
I'm not sure if this fits into the vim-matchup strategy, being more of a replacement / combo, as well as having like 20 pages of specification to explain what it does :) Feels more towards the territorial waters of machakann/vim-patternjump or something like jeetsukumaran/vim-indentwise or even fcpg/vim-shore, in terms of implementing a general-feel sort of thing rather than building up on established Vim conventions.
From what I can see it leans outside of sensible/simple-to-implement range, but in any case I appreciate your time spent on clearing up my confusion.
This is implemented as an example "custom" motion. The intent is to provide an API to allow users to define their own motions which use match-up's matching features. The actual matching API isn't really specified yet, but the example motion should still be useable. Since this isn't the mainstream motion, no documentation and not much support is provided. Interested users can see matchup#custom#example_motion
which is fairly simple and constructed from basic building-blocks (API subject to change).
To use:
call matchup#custom#define_motion('nox', '%',
\ 'matchup#custom#example_motion', { 'down': 1 })
call matchup#custom#define_motion('nox', 'g%',
\ 'matchup#custom#example_motion', { 'down': 0 })
Works and feels great! Some questions:
1 - custom.vim
has to be sourced explicitly to work.
Plug 'andymass/vim-matchup' " {{{
source ~/.vim/bundle/vim-matchup/autoload/matchup/custom.vim
call matchup#custom#define_motion('nox', 'q',
\ 'matchup#custom#example_motion', { 'down': 1 })
call matchup#custom#define_motion('nox', 'gq',
\ 'matchup#custom#example_motion', { 'down': 0 })
" }}}
A setup like this triggers an error for not having access to motion_sid()
, because the source
has to go after call plug#end()
to work like this. So should the calls to define_motion
, because they require custom.vim
. Is there a better way for right now?
2 - % and g% when used as motions now consistently grab the match in both directions. What I would prefer as a default is leave the match as is, only selecting the text until the match. I couldn't easily modify the source to achieve this, and v
to trigger the inclusiveness of a motion (e.g. dv%
) has no effect.
Edit: The problem with source-order is honestly just me using the plugin manager wrong. It does work for most cases to couple the config like that, but I really should try something like minpac which should play better with runtimepath-related things.
runtimepath
after call plug#end()
, so you'd need to use the matchup#custom#define_motion
function after the plug#end()
, not interspersed with the Plug
s. Alternatively, I don't see why something like this wouldn't work:Plug 'andymass/vim-matchup'
augroup matchup_custom
au!
autocmd! VimEnter *
\ call matchup#custom#define_motion('nox', '%',
\ 'matchup#custom#example_motion', { 'down': 1 })
\ \| call matchup#custom#define_motion('nox', 'g%',
\ 'matchup#custom#example_motion', { 'down': 0 })
augroup END
matchup#custom#example_motion
. Please see the recent commit.
From docs:
However for me, with this minimal vimrc,
In the following examples, jumps (and motion-s) backwards:
Effectively acting the same as
g%
. Been a long time, last tested at commit 62b3db9684ce7e9626b0a631d9e7fbf53eb09780. Seems like I'm doing something wrong. Will appreciate any pointers / possible workarounds.]%
works correctly but further jumps lead to next closing matches, so it can't be substituted for%
.Does work correctly in some cases:
Jumps over
else
directly tofi
, in this example.Seems like it could be solved with
matchup_hotfix
. However the issue does not look to be filetype-specific. Will appreciate any pointers.