Skip to content
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

More improvements to the MoveHorizontally functions #48

Merged
merged 8 commits into from Jul 13, 2020
Merged

Conversation

@hugomg
Copy link
Contributor

@hugomg hugomg commented Jul 12, 2020

I gave another close look at the MoveHorizontally functions. Found a couple of bugs to fix and figured out a way to put the movement logic in a single place. That are three main changes in this PR:

  1. Improved the workaround for the problem of virtualedit putting the cursor in the wrong place. Instead of fixing the cursor after virtualedit messes up its position, we now disable virtualedit in the cases it is bugged. This means that the [ and ] always point to the correct place and can now be used by our functions. I also reported the bug to the Vim maintainers. They quickly found out what was the problem and already have patches queued up for the next Vim release.

  2. The core movement logic MoveCharHorizontally and MoveBlockHorizontally in now in a single function. The trick is that "x" does the same thing as "d" if we are in Visual mode.

  3. Uses of virtcol() are replaced by col(), improving how the functions behave in the presence of tabs. See the last commit message for details.

hugomg added 6 commits Jul 10, 2020
I reported that bug with the virtualedit to the upstream Vim maintainers
and it has since been fixed in both Vim and Neovim. However, since we
will need to still support Vim <= 8.2 for a while, I also improved the
workaround that we use.

It turns out that virtualedit is only bugged in the cases where we don't
actually need to use it. Therefore, instead of fixing the cursor after
it ends up in the wrong place, we can instead disable virtualedit when
it is not needed. One advantage of doing it this way is that the `[ and
`] marks now always point to the right place after the operation.
Because of the g:loaded_move guard, we don't need to worry about
functions being defined more than once.
If we take advantage of the fact that "x" in visual mode works the same
as "d" in visual mode, we can put all the logic for moving horizontally
in a single place.
This commit removes the special case for linewise visual mode in the
ModeBlockHorizontally function. I think that it is more consistent if
all the visual modes behave the same: now it always switches to visual
mode and then tries to move the selected rectangular area.

That said, most of the time trying to move a linewise selection isn't
super useful. It only does something interesting if
move_past_end_of_line is enabled.
This makes the function more similar to MoveHorizontally.
In this commit we replace all our uses of virtcol() by col(), which
fixes a couple of bugs related to tabs.

One bug was in move_past_end_of_line. Since strwidth treats tabs as
having 1 character, if the line had tabs we would think that the end of
line appeared sooner than it should. If we tried to move something to
the right it would get "stuck" before reaching the end.

Another bug was that MoveRight needed a count of at least 8 to be able
to move over a tab. In the fixed version a count of 1 is enough, which
makes th MoveRight binding behave more similarly to "l".

Finally, there was the minor issue that "normal! 0|" is actually an
invalid command. It does the right thing because 0 moves to the first
column and then the | is ignored but relying on a command being silently
ignored is a bit fishy. Anyway, now that we don't call `|` at all this
problem is avoided entirely.
"
function s:MoveBlockHorizontally(distance)
function s:MoveHorizontally(corner1, corner2, distance)

This comment has been minimized.

@matze

matze Jul 13, 2020
Owner

Any particular reason to call these parameters cornerX? Maybe from and to instead?

This comment has been minimized.

@hugomg

hugomg Jul 13, 2020
Author Contributor

Dunno. I think from and to sound like they could refer to the distance that we are moving instead of to the area that we are moving. "Move X from here to there"

What about corner_start and corner_end?

This comment has been minimized.

@matze

matze Jul 13, 2020
Owner

Sounds good.

This comment has been minimized.

@hugomg

hugomg Jul 13, 2020
Author Contributor

OK! It should be fixed in the latest commit now.

" In normal mode, move the character under the cursor horizontally
"
function s:MoveCharHorizontally(distance)

This comment has been minimized.

@matze

matze Jul 13, 2020
Owner

I'm just noticing it now but the newlines are all over the place now. I'd prefer to not have a newline after function and before endfunction.

hugomg added 2 commits Jul 13, 2020
As suggested by code review, remove all blank lines after `function` and
before `endfunction`.
Following a suggestion from code review.
@matze
Copy link
Owner

@matze matze commented Jul 13, 2020

Alright, thanks 👍

@matze matze merged commit b244c7e into matze:master Jul 13, 2020
@hugomg
Copy link
Contributor Author

@hugomg hugomg commented Jul 13, 2020

My pleasure :)

@hugomg hugomg deleted the hugomg:tabs branch Jul 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants
You can’t perform that action at this time.