-
Notifications
You must be signed in to change notification settings - Fork 264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Behavior of text object when outside of matching pairs #1139
Comments
The first part is likely a bug and patches would be welcome. The second part is a feature. |
Your comment is valid at first sight. But thinking more about the problem, I am starting to wonder. Some people expect the behavior that you state. If I However, in practice, I think that what vim does could be desired. I am taking the example from the issue here, but feel free to imagine any block in your programming language or in a json file:
Often, the user will want to replace the content of a block with something else. I cannot generalize, but I feel that in replacements, users will 95% of the time want to keep their indentation level and directly start replacing. Let's say I want this:
In the above block in vim, I simply do With vis, I have to do I can otherwise do By the way, Kakoune works like vis for the above example, as it does not exclude new lines or spaces. But as it has motions first, visual mode is the norm and so it makes sense to implement it this way, and to let the user decide then to do For deletions, the desired behavior might be more like vis. If I want to empty the block there are chances that I want those braces collapsed ( So in the end, I am not exactly sure that vis should diverge from vim for this behavior. Note also that vim goes even farther, and this might feel opinionated. If there are empty-indented lines before the closing of the text-object character, there are also excluded. In this example,
If I execute
I am not sure why this is acting this way. For reference, here is the location in neovim (should be similar in vim) where all this logic of excluding newline or whitespace is developed. |
The first thing is quite interesting. I'd never considered using `ci(`
when my cursor wasn't between parentheses. So rather than have `ci(` do
"change inside surrounding parentheses" you'd make it "change from next
) to matching ("? Should we then also make a difference for `ci)` to be
"change from previous ( to matching )" so you could edit the wrapped
text *before* the cursor? This could be useful especially for `}`.
The second thing I'm not sure. I've often felt that `ca(` and `ci(` were
very close to each other. Perhaps this is where they could differ: `ca(`
include the matching pair, `ci(` excludes the pair *and the whitespace
directly inside of it* (which is what your latter example demonstrates
vim to do).
|
Not exactly. I would stick to vim behaviour which I think is more or less "change inside surrounded parenthesis if there are surrounded parenthesis, otherwise change inside next match of parenthesis on the same line". Vis does not work with lines being the base though. So not sure if it should match on next lines also.
I would personally not move away from vim's implementation if we don't have good reasons to. |
I am trying to analyse the differences between vis and vim when targeting a matching pair from outside of the text object, or when there are both a matching pair enclosed or on the same line further away.
First, let's talk about single-line, without any enclosing pairs above or below. See this simple example. The cursor is represented by
▌
.In vim, I can do
ci"
and I will be able to directly changemy_parameter
. This also works in vis 🎉. The behavior is the same for simple quotes. However, in vim, this also works for other pairs such as for()
/{}
/[]
/<>
. And this does not seem supported in vis, while being a really handy feature. When I tryci(
in the above example, it enters insert mode without moving the cursor.Now, if we talk about visual mode, even doing
vi"
orvi'
does not produce the desired behavior. Effectively, it will enter visual mode and select everything from the current cursor until the closing"
or'
instead of just selecting the inside of the matching"
or'
. Doingvi(
does nothing except going into visual mode.Now let's take an example with multiline enclosing pairs.
So the behavior in vim here when doing
ci(
orvi(
will be to change the inside of the outer parenthesis just above and below. However, it will ignore the new-line characters or spaces that are on the same lines as(
and)
.So doing
ci(#my comment
will result into:However, if the initial example had non-space nor new-line characters on the same line as
(
, such as:The change would start applying on the same line as
(
and the result would result in:Vis behavior is different. Taking the initial example, it will not ignore new-line characters and spaces, so doing
ci(#replacement
will result in:When doing
ca(
orva(
, the behavior seems more consistent between vim and vis.So those are two examples that show differences between vis and vim. First I wanted to know if there were technical or design-related reasons for them. Maybe vis not acting at the line level leads to those?
Otherwise, are those differences existing on purpose, or should they be considered bugs?
Whatever the outcome of this issue, those differences are not documented in the FAQ "Differences from Vi(m)".
The text was updated successfully, but these errors were encountered: