unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Patch to highlight current line number [nlinum.el]
@ 2016-07-15 17:10 Kaushal Modi
  2016-07-16  2:15 ` Stefan Monnier
  0 siblings, 1 reply; 16+ messages in thread
From: Kaushal Modi @ 2016-07-15 17:10 UTC (permalink / raw)
  To: Stefan Monnier, Emacs developers; +Cc: code.falling


[-- Attachment #1.1: Type: text/plain, Size: 4762 bytes --]

Hi Stefan and emacs-devel,

Inspired by the nlinum-relative package[1], I have come up with the below
patch for nlinum that just sets the current line number in a different face
`nlinum-current-line-face'. @SheJinxin, hope this is fine with you.

By submitting this patch to the list, I am looking forward to how the
performance can be improved. Right now, this works as I want but I do this
by flushing the text properties in post-command-hook. I do not know enough
about jit-lock to use it or how to use it to update the face for the
current line number each time the cursor moves across lines. What's the
best way?

I am also looking forward for a review to find a bug because at times, very
rarely (once a month or so), I see about 15-20 consecutive lines set to the
same nlinum-current-line-face. As I cannot reproduce that issue, I don't
know where to start the debug from. Hopefully review of the below patch by
more experienced eyes can help catch this bug?

Thanks.

The result of this patch looks like this in my theme:

[image: pasted1]
The first draft of the patch follows:

diff --git a/packages/nlinum/nlinum.el b/packages/nlinum/nlinum.el
index 98c9cbc..02a7e0b 100644
--- a/packages/nlinum/nlinum.el
+++ b/packages/nlinum/nlinum.el
@@ -41,6 +41,14 @@
 (defvar nlinum--width 2)
 (make-variable-buffer-local 'nlinum--width)

+(defface nlinum-current-line-face
+  '((t :inherit linum :weight bold))
+  "Face for displaying current line."
+  :group 'nlinum)
+
+(defvar-local nlinum--current-line 0
+  "Store current line number before jit-lock.")
+
 ;; (defvar nlinum--desc "")

 ;;;###autoload
@@ -51,7 +59,7 @@ and disable it otherwise.  If called from Lisp, enable
the mode
 if ARG is omitted or nil.

 Linum mode is a buffer-local minor mode."
-  :lighter nil ;; (" NLinum" nlinum--desc)
+  :lighter nil ; (" NLinum" nlinum--desc)
   (jit-lock-unregister #'nlinum--region)
   (remove-hook 'window-configuration-change-hook #'nlinum--setup-window t)
   (remove-hook 'text-scale-mode-hook #'nlinum--setup-window t)
@@ -60,6 +68,7 @@ Linum mode is a buffer-local minor mode."
   (remove-overlays (point-min) (point-max) 'nlinum t)
   ;; (kill-local-variable 'nlinum--ol-counter)
   (kill-local-variable 'nlinum--width)
+  (remove-hook 'post-command-hook #'nlinum--current-line-update t)
   (when nlinum-mode
     ;; FIXME: Another approach would be to make the mode permanent-local,
     ;; which might indeed be preferable.
@@ -67,7 +76,8 @@ Linum mode is a buffer-local minor mode."
     (add-hook 'text-scale-mode-hook #'nlinum--setup-window nil t)
     (add-hook 'window-configuration-change-hook #'nlinum--setup-window nil
t)
     (add-hook 'after-change-functions #'nlinum--after-change nil t)
-    (jit-lock-register #'nlinum--region t))
+    (jit-lock-register #'nlinum--region t)
+    (add-hook 'post-command-hook #'nlinum--current-line-update nil t))
   (nlinum--setup-windows))

 (defun nlinum--face-height (face)
@@ -131,6 +141,22 @@ Linum mode is a buffer-local minor mode."
                          (point-min) (point-max) '(fontified)))))
                   (current-buffer)))

+(defun nlinum--current-line-update ()
+  "Reflush display on current window"
+  (when nlinum-mode
+    (nlinum--after-change)
+    (setq nlinum--current-line (string-to-number (format-mode-line "%l")))
+    ;; Do reflush only in the visible portion in the window, not the whole
+    ;; buffer, when possible.
+    (let* ((start (window-start))
+           (end (window-end))
+           (out-of-range-p (< (point-max) end)))
+      (when out-of-range-p
+        (setq start (point-min))
+        (setq end (point-max)))
+      (with-silent-modifications
+        (remove-text-properties start end '(fontified))))))
+
 ;; (defun nlinum--ol-count ()
 ;;   (let ((i 0))
 ;;     (dolist (ol (overlays-in (point-min) (point-max)))
@@ -215,11 +241,15 @@ Used by the default `nlinum-format-function'."

 (defvar nlinum-format-function
   (lambda (line width)
-    (let ((str (format nlinum-format line)))
+    (let* ((line-diff (abs (- line nlinum--current-line)))
+           (current-line-p (eq line-diff 0))
+           (str (format nlinum-format line)))
       (when (< (length str) width)
         ;; Left pad to try and right-align the line-numbers.
         (setq str (concat (make-string (- width (length str)) ?\ ) str)))
-      (put-text-property 0 width 'face 'linum str)
+      (if current-line-p
+          (put-text-property 0 width 'face 'nlinum-current-line-face str)
+        (put-text-property 0 width 'face 'linum str))
       str))
   "Function to build the string representing the line number.
 Takes 2 arguments LINE and WIDTH, both of them numbers, and should return

[1]: https://github.com/CodeFalling/nlinum-relative
-- 

Kaushal Modi

[-- Attachment #1.2: Type: text/html, Size: 6541 bytes --]

[-- Attachment #2: pasted1 --]
[-- Type: image/png, Size: 46826 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-07-20 20:31 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-15 17:10 Patch to highlight current line number [nlinum.el] Kaushal Modi
2016-07-16  2:15 ` Stefan Monnier
2016-07-18  4:31   ` Kaushal Modi
2016-07-18 13:40     ` Stefan Monnier
2016-07-18 15:28       ` Kaushal Modi
2016-07-18 17:09         ` Stefan Monnier
2016-07-18 22:05           ` Kaushal Modi
2016-07-18 22:55             ` Kaushal Modi
2016-07-19  0:32             ` Stefan Monnier
2016-07-19  5:00               ` Kaushal Modi
2016-07-19 12:28                 ` Stefan Monnier
2016-07-19 12:40                   ` Kaushal Modi
2016-07-20 19:30                     ` Stefan Monnier
2016-07-20 19:38                       ` Kaushal Modi
2016-07-20 20:28                         ` Stefan Monnier
2016-07-20 20:31                           ` Kaushal Modi

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).