Summary: Add hook for preset width nlinum
> To precalculate the line number width to avoid horizontal jumps on scrolling:
> ;; Preset width nlinum
> (add-hook 'nlinum-mode-hook
> (lambda ()
> (setq nlinum--width
> (length (number-to-string
> (count-lines (point-min) (point-max)))))))
This page is about displaying line numbers in a buffer, or otherwise indicating line numbers, without actually changing the buffer content. If you just want to work on a specific part of the file and you are accustomed to doing that by showing line numbers in the margin, try BasicNarrowing instead.
See Also: The code on this page just displays line numbers without actually changing the buffer content. NumberLines will add the line numbers to the buffer content.
It could slow down emacs when viewing file with more than tens of thousands of lines. See https://github.com/redguardtoo/emacs.d/issues/178 for bug report and solution.
If you just want the current line number in your modeline (and it isn’t there already), use LineNumberMode by running the
M-x line-number-mode command.
If you just want to know the current line number that the TextCursor is on, you can use the
M-x what-line command (which is usually not on a key). Or use
C-x l) that reports the total number of lines as well as the numbers of lines before and after the current one.
nlinum.el library, available from GNU ELPA (http://elpa.gnu.org/packages/nlinum.html) is meant as a replacement for linum.el, using the jit-lock infrastructure to fix various corner case bugs in linum.el. It should usually be about as fast or faster than linum.el.
To precalculate the line number width to avoid horizontal jumps on scrolling:
;; Preset width nlinum (add-hook 'nlinum-mode-hook (lambda () (setq nlinum--width (length (number-to-string (count-lines (point-min) (point-max)))))))
linum.el works incrementally and can number large files very quickly.
linum.el is distributed with Emacs in versions after 22 (currently only CVS Emacs)
Seems very good, to me. It looks like a good candidate to replace
setnu.el. – DrewAdams
I was wondering if there is way to change the color of the line numbers e.g change color/change background color so that it can be readily differentiated from the neighboring text. Great code. Thanks – Saptarshi Also is there a way to turn on linum mode automatically for any opened file? - Thanks Saptarshi
M-x customize-face RET linum. Also try
M-x global-linum-mode, or append
(add-hook 'find-file-hook (lambda () (linum-mode 1)))to your
(global-linum-mode 1)to your
Another workaround that keeps the appearance of the dynamic linum-format is to use this function which replaces the spaces on the left with zeroes that have the same foreground and background color.
(eval-after-load 'linum '(progn (defface linum-leading-zero `((t :inherit 'linum :foreground ,(face-attribute 'linum :background nil t))) "Face for displaying leading zeroes for line numbers in display margin." :group 'linum) (defun linum-format-func (line) (let ((w (length (number-to-string (count-lines (point-min) (point-max)))))) (concat (propertize (make-string (- w (length (number-to-string line))) ?0) 'face 'linum-leading-zero) (propertize (number-to-string line) 'face 'linum)))) (setq linum-format 'linum-format-func)))
If you cant to just align line numbers to the right as well as have a little padding on the right.
(defun linum-format-func (line) (let ((w (length (number-to-string (count-lines (point-min) (point-max)))))) (propertize (format (format "%%%dd " w) line) 'face 'linum))) (setq linum-format 'linum-format-func)
I, personally, wanted a one-space separation between the line number display and the buffer contents. Couldn’t find a way through the customisation settings. Perhaps it can only be done in Emacs in X, but I don’t use X-based. I’ve found a simple way to do it, however:
(setq width (max width (length str)))
(setq width (max width (+ (length str) 1)))
Putting the following in your .emacs yields almost the same result without modification of linum.el:
(setq linum-format “%d “)
If you want a solid line separator, try something like this:
(setq linum-format “%4d \u2502 “)
linum.elthat is in Emacs 24 (a build from Dec 2011), the default value of
"%6d ", and the digits are right-aligned. – DrewAdams
emacs -Q(Emacs 24), I see no extra space at the left. The the last line number, which has the most digits, is flush with the left side, and all line numbers are right aligned. Here are two images, from the top and bottom of the buffer. What am I missing? – DrewAdams
[[image:SomePageName]]#. Then click `Preview' to show the page and that source text will show you a `?##’ link in the previewed page. Click that link to get to an upload page. – DrewAdams
Or you can set it as a function like the following if you’d like it right justified. The body of the function is modified from linum-0.9x.
(setq linum-format (lambda (line) (propertize (format (let ((w (length (number-to-string (count-lines (point-min) (point-max)))))) (concat “%” (number-to-string w) “d “)) line) ‘face ‘linum)))
You can use
‘linum-before-numbering-hook’ to count and store the number of lines only once per update. Thus you can avoid the somewhat expensive
‘count-lines’ call for each updated line. And a more simplistic constant-width version of the above could look like:
(setq linum-format “%6d “)
Here’s an approach based on the previous suggestion of using
‘linum-before-numbering-hook’ to make the line counting more efficient:
(defvar my-linum-format-string "%4d")
(add-hook 'linum-before-numbering-hook 'my-linum-get-format-string)
(defun my-linum-get-format-string () (let* ((width (length (number-to-string (count-lines (point-min) (point-max))))) (format (concat "%" (number-to-string width) "d"))) (setq my-linum-format-string format)))
(setq linum-format 'my-linum-format)
(defun my-linum-format (line-number) (propertize (format my-linum-format-string line-number) 'face 'linum))
Here’s a better approach. Every buffer has it’s own format variable and the separator use the mode-line face.
(unless window-system (add-hook 'linum-before-numbering-hook (lambda () (setq-local linum-format-fmt (let ((w (length (number-to-string (count-lines (point-min) (point-max)))))) (concat "%" (number-to-string w) "d")))))) (defun linum-format-func (line) (concat (propertize (format linum-format-fmt line) 'face 'linum) (propertize " " 'face 'mode-line))) (unless window-system (setq linum-format 'linum-format-func))
Since most editors number the last line of a file even if it is empty (ie. no characters after the last eol char), I kept having to think about how many lines are in the file. Even Emacs lists the line number in the mode line, but no number appears in the margin. The below patch fixes this:
--- linum.el-rev474.svn000.tmp.el Fri May 08 11:30:24 2009 +++ linum.el Fri May 08 11:29:38 2009 @@ -135,8 +135,15 @@ - (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)) + (let* ((line (line-number-at-pos)) + (limit (window-end win t)) + ;; set empty-line-at-eob flag + (empty-line-at-eob (or (equal ?\n (char-before (point-max))) + (equal (point-min) (point-max)))) + ;; we will automatically number the line at eob if it's not empty + ;; (so we'll say it's already done) + (numbered-line-at-eob (not empty-line-at-eob)) + (fmt (cond ((stringp linum-format) linum-format) + ((eq linum-format 'dynamic) + (let* ((c (count-lines (point-min) (point-max))) + (w (length (number-to-string + (+ c (if empty-line-at-eob 1 0)))))) + (concat "%" (number-to-string w) "d"))))) + (width 0)) @@ -146 +153,2 @@ - (while (and (not (eobp)) (<= (point) limit)) + ;; stop if point>limit, or if eobp and numbered-line-at-eob + (while (and (not (and (eobp) numbered-line-at-eob)) (<= (point) limit)) @@ -165,0 +174,4 @@ + ;; before moving forward, if we're already at eob + (if (eobp) + ;; then we've numbered the empty line + (setq numbered-line-at-eob t))
If this is seen as useful, I’d like for it to be incorporated into the original code. – AdamKerz
I don’t want to use linum on certain major-modes like eshell-mode, wl-summary-mode or compilation-mode. Therefore I tried to hook on these modes, but this doesn’t work for me (maybe a bug?) . So I tried to overwrite the function (linum-on), which works fine. Here is my solution:
(setq linum-disabled-modes-list ‘(eshell-mode wl-summary-mode compilation-mode)) (defun linum-on () (unless (or (minibufferp) (member major-mode linum-disabled-modes-list)) (linum-mode 1)))
Select lines by click-dragging on the margin. Tested with GNU Emacs 23.3
(defvar *linum-mdown-line* nil) (defun line-at-click () (save-excursion (let ((click-y (cdr (cdr (mouse-position)))) (line-move-visual-store line-move-visual)) (setq line-move-visual t) (goto-char (window-start)) (next-line (1- click-y)) (setq line-move-visual line-move-visual-store) ;; If you are using tabbar substitute the next line with ;; (line-number-at-pos)))) (1+ (line-number-at-pos))))) (defun md-select-linum () (interactive) (goto-line (line-at-click)) (set-mark (point)) (setq *linum-mdown-line* (line-number-at-pos))) (defun mu-select-linum () (interactive) (when *linum-mdown-line* (let (mu-line) ;; (goto-line (line-at-click)) (setq mu-line (line-at-click)) (goto-line (max *linum-mdown-line* mu-line)) (set-mark (line-end-position)) (goto-line (min *linum-mdown-line* mu-line)) (setq *linum-mdown* nil)))) (global-set-key (kbd "<left-margin> <down-mouse-1>") 'md-select-linum) (global-set-key (kbd "<left-margin> <mouse-1>") 'mu-select-linum) (global-set-key (kbd "<left-margin> <drag-mouse-1>") 'mu-select-linum)
It is possible to change the linum’s face so that the background has a custom color, but how to fix the background of the left-margin under line numbers so that it has the same color (not the default one)? See the snapshot.
As far as i know that space under the numbers is the “default” face and there is no difference between this color and the background of other buffers. So all you can do is to have the same background color for the “default” and “linum” faces. (You can customize a face with “M-x customize-face”) – AlexKost
If you want to display line numbers for every line you are editing, take a look at setnu.el by KyleJones.
I couldn’t find a function to toggle setnu mode on/off, so I wrote one:
(defun toggle-setnu-mode () (interactive) (if setnu-mode (setnu-mode -1) (setnu-mode 1)))
I have this bound to C-n.
emacs -q, to see if the problem comes from Emacs and the setnu(+) library or from something in your InitFile.
(require 'setnu)instead of
(require 'setnu+). If so, then the problem is not in Lisp:setnu+.el. When you use
‘require’, Emacs loads the required library. Library
setnu+.eldoes its own
setnu.el, so that’s how
setnugets loaded if you require
setnu.el, then the workaround is to just use
(require 'setnu). I suspect the problem is really in
setnu.el, but please find that out.
setnu.el, then please notify KyleJones (the
setnumaintainer). It seems odd that XEmacs would be very fast and GnuEmacs very slow. Perhaps there is a GnuEmacs bug associated with this. It would be worth finding out. – DrewAdams
setnu.el, probably). Do you have the problem when you start with
emacs -q? If not, then probably some other library you use is interfering. Does the problem occur in every mode? – DrewAdams
(custom-set-variables ‘(global-font-lock-mode t nil (font-lock)))
shell> emacs -q
I tried using setnu+ with Aquamacs and when I add newlines to the current buffer, the frame gets wider. (if I delete the newline, it does not decrease the width framesize)
This is fixed if you customize the variable setnu+-fit-frame-flag to nil
(custom-set-variables ‘(setnu+-fit-frame-flag nil))
this will leave the frame alone, and everything is fine.
In soft wrap mode the wrapped line goes under the linenumbers which gives the impression that line numbers are part of the buffer. Also, line numbers participate in syntax coloring which I think is basically wrong.
The highlight problem can be rectified by assigning the line number extent to a new customizable face. I sent this very simple patch to the author who will incorporate it in a later release.
According to the author of sentu+, there is no easy way to get the correct wrapped line behaviour fixed. In fact, the proper place for line-numbers would be on the fringe, not the buffer proper. I am truely surprised noone ever needed this basic feature of a code editor.
Last year I wrote lineno.el, which works on any size files. Rather than making line numbers for the whole buffer, it just displays them for the lines visible in the selected window, updating them as the buffer is edited or the location changed. That way the actual size of the file does not matter. I don’t use it much, but it seems to work well.
On a larger buffer with line numbers, when I do C-x 2 to split the window and then scroll one of them, the numbers in the other window vanish.
Yes, that is the way it works - it draws in the current window. It would not be too hard to make it work in multiple windows, but it didn’t really seem necessary to how I wanted to use it. (you would have to use buffer-window-count to find how many and what windows it is showed in, and replace the local variables with lists)
If I had time to go in and fix something, the highest priority would be to make it work with ediff. It has essentially the same problem there, the numbers are updated from inside post-command-hook, if the buffer is changed in some way that is not a command the update function is not called.
I have added lineno.el to marmalade repo (http://marmalade-repo.org/packages/lineno/0.1) (GOOD LIVE LINK). The file is in the repo as “.tar”, but just change the ending to “.el” - it is not really a TAR file.
I find that the redraw operation to put in the line numbers makes the text “jitter” uncomfortably to the right as I page up and down the buffer. First the text is drawn by Emacs, then the line number routine redraws it shifted right to put the line numbers it. It would be nice to hook into the first rendering, instead of hooking in after the first rendering is already done. But it does put the line numbers in nicely.
I tried linum, nlinim and lineno on the sqlite-amalgamation file sqlite3.c (5MB, 148784 lines). lineno is the only one to be usable on my machine (3.5 GHz Intel Core 7).
– priyadarshan 2014-08-07 13:56 UTC