lispy point history09 Mar 2015
It was kind of disappointing to summarize in
the last post
that there weren't many new features for
lispy 0.24.0. So I thought long and hard and came up with something
quite obvious: since
lispy offers commands to quickly manipulate point and mark, it should offer one
to quickly restore them.
Here's the bulk of the new code:
(defvar lispy-pos-ring (make-ring 200) "Ring for point and mark position history.") (ring-insert lispy-pos-ring 1) (defun lispy--remember () "Store the current point and mark in history." (if (region-active-p) (let ((bnd (lispy--bounds-dwim))) (unless (equal bnd (ring-ref lispy-pos-ring 0)) (ring-insert lispy-pos-ring bnd))) (unless (eq (point) (ring-ref lispy-pos-ring 0)) (ring-insert lispy-pos-ring (point))))) (defun lispy-back () "Move point to a previous position" (interactive) (if (zerop (ring-length lispy-pos-ring)) (user-error "At beginning of point history") (let ((pt (ring-remove lispy-pos-ring 0))) (if (consp pt) (lispy--mark pt) (deactivate-mark) (goto-char pt)))))
Here, I'm using
lispy-pos-ring made with
make-ring to store the
last 200 point and mark positions. In Elisp, a ring is basically a stack backed by a vector.
When the vector space overflows, the older stuff is overwritten.
In this ring I store each time either the point, or a cons of the point and mark if the region is active. This way possible to restore the region even if it was deactivated several movement commands ago.
lispy--remember into the most used navigation commands:
- j -
- k -
- h -
- l -
- f -
- i -
lispy-mark-car(when the region is active)
- a -
lispy-back is now bound to b. The previous binding of
lispy-store-region-and-buffer is now bound to
xB (quite close to B - the binding for
I really like the new command, it's especially useful to reverse h and l. Previously, they could be reversed with f, but that can get annoying if you have to press it many times. This results in a much more relaxed editing - I know that whatever I press, I can restore the point position quickly if needed.
This feature is added to the already present list of safeguards:
- j and k are guaranteed not to exit the parent list.
- > and < are guaranteed not to exit the parent list.
- C reverses itself.
Here's a recipe to copy the third item of the current list and move
the point back: 4mnb. You can use it to copy a function's
docstring if you're in Elisp. You'll need 3mnb for
Clojure, since it weirdly has the docstring before the arguments. I
think it's pretty cool: by typing 3mnb I'm basically
(kill-new (caddr (current-sexp))) on my own code.