SPC/DEL navigation works
This commit is contained in:
@@ -42,6 +42,15 @@ Currently, we take care to only search from the point to the beg/end of the wind
|
||||
result))))
|
||||
#+end_src
|
||||
|
||||
** TODO Avoid leaping to target directly under point
|
||||
|
||||
Currently, if the point is on ~a~, that very ~ab~ pair will be given as a potential target.
|
||||
|
||||
#+begin_src
|
||||
↓
|
||||
ab
|
||||
#+end_src
|
||||
|
||||
** TODO Leap any direction
|
||||
|
||||
** TODO Cleanup w/ ~pre-command-hook~
|
||||
|
||||
88
evil-leap.el
88
evil-leap.el
@@ -137,35 +137,36 @@ spice!
|
||||
|
||||
Spice: If an entry with key LABEL already exists in LABELED-TARGETS, a fresh
|
||||
hash table will be created and inserted into LABELED-TARGETS under key '?\\s'.
|
||||
This fresh hash table will itself have a key '?\\b' pointing back to
|
||||
This fresh hash table will itself have a key '?\\d' pointing back to
|
||||
LABELED-TARGETS. If this '?\\s' entry already exists in LABELED-TARGETS, it
|
||||
will instead try to insert it into /that/ hash table, continuing until a
|
||||
suitable home is found.
|
||||
|
||||
;; Spice: Since the expected appearance of label overlays is so tightly coupled
|
||||
;; with the above logic, the overlays are also created by this routine. Sorry!
|
||||
|
||||
This all implies that important parts of evil-leap will enter the eldritch world
|
||||
of Undefined Behaviour, should either `evil-leap-safe-labels' or
|
||||
`evil-leap-labels' contain '?\\s' or '?\\b'."
|
||||
`evil-leap-labels' contain '?\\s' or '?\\d'."
|
||||
;; If the label is already present in `labeled-targets', we insert it into the
|
||||
;; "next" map at key '?\s'.
|
||||
(let ((existing-targets (ht-get labeled-targets label target)))
|
||||
;; REVIEW: This is terribly inefficient to be ran in a tight loop (i.e.
|
||||
;; `evil-leap--label-targets').
|
||||
(if (<= (length evil-leap-labels) (length existing-targets))
|
||||
;; If labeled-targets[?\s] (the "next map") exists, ...
|
||||
(if-let ((next-labeled-targets (ht-get labeled-targets ?\s)))
|
||||
;; ... recurse into it. ...
|
||||
(evil-leap--add-to-labeled-targets!
|
||||
next-labeled-targets label target)
|
||||
;; ... If it doesn't, create a new hash table, stored in
|
||||
;; `labeled-targets' at key '?\s', containing nought but a back-link key
|
||||
;; ('?\b')[1], and the given label/target pair[2].
|
||||
(print "here!")
|
||||
(ht-set! labeled-targets ?\s
|
||||
(ht (?\b labeled-targets) ; [1]
|
||||
(label (list target))))) ; [2]
|
||||
;; The label does not exist, meaning we needn't muck around with the next
|
||||
;; map. Proceed normally with `ht-set!'!
|
||||
(ht-set! labeled-targets label target))))
|
||||
;; "next map" at key '?\s'.
|
||||
(if (ht-get labeled-targets label)
|
||||
;; If labeled-targets[?\s] (the "next map") exists, ...
|
||||
(if-let ((next-labeled-targets (ht-get labeled-targets ?\s)))
|
||||
;; ... recurse into it. ...
|
||||
(evil-leap--add-to-labeled-targets!
|
||||
next-labeled-targets label target)
|
||||
;; ... If it doesn't, create a new hash table, stored in
|
||||
;; `labeled-targets' at key '?\s', containing nought but a back-link key
|
||||
;; ('?\d')[1], and the given label/target pair[2].
|
||||
(evil-leap--add-overlay-target! target label)
|
||||
(ht-set! labeled-targets ?\s
|
||||
(ht (?\d labeled-targets) ; [1]
|
||||
(label target)))) ; [2]
|
||||
;; The label does not exist, meaning we needn't muck around with the next
|
||||
;; map. Proceed normally with `ht-set!'!
|
||||
(evil-leap--add-overlay-target! target label)
|
||||
(ht-set! labeled-targets label target)))
|
||||
|
||||
(defun evil-leap--label-targets-safe (targets)
|
||||
"TODO returns a hash table mapping labels to targets"
|
||||
@@ -179,7 +180,7 @@ of Undefined Behaviour, should either `evil-leap-safe-labels' or
|
||||
(ht-set! labeled-targets 'auto-jump (car targets))
|
||||
(dolist (target (cdr targets) labeled-targets)
|
||||
(let ((lbl (pop labels)))
|
||||
(evil-leap--add-overlay-target! target lbl)
|
||||
;; (evil-leap--add-overlay-target! target lbl)
|
||||
(evil-leap--add-to-labeled-targets! labeled-targets lbl target)))))
|
||||
|
||||
(defun evil-leap--label-targets-unsafe (targets)
|
||||
@@ -189,7 +190,7 @@ of Undefined Behaviour, should either `evil-leap-safe-labels' or
|
||||
(labeled-targets (ht-create 'eq)))
|
||||
(dolist (target targets labeled-targets)
|
||||
(let ((lbl (pop labels)))
|
||||
(evil-leap--add-overlay-target! target lbl)
|
||||
;; (evil-leap--add-overlay-target! target lbl)
|
||||
(evil-leap--add-to-labeled-targets! labeled-targets lbl target)))))
|
||||
|
||||
(defun evil-leap--label-targets (targets)
|
||||
@@ -254,21 +255,29 @@ associated labels."
|
||||
- read a key from the user;
|
||||
- if the key corresponds to a label, jump to it;
|
||||
- otherwise, let the input `fall through,' as if Leap were never here."
|
||||
(progn
|
||||
;; REVIEW: Should the return value of `evil-leap-action' be returned by us?
|
||||
(evil-leap--try-auto-jump labeled-targets)
|
||||
(let ((given-key (evil-read-key)))
|
||||
(if-let ((selected-target (ht-get labeled-targets given-key)))
|
||||
(funcall evil-leap-action selected-target)
|
||||
;; If we are given a key that does not correspond to any label, we let
|
||||
;; it 'fall through' to give it a proper run through Emacs' command
|
||||
;; loop. We do this as a formality in the general case, but it is
|
||||
;; essential to the idea behind auto-jump.
|
||||
;; REVIEW: Should the return value of `evil-leap-action' be returned by us?
|
||||
;; (with-output-to-temp-buffer (format "*select - %s*" (current-time))
|
||||
;; (pp labeled-targets))
|
||||
(evil-leap--try-auto-jump labeled-targets)
|
||||
(let ((given-key (evil-read-key)))
|
||||
(if-let ((selected-target (ht-get labeled-targets given-key)))
|
||||
;; '?\s' and '?\d' are special targets that lead to alternative sets
|
||||
;; of labeled targets; if we find another hash table, select from that
|
||||
;; one instead.
|
||||
(if (ht-p selected-target)
|
||||
;; TODO: Overlays should be updated here.
|
||||
(progn (print "space or del!")
|
||||
(evil-leap-select-from-labeled-targets selected-target))
|
||||
(funcall evil-leap-action selected-target))
|
||||
;; If we are given a key that does not correspond to any label, we let
|
||||
;; it 'fall through' to give it a proper run through Emacs' command
|
||||
;; loop. We do this as a formality in the general case, but it is
|
||||
;; essential to the idea behind auto-jump.
|
||||
|
||||
;; REVIEW: Should the passthrough behaviour be configurable in the
|
||||
;; non-auto-jump case?
|
||||
(progn (push given-key unread-command-events)
|
||||
nil)))))
|
||||
;; REVIEW: Should the passthrough behaviour be configurable in the
|
||||
;; non-auto-jump case?
|
||||
(progn (push given-key unread-command-events)
|
||||
nil))))
|
||||
|
||||
|
||||
; Labels
|
||||
@@ -289,7 +298,7 @@ with key SECOND-CHAR."
|
||||
(ht-each
|
||||
(lambda (_label target)
|
||||
;; 1. A value in `labeled-targets' isn't always a target (e.g. entries
|
||||
;; at '?\s' and '?\b').
|
||||
;; at '?\s' and '?\d').
|
||||
;; 2. If a target is an auto-jump candidate, its `overlay' slot is nil.
|
||||
(when-let ((overlay (and (evil-leap-target-p target)
|
||||
(evil-leap-target-overlay target))))
|
||||
@@ -372,7 +381,6 @@ Keyword arguments
|
||||
(second-char (evil-read-key))
|
||||
(_ (evil-leap--unlabel-other-branches second-char branches))
|
||||
(labeled-targets (ht-get branches second-char)))
|
||||
(pp labeled-targets)
|
||||
(evil-leap-select-from-labeled-targets labeled-targets))
|
||||
;; TODO: would it be faster to go through `labeled-targets' and unlabel them
|
||||
;; ourselves?
|
||||
|
||||
Reference in New Issue
Block a user