guillermooo / Vintageous

Vi/Vim emulation for Sublime Text 3
http://guillermooo.bitbucket.org/Vintageous/
Other
1.64k stars 115 forks source link

Redo should leave cursor at the beginning of the redone edit. #302

Open jordwalke opened 11 years ago

jordwalke commented 11 years ago

Vim leaves the cursor at the beginning of the redone edit. This is critical for being able to correctly reply changes through a file and visually determine what is changing.

--- Want to back this issue? **[Place a bounty on it!](https://www.bountysource.com/issues/798485-redo-should-leave-cursor-at-the-beginning-of-the-redone-edit?utm_campaign=plugin&utm_content=tracker%2F204305&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F204305&utm_medium=issues&utm_source=github).
jordwalke commented 11 years ago

Thanks! I'll give this a shot.

jordwalke commented 11 years ago

So how did that diff improve the behavior of redo? I'm seeing the same behavior, I believe.

jordwalke commented 11 years ago

Specifically, Vim leaves the cursor at the start of the "redone" change - not the end of it.

guillermooo commented 11 years ago

Oh, yeah, it's simply restoring the caret position before the redo op. It should find the start of the edit instead.

jordwalke commented 11 years ago

:+1:

guillermooo commented 11 years ago

Which doesn't seem to be too simple, though... :/

jordwalke commented 11 years ago

Any thoughts on this? I think it's the last thing holding me back from switching full-on to Vintageous. Haven't you ever noticed that sometimes it's impossible to undo/redo/undo/redo to see a particular change that you made? This is the culprit, I believe.

One challenge is that Sublime's undo/redo gets this wrong itself so Vintageous will need to improve upon it. Every item on the undo/redo stack might need to have the original cursor position recorded if it can't be inferred from the change data itself.

guillermooo commented 11 years ago

Doesn't seem to bother me so much, but I'd like to get this right in Vintageous as a main goal. However, I indeed suspect Sublime Text can't provide the means to make this work, and although I have a couple of ideas, I'm not confident they will work.

Anyhow, it'll be some time before I revisit this issue.

jordwalke commented 11 years ago

I really wish we had a fix for this - I know I keep saying it, but this has got to be the last thing that keeps me from switching completely.

The reason why I feel it is so bad, is that there are situations you can get into, where it is impossible to tell which changes you are redoing and undoing - it jumps around the screen and "skips over" changes. In Vim you can always go u->c-r to reply any change, regardless of how the two subsequent changes are spread out over the file.

guillermooo commented 11 years ago

I haven't thought the issue through, but it seems it's impossible to hook into the undo stack's .push() method, so it isn't possible to know when an editing command has been run by the user. Without that information, I don't think Vintageous can track the cursor location reliably.

Probably inspecting the command history and comparing the oldest known item to the newest would help, but I haven't explored that option.

guillermooo commented 11 years ago

S3 commits selection changes as well as buffer edits to the command history, but does not provide any way to distinguish between the two.

To improve the cursor placement in Vintageous when undoing/redoing, it should suffice to know the current index into the command history and whether the recorded command at that position is a modifying command or not.

Until that's available through the api, I've run out of ideas to solve this issue.

jordwalke commented 11 years ago

Do you think the main Sublime author will be supportive of implementing this? I would think he'd be supportive because Vintageous is the best Vim mode effort for Sublime and by having a solid Vim mode in Sublime, many users will likely convert.

guillermooo commented 11 years ago

I hope so, but I suppose it won't be a priority for them. Perhaps too narrow of a scope for practical usage.

jordwalke commented 11 years ago

Actually, I believe their current experience is horribly broken even outside of Vintageous - so I hope they'd like to fix it regardless.

jordwalke commented 10 years ago

I have to say, this is really inhibiting my productivity. Honestly, everything about using sublime with Vintegeous is spot on except this. Is it possible to record the position when beginning insert mode (or delete/change command) in Vintageous - and then remap (c-r) to not only redo as normal, but then jump to that previously recorded location? We're so close here!

guillermooo commented 10 years ago

I'll think about it. We'll get it right eventually.

jordwalke commented 10 years ago

Related: http://www.sublimetext.com/forum/viewtopic.php?f=3&t=9802

jordwalke commented 10 years ago

And I just realized that vintageous reimplements redo/undo in a different way than the standard sublime undo/redo. Both are broken. Have you considered implementing your own undo/redo? You'd probably want an undo tree, instead of an undo stack (vim has an undo tree and it unleashes all kinds of awesome plugin opportunities).

jordwalke commented 10 years ago

Maybe we can evaluate this plugin: https://github.com/randy3k/ChangeList

jordwalke commented 10 years ago

I brought up the issue here: https://github.com/SublimeText/Issues/issues/107

@guillermooo: This isn't a bug in your code by any means, but do you have any suggestions about how to fix this, whether or not SublimeHQ does? It totally ruins the Vim feel (even if it's not your fault).

