From 51b9685d9aa164e419d6d7f1f659e9d7cce086cb Mon Sep 17 00:00:00 2001 From: Madeleine Sydney Date: Wed, 27 Nov 2024 15:15:39 -0700 Subject: [PATCH] SPC/DEL overlays work --- README.org | 11 ++++++----- evil-leap.el | 54 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/README.org b/README.org index 4377f74..02dd5f8 100644 --- a/README.org +++ b/README.org @@ -5,11 +5,8 @@ Evil's answer to Neovim's answer to the mouse * Tasks -** TODO Equivalence classes - -** TODO Many targets w/ [[kbd:][SPC]] and [[kbd:][DEL]] labels - -** TODO Match newlines with [[kbd:][SPC SPC]] +** DONE Many targets w/ [[kbd:][SPC]] and [[kbd:][DEL]] labels +CLOSED: [2024-11-27 Wed 16:04] ** DONE Passthrough input on fail CLOSED: [2024-11-23 Sat 09:07] @@ -17,6 +14,10 @@ CLOSED: [2024-11-23 Sat 09:07] ** DONE Leap backwards CLOSED: [2024-11-24 Sun 08:55] +** TODO Equivalence classes + +** TODO Match newlines with [[kbd:][SPC SPC]] + ** TODO Leap from window ** TODO Only leap to visible targets diff --git a/evil-leap.el b/evil-leap.el index 32802a5..c3c4f54 100644 --- a/evil-leap.el +++ b/evil-leap.el @@ -57,6 +57,10 @@ jump." "TODO" :group 'evil-leap) +(defface evil-leap-further-label-face '((t :inherit shadow)) + "TODO" + :group 'evil-leap) + (defcustom evil-leap-use-char-fold-table t "TODO" :group 'evil-leap @@ -120,7 +124,11 @@ jump." (make-overlay (+ pos 2) (+ pos 3) buffer))) (label-string (string label))) - (put-text-property 0 1 'face 'evil-leap-label-face label-string) + (put-text-property 0 1 + 'face (if (eq label ?\s) + 'evil-leap-further-label-face + 'evil-leap-label-face) + label-string) (overlay-put overlay 'category 'evil-leap) (overlay-put overlay 'before-string label-string) ;; Normally, we want the labels to cover the buffer's text, rather than @@ -159,13 +167,11 @@ of Undefined Behaviour, should either `evil-leap-safe-labels' or ;; ... 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) @@ -206,6 +212,28 @@ represented by characters. Adds overlays for labels" (evil-leap--label-targets-safe targets) (evil-leap--label-targets-unsafe targets)))) +(defun evil-leap--update-further-overlays! (labeled-targets) + (ht-each (lambda (k v) + (cond ((eq k ?\s) + (evil-leap--update-further-overlays! v)) + ((evil-leap-target-p v) + (evil-leap--add-overlay-target! v ?\s)) + ;; Auto-jumps and back-links are met with no-ops. + (t nil))) + labeled-targets)) + +(defun evil-leap--update-earlier-overlays! (labeled-targets) + (ht-each (lambda (k v) + (cond ((eq k ?\d) + (evil-leap--update-earlier-overlays! v)) + ((evil-leap-target-p v) + (when-let ((overlay (evil-leap-target-overlay v))) + (delete-overlay overlay))) + ;; Auto-jumps and fore-links are met with no-ops. + (t nil))) + labeled-targets)) + +;; REVIEW: This could be more efficient. We needn't traverse /every/ target. (defun evil-leap--update-target-overlays! (labeled-targets) "TODO Create or update overlays to visually present a set of targets' associated labels." @@ -216,8 +244,17 @@ associated labels." ((eq k 'auto-jump) nil) + ;; Label every further ((eq k ?\s) - (error "TODO: Recurse into ")))) + (evil-leap--update-further-overlays! v)) + + ;; Delete every previous overlay. + ((eq k ?\d) + (evil-leap--update-earlier-overlays! v)) + + ;; Targets are simply labeled with their label. }:D + ((evil-leap-target-p v) + (evil-leap--add-overlay-target! v k)))) labeled-targets)) (defun evil-leap--euclidean-distance (x1 y1 x2 y2) @@ -259,15 +296,15 @@ associated labels." ;; (with-output-to-temp-buffer (format "*select - %s*" (current-time)) ;; (pp labeled-targets)) (evil-leap--try-auto-jump labeled-targets) + ;; TODO: Overlays should be updated here. + (evil-leap--update-target-overlays! 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)) + (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 @@ -333,6 +370,9 @@ corresponding to each occurence of P." ;; We are forced to save-excursion a second time, lest we enter a ;; feedback loop, where `re-search-forward' moves to a match, and ;; `goto-char' jumps to a position *preceding* the match. + ;; + ;; REVIEW: Alternatively, we could call `forwrad-char' as the last + ;; action in the loop. (save-excursion (goto-char (match-beginning 0)) (let ((second-char (aref (match-string 1) 0)) ; string->char