Undo selection
Closed this issue · 5 comments
Thanks for this amazing addin :)
It would be nice to be able to keep an history of the selection, and to restore the previous one (for example if you select the ancestor, but you did the shortcut one too many)
I agree, being able to "jump back" to the previous selection in the stack, or "jump forward" to the next selection, is very useful...
Fortunately, this functionality is built in to Sublime Text!
I use this all the time to do exactly what you're describing. Here are my key bindings for these commands. Does it work for you?
it doesn't work well no ? it won't have the same steps as you did in the reverse order
See: https://drive.google.com/file/d/1jaN0CNtM2V9b1KMuFTySUWahM5Dtcff7/view?usp=sharing
(I think this shortcut is more about cursor position than selection)
I did this small piece of code and it's exactly the behavior I want (not sure if it can be improve to not have global variables, not clearing the entire selection to restore the previous one, etc)
import sublime, sublime_plugin
from copy import deepcopy
_history = []
skip_next = False
def _selection_to_tuple(sel):
return [(s.a, s.b) for s in sel]
class SelectionListener(sublime_plugin.EventListener):
def run(self, edit):
if _history:
self.view.sel(_history.pop())
def on_selection_modified(self, view):
global _history, skip_next
if skip_next:
skip_next = False
return
selection = view.sel()
if len(selection) == 1 and selection[0].a == selection[0].b:
_history = [[(selection[0].a, selection[0].b)]]
else:
to_add = _selection_to_tuple(selection)
if not _history or _history[-1] != to_add:
_history.append(to_add)
class PreviousSelectionCommand(sublime_plugin.TextCommand):
def run(self, edit):
global _history, skip_next
if _history:
skip_next = True
sel = self.view.sel()
while True:
new_selection = _history.pop() if len(_history) > 1 else _history[0]
if len(_history) <= 1 or _selection_to_tuple(sel) != new_selection:
break
sel.clear()
regions = [sublime.Region(a=a, b=b) for a, b in new_selection]
sel.add_all(regions)
self.view.show(regions[0])
You're right, the jump_back
and jump_forward
commands seem to group multiple selection changes into a single "jump". This is also how the undo
and redo_or_repeat
commands work as well -- they group multiple text changes into a single "undo" or "redo". I usually don't mind this behavior, but it's cool to see the more granular alternative you built =)
If I'm not mistaken and read this issue correctly. 1. Selection changes can (generally) be done by soft_undo
(ctrl+u
) but here we're usually too fast and Sublime would combine entries. 2. You can manual add entries to the jump back/forth history:
view.run_command("add_jump_record", {
"selection": [(r.a, r.b) for r in view.sel()]
})
Maybe adding this does the trick for soft_undo
as well.