Restoring selections after accidental clear

Often times I find myself performing a complex series of editing commands including sub selections. However, I often fumble a key and accidentally clear all of my carefully constructed selections. I know about ctrl o and saving selections with z, but the former doesn’t seem to always have the last selection state and the latter requires saving selections ahead of time (which I have done on occasion). Am i missing a convenient way to go back one step in selections? How do you all deal with this situation?

There is currently no native solution.

You can use registers and hooks to restore the penultimate selection state.

# Save selections to the [b]ackup register.
hook -group backup-selections global NormalIdle .* %{
  set-register b %reg{z}
  execute-keys -draft '"zZ'
}

# Add a mapping to easily reach the command.
map -docstring 'Restore selections from the [b]ackup register' global user z '"bz'

See also the discussion #898 to undo selection change.

3 Likes

The ,z map above really makes the difference between usable and unusable — at least for me as a kak newbie. However I wonder

  • how often does the NormalIdle hook run: CPU cost?
  • how does it work: how come the hook doesn’t run immediately after selection changes, overwriting the backup?

Further, without getting into generalized selection-undo, can I back up the selection periodically? I’d like to write a hook to save to some variable / setting every 15 seconds (perhaps with 2-3 levels of backup), but only if the selection is either multiple-region or multi-line. That would be good enough. Less than 15 seconds of “selection work”, or work that is trivial, are not worth backing up. But as it stands, ,z breaks if you move the cursor twice.

Normal idle runs once when you do nothing, and there is no sh call in the command, so it is wise.

Try to execute <c-s> in the hook, and then use <c-o> for restoring.

I found this works for cursor motion with the keyboard but not if I accidentally moved the cursor by clicking with the mouse on the terminal window. Is there a workaround for this?

I don’t want to disable the mouse completely as I do use it in Kakoune.

I expect it is breaking because the NormalIdle hook runs twice after a mouse click.

I’m currently trying the following to go back two selections:


# Save selections to the backup registers.
hook -group backup-selections global NormalIdle .* %{
  set-register c %reg{b}
  set-register b %reg{z}
  execute-keys -draft '"zZ'
}

# Add a mapping to easily reach the command.
map -docstring 'Restore selections from the backup register' global user z ': undo-selections<ret>'

define-command undo-selections -docstring "Restore selections" %{
  execute-keys '"cz'
  set-register b %reg{c}
}

but not if I accidentally moved the cursor by clicking with the mouse on the terminal window. Is there a workaround for this?

You can try my undo-selection-change branch which adds native selection-undo.
See Undo selection change · Issue #898 · mawww/kakoune · GitHub

I’m pretty happy with it, will submit a PR soon.

2 Likes

PR is up, I’ve been using it for a bit, it seems stable

1 Like