diff --git a/README.org b/README.org index ef7643a..4377f74 100644 --- a/README.org +++ b/README.org @@ -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~ diff --git a/evil-leap.el b/evil-leap.el index 45936a0..32802a5 100644 --- a/evil-leap.el +++ b/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?