Does anyone know how if something like this Vim Relative Line Numbers exists for emacs? I use vimpulse, and man, that would be super handy to have! I know some lisp, so if it doesn't, I could try to make my own, if I got a point in the right direction.
Update: Thanks to the correct response, I came up with this, that will show 1 for the current line, and -1 for the previous line, for combining with vimpulse yanks and deletes.
Thanks a ton to all who helped! I know it is not exactly what Vim does, but what good is the Relative line numbers in vim that start at zero?? Silly vim.
(defvar my-linum-current-line-number 0) (setq linum-format 'my-linum-relative-line-numbers) (defun my-linum-relative-line-numbers (line-number) (let ((test2 (1+ (- line-number my-linum-current-line-number)))) (propertize (number-to-string (cond ((<= test2 0) (1- test2)) ((> test2 0) test2))) 'face '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)
By default, Emacs displays the current line number of the point in the mode line. You can toggle this feature off or on with the command M-x line-number-mode , or by setting the variable line-number-mode .
Press the Esc key if you are currently in insert or append mode. Press : (the colon). The cursor should reappear at the lower left corner of the screen next to a : prompt. A column of sequential line numbers will then appear at the left side of the screen.
When you display relative numbers in Vim, each line is numbered by its distance from the cursor. Take a look at the position of the cursor in the image above. This position is marked as 0. Accordingly, lines above and under the cursor are labeled as 1, the next ones 2 and so on.
In Emacs 26.1, there's a built-in line number mode (display-line-numbers-mode)
. Enable it and set (setq display-line-numbers 'relative)
to use relative line numbers.
(2012-03-16: line numbers are now right-aligned, and displayed in the correct face.)
The problem here is that by the time a custom linum-format
function is called, point has already been moved (by linum-update-window
) to the line in question, so we can no longer use it to establish the difference between the two lines; it would just print a zero for every line.
There is a linum-before-numbering-hook
, but this is run after point has been moved to the start of the buffer, so that's not useful for our purpose.
The following code solves the problem by using advice for linum-update
to store the current line number, so that it will be available to the custom linum-format
function.
To right-align the numbers I initially used a hard-coded format string of %3d
on the basis that a single window showing more than 100 lines of code was not terribly likely. If you're a fan of follow-mode
, however (or simply have multiple windows on the same buffer), that circumstance becomes exceedingly likely; so the code now calculates the number of columns required dynamically. The use of linum-before-numbering-hook
makes this more efficient than the approach taken by the default dynamic
linum format.
Note that if you comment out the add-hook
, the faster non-dynamic approach is used.
(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-relative-line-numbers) (defun my-linum-relative-line-numbers (line-number) (let ((offset (- line-number my-linum-current-line-number))) (propertize (format my-linum-format-string offset) 'face '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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With