+(defvar nlinum--line-number-cache nil)
+(make-variable-buffer-local 'nlinum--line-number-cache)
+
+;; We could try and avoid flushing the cache at every change, e.g. with:
+;; (defun nlinum--before-change (start _end)
+;; (if (and nlinum--line-number-cache
+;; (< start (car nlinum--line-number-cache)))
+;; (save-excursion (goto-char start) (nlinum--line-number-at-pos))))
+;; But it's far from clear that it's worth the trouble. The current simplistic
+;; approach seems to be good enough in practice.
+
+(defun nlinum--after-change (&rest _args)
+ (setq nlinum--line-number-cache nil))
+
+(defun nlinum--line-number-at-pos ()
+ "Like `line-number-at-pos' but sped up with a cache."
+ ;; (assert (bolp))
+ (let ((pos
+ (if (and nlinum--line-number-cache
+ (> (- (point) (point-min))
+ (abs (- (point) (car nlinum--line-number-cache)))))
+ (funcall (if (> (point) (car nlinum--line-number-cache))
+ #'+ #'-)
+ (cdr nlinum--line-number-cache)
+ (count-lines (point) (car nlinum--line-number-cache)))
+ (line-number-at-pos))))
+ ;;(assert (= pos (line-number-at-pos)))
+ (setq nlinum--line-number-cache (cons (point) pos))
+ pos))
+
+(defcustom nlinum-format "%d"
+ "Format of the line numbers.
+Used by the default `nlinum-format-function'."
+ :type 'string
+ :group 'linum)
+
+(defvar nlinum-format-function
+ (lambda (line width)
+ (let ((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)
+ str))
+ "Function to build the string representing the line number.
+Takes 2 arguments LINE and WIDTH, both of them numbers, and should return
+a string. WIDTH is the ideal width of the result. If the result is larger,
+it may cause the margin to be resized and line numbers to be recomputed.")
+