guillermooo commented 10 years ago

@jordwalke Too much work for me at the moment. I'm all for improving undo/redo, but I think it'd be wise to wait and see ST's next move. Also, I'm in the middle of another big refactor to simplify handling of commands internally, so that'll keep me busy for some time.

Do you have repro steps, BTW?

jordwalke commented 10 years ago

I mention the repro steps here:

https://github.com/SublimeText/Issues/issues/107#issuecomment-21991912

Maybe if I put a 100$ bounty on it? :) It's not a problem with Vintageous, it's a problem with Sublime. But since it effects the "vim feel", it might have to be fixed at the Vintageous level.

guillermooo commented 10 years ago

I don't think I'd be able to deliver :) There's too many open questions regarding undo/redo/macros. Either Vintageous or ST or both are too brittle with regards to this.

I guess Vintageous could intercept all commands via .on_text_command() and decide whether to keep them in its own history or discard them, but I'd rather ST had a .on_add_to_history() providing details on selections, command name, params... Also, ST command history should probably be editable and expose some internal data.

I think I'll first work on other existing bugs, then on the ex mode in 4.0 and maybe later on this. By that time, ST 3.0 final should be out and perhaps this particular problem will have a more obvious solution.

As far as I'm concerned, getting this and caret placement right are top priorities, but I don't see how to make them happen in a satisfactory way.

jordwalke commented 10 years ago

I don't blame you. It seems we must rely solely on the Sublime developer to fix this issue. But I have never seen him respond to this bug which has been brought up by several people. I sure hope Sublime hasn't got into unsupported mode.

jordwalke commented 10 years ago

The worst part about this is that there is no consistency. Wherever you are in the undo stack, if you move your cursor - that becomes your new cursor position every time you undo/redo to that save point. Again, I know this isn't Vintageous' fault.

jordwalke commented 9 years ago

So I realized that there's actually two issues. Redo should leave cursor at the beginning of the redone change, but that's not as serious as the second issue.

The second issue is that Sublime associates a cursor position with each place in the undo tree. If you undo to a version, then move your cursor, whatever you do - if you undo/redo and end up on that version in the undo tree again at some point, it will force your cursor to where you left it the last time you were at that version. This is the main issue - and the main reason why it's easy to get in a situation where it is impossible to see what changes have been applied by replaying redo.

I asked a bunch of Sublime users how this doesn't disturb them to the point of insanity. Everyone that said they didn't notice it, doesn't use Vintageous. The reason is because the way you navigate code in a Vim mode, is by moving the cursor so you are very likely to get in this situation. People who don't use Vim modes scroll to where they want to move (with a mouse) and so they don't notice it. I think this is a hugely critical issue, but now that I've articulated the exact problem well, I feel it's easier to fix. I even started hacking together a solution but I don't know Sublime's API as well as you (or Python for that matter). (I actually made good progress but noticed inconsistencies in sublime's API).

Wouldn't it be possible to simply compare the file text before and after a redo/undo and move the cursor to the first character sequence that differs between the two versions (also clearing out any selections - as vim always does when you undo/redo/repeat)?

jordwalke commented 9 years ago

I don't know if there's a bot that will post here eventually, but linking to the bounty just in case it doesn't: https://www.bountysource.com/issues/798485-redo-should-leave-cursor-at-the-beginning-of-the-redone-edit

braham-snyder commented 8 years ago

+1