emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 4e4c488 020/110: Add avy-linum-mode


From: Oleh Krehel
Subject: [elpa] master 4e4c488 020/110: Add avy-linum-mode
Date: Sat, 11 May 2019 10:15:35 -0400 (EDT)

branch: master
commit 4e4c488eefe4dad1b143ed100bbc26e838a56e10
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Add avy-linum-mode
    
    * avy.el (avy--linum-strings): New defun.
    (avy--linum-update-window): New defun. This is a copy-paste of
    `linum-update-window' with just a few lines added.
    (avy-linum-mode): New minor mode. Currently, only works with
    `avy-all-windows' set to nil.
    (avy--line): When `avy-linum-mode' is on, don't display
    overlays. Instead, display a simple message.
    
    Fixes #155
---
 avy.el | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/avy.el b/avy.el
index 74aba07..4461cbb 100644
--- a/avy.el
+++ b/avy.el
@@ -1160,6 +1160,83 @@ Which one depends on variable `subword-mode'."
                 (forward-line 1)))))))
     (nreverse candidates)))
 
+(defun avy--linum-strings ()
+  (let* ((lines (mapcar #'car (avy--line-cands)))
+         (line-tree (avy-tree lines avy-keys))
+         (line-list nil))
+    (avy-traverse
+     line-tree
+     (lambda (path _leaf)
+       (let ((str (propertize (apply #'string (reverse path))
+                              'face 'avy-lead-face)))
+         (when (> (length str) 1)
+           (set-text-properties 0 1 '(face avy-lead-face-0) str))
+         (push str line-list))))
+    (nreverse line-list)))
+
+(defun avy--linum-update-window (_ win)
+  "Update line numbers for the portion visible in window WIN."
+  (goto-char (window-start win))
+  (let ((line (line-number-at-pos))
+        (limit (window-end win t))
+        (fmt (cond ((stringp linum-format) linum-format)
+                   ((eq linum-format 'dynamic)
+                    (let ((w (length (number-to-string
+                                      (count-lines (point-min) (point-max))))))
+                      (concat "%" (number-to-string w) "d")))))
+        (width 0)
+        (avy-strs (when avy-linum-mode
+                    (avy--linum-strings))))
+    (run-hooks 'linum-before-numbering-hook)
+    ;; Create an overlay (or reuse an existing one) for each
+    ;; line visible in this window, if necessary.
+    (while (and (not (eobp)) (< (point) limit))
+      (let* ((str
+              (cond (avy-linum-mode
+                     (pop avy-strs))
+                    (fmt
+                     (propertize (format fmt line) 'face 'linum))
+                    (t
+                     (funcall linum-format line))))
+             (visited (catch 'visited
+                        (dolist (o (overlays-in (point) (point)))
+                          (when (equal-including-properties
+                                 (overlay-get o 'linum-str) str)
+                            (unless (memq o linum-overlays)
+                              (push o linum-overlays))
+                            (setq linum-available (delq o linum-available))
+                            (throw 'visited t))))))
+        (setq width (max width (length str)))
+        (unless visited
+          (let ((ov (if (null linum-available)
+                        (make-overlay (point) (point))
+                      (move-overlay (pop linum-available) (point) (point)))))
+            (push ov linum-overlays)
+            (overlay-put ov 'before-string
+                         (propertize " " 'display `((margin left-margin) 
,str)))
+            (overlay-put ov 'linum-str str))))
+      ;; Text may contain those nasty intangible properties, but that
+      ;; shouldn't prevent us from counting those lines.
+      (let ((inhibit-point-motion-hooks t))
+        (forward-line))
+      (setq line (1+ line)))
+    (when (display-graphic-p)
+      (setq width (ceiling
+                   (/ (* width 1.0 (linum--face-width 'linum))
+                      (frame-char-width)))))
+    (set-window-margins win width (cdr (window-margins win)))))
+
+(define-minor-mode avy-linum-mode
+  "Minor mode that uses avy hints for `linum-mode'."
+  :group 'avy
+  (if avy-linum-mode
+      (progn
+        (require 'linum)
+        (advice-add 'linum-update-window :around 'avy--linum-update-window)
+        (linum-mode 1))
+    (advice-remove 'linum-update-window 'avy--linum-update-window)
+    (linum-mode -1)))
+
 (defun avy--line (&optional arg beg end)
   "Select a line.
 The window scope is determined by `avy-all-windows' (ARG negates it).
@@ -1167,7 +1244,10 @@ Narrow the scope to BEG END."
   (let ((avy-action #'identity))
     (avy--process
      (avy--line-cands arg beg end)
-     (avy--style-fn avy-style))))
+     (if avy-linum-mode
+         (progn (message "Goto line:")
+                'ignore)
+       (avy--style-fn avy-style)))))
 
 ;;;###autoload
 (defun avy-goto-line (&optional arg)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]