I'm working with a file which is zero-indexed. Using M-x linum-mode
, I can get emacs to display line numbers. How can I get emacs to start counting from 0 instead of 1?
2 Answers
This is a cleaner solution:
;; paste this in your init file
(eval-when-compile (require 'cl-lib))
(defun nadvice/linum-update-window (old-fun &rest args)
(cl-letf* ((old-count-lines (symbol-function #'count-lines))
((symbol-function #'count-lines)
(lambda (&rest args) (1- (apply old-count-lines args)))))
(apply old-fun args)))
(defun linum-toggle-zero-indexing ()
(interactive)
(if (advice-member-p #'nadvice/linum-update-window 'linum-update-window)
(advice-remove 'linum-update-window #'nadvice/linum-update-window)
(advice-add 'linum-update-window :around #'nadvice/linum-update-window)))
Use M-x linum-toggle-zero-indexing
RET to toggle the zero-indexing.
Add a 1-
to line-number-at-pos
and count-lines
.
(require 'linum)
(defun linum-update-window (win)
"Update line numbers for the portion visible in window WIN."
(goto-char (window-start win))
(let ((line (1- (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
(1- (count-lines (point-min) (point-max)))))))
(concat "%" (number-to-string w) "d")))))
(width 0))
(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 (if fmt
(propertize (format fmt line) 'face 'linum)
(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)))))
;; open up space in the left margin, if needed, and record that
;; fact as the window-parameter `linum--set-margins'
(let ((existing-margins (window-margins win)))
(when (> width (or (car existing-margins) 0))
(set-window-margins win width (cdr existing-margins))
(set-window-parameter win 'linum--set-margins (window-margins win))))))
-
Thank you very much. Since I'm new to emacs, could you explain how I can use that function in emacs? I think I have to add something like
add-hook
in my .emacs.el file?, but I don't really know how to do that.– shimaoCommented Feb 2, 2016 at 5:00 -
Just stuff it all inside your
.emacs
file, save, and restart Emacs. :) All I did was add1-
in two places --1-
is a function that essentially subtracts 1. Here is the doc-string: "1- is a built-in function in 'C source code'. (1- NUMBER) Return NUMBER minus one. NUMBER may be a number or a marker. Markers are converted to integers." Therequire
statement ensures that the library is loaded, before you essentially re-define one of its functions.– lawlistCommented Feb 2, 2016 at 5:14