emacselisp

Colorize current line number


I am using global-linum-mode for line numbers. It would be nice if the line number of the current line was highlighted with different color (and/or also different background). Anybody has an idea how to achieve this?

Thank you!


Solution

  • I've derived this answer from my previous answer to Relative Line Numbers In Emacs, as it deals with the same issue of remembering the current line number during the linum format process.

    I'm inheriting from the linum face, but using the background colour from hl-line. If the foreground and background don't match nicely, you can assign a foreground colour explicitly with
    M-x customize-face RET my-linum-hl RET

    (require 'hl-line)
    
    (defface my-linum-hl
      `((t :inherit linum :background ,(face-background 'hl-line nil t)))
      "Face for the current line number."
      :group 'linum)
    
    (defvar my-linum-format-string "%3d")
    
    (add-hook 'linum-before-numbering-hook 'my-linum-get-format-string)
    
    (defun my-linum-get-format-string ()
      (let* ((width (1+ (length (number-to-string
                                 (count-lines (point-min) (point-max))))))
             (format (concat "%" (number-to-string width) "d")))
        (setq my-linum-format-string format)))
    
    (defvar my-linum-current-line-number 0)
    
    (setq linum-format 'my-linum-format)
    
    (defun my-linum-format (line-number)
      (propertize (format my-linum-format-string line-number) 'face
                  (if (eq line-number my-linum-current-line-number)
                      'my-linum-hl
                    'linum)))
    
    (defadvice linum-update (around my-linum-update)
      (let ((my-linum-current-line-number (line-number-at-pos)))
        ad-do-it))
    (ad-activate 'linum-update)
    

    As with that other answer, this is more efficient in generating the dynamic width than the default dynamic format, but you can use a static width for maximum speed by commenting out the line (add-hook linum-before-numbering-hook 'my-linum-get-format-string) (and optionally modify the initial value of my-linum-format-string to set your preferred width).