Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upMore improvements to the MoveHorizontally functions #48
Conversation
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.
plugin/move.vim
Outdated
| " | ||
| function s:MoveBlockHorizontally(distance) | ||
| function s:MoveHorizontally(corner1, corner2, distance) |
matze
Jul 13, 2020
Owner
Any particular reason to call these parameters cornerX? Maybe from and to instead?
Any particular reason to call these parameters cornerX? Maybe from and to instead?
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?
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?
matze
Jul 13, 2020
Owner
Sounds good.
Sounds good.
hugomg
Jul 13, 2020
Author
Contributor
OK! It should be fixed in the latest commit now.
OK! It should be fixed in the latest commit now.
plugin/move.vim
Outdated
| " In normal mode, move the character under the cursor horizontally | ||
| " | ||
| function s:MoveCharHorizontally(distance) | ||
|
|
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.
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.
As suggested by code review, remove all blank lines after `function` and before `endfunction`.
Following a suggestion from code review.
|
Alright, thanks |
|
My pleasure :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
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:
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.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.
Uses of virtcol() are replaced by col(), improving how the functions behave in the presence of tabs. See the last commit message for details.