SPC/DEL navigation works

This commit is contained in:
Madeleine Sydney
2024-11-27 15:15:09 -07:00
parent e49883a6c9
commit cba55fdc78
2 changed files with 57 additions and 40 deletions

View File

@@ -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~

View File

@@ -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?