emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Temporarily select-window, without updating mode-line face and curso


From: Stefan Kangas
Subject: Re: Temporarily select-window, without updating mode-line face and cursor fill?
Date: Tue, 4 May 2021 19:49:25 -0500

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> We really should simply speed up `line-number-at-pos`.
> It shouldn't be hard.  See below what I do in nlinum.el.

Interesting, it seems much faster at least in this simplistic test:

    (benchmark-run 100000 (line-number-at-pos))
    => (5.868677411999999 0 0.0)

    (benchmark-run 100000 (line-number-at-pos))
    => (0.9772498589999999 1 0.5954873589998897)

Why not to just rename `line-number-at-pos' to
`internal--line-number-at-pos and install something much like the below
as `line-number-at-pos'?

> (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.
> Only works right if point is at BOL."
>   ;; (cl-assert (bolp))
>   (if nlinum-widen
>       (save-excursion
>         (save-restriction
>           (widen)
>           (forward-line 0)              ;In case (point-min) was not at BOL.
>           (let ((nlinum-widen nil))
>             (nlinum--line-number-at-pos))))
>     (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)))
>       (add-hook 'after-change-functions #'nlinum--after-change nil :local)
>       (setq nlinum--line-number-cache (cons (point) pos))
>       pos)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]