* lisp/emacs-lisp/tabulated-list.el: New optional print method
(tabulated-list-print): New optional argument, UPDATE. If non-nil, the list is printed by only adding and deleting the changed entries, instead of erasing the whole buffer. This method is much faster when few or no entries have changed. * doc/lispref/modes.texi (Tabulated List Mode): Document it. * etc/NEWS: Document it.
This commit is contained in:
parent
d38350984e
commit
c205098b6a
3 changed files with 59 additions and 10 deletions
|
@ -1055,7 +1055,7 @@ the above variables (in particular, only after setting
|
|||
@code{tabulated-list-format}).
|
||||
@end defun
|
||||
|
||||
@defun tabulated-list-print &optional remember-pos
|
||||
@defun tabulated-list-print &optional remember-pos update
|
||||
This function populates the current buffer with entries. It should be
|
||||
called by the listing command. It erases the buffer, sorts the entries
|
||||
specified by @code{tabulated-list-entries} according to
|
||||
|
@ -1065,6 +1065,13 @@ specified by @code{tabulated-list-entries} according to
|
|||
If the optional argument @var{remember-pos} is non-@code{nil}, this
|
||||
function looks for the @var{id} element on the current line, if any, and
|
||||
tries to move to that entry after all the entries are (re)inserted.
|
||||
|
||||
If the optional argument @var{update} is non-@code{nil}, this function
|
||||
will only erase or add entries that have changed since the last print.
|
||||
This is several times faster if most entries haven't changed since the
|
||||
last time this function was called. The only difference in outcome is
|
||||
that tags placed via @code{tabulated-list-put-tag} will not be removed
|
||||
from entries that haven't changed (normally all tags are removed).
|
||||
@end defun
|
||||
|
||||
@node Generic Modes
|
||||
|
|
6
etc/NEWS
6
etc/NEWS
|
@ -205,10 +205,16 @@ font, and (iii) the specified window.
|
|||
`message' and related functions from displaying messages the Echo
|
||||
Area. The output is still logged to the *Messages* buffer.
|
||||
|
||||
+++
|
||||
** It is now safe for a mode that derives `tabulated-list-mode' to not
|
||||
call `tabulated-list-init-header', in which case it will have no
|
||||
header.
|
||||
|
||||
+++
|
||||
** `tabulated-list-print' takes a second optional argument, update,
|
||||
which specifies an alternative printing method which is faster when
|
||||
few or no entries have changed.
|
||||
|
||||
|
||||
* Editing Changes in Emacs 25.1
|
||||
|
||||
|
|
|
@ -298,7 +298,7 @@ column. Negate the predicate that would be returned if
|
|||
(lambda (a b) (not (funcall sorter a b)))
|
||||
sorter))))
|
||||
|
||||
(defun tabulated-list-print (&optional remember-pos)
|
||||
(defun tabulated-list-print (&optional remember-pos update)
|
||||
"Populate the current Tabulated List mode buffer.
|
||||
This sorts the `tabulated-list-entries' list if sorting is
|
||||
specified by `tabulated-list-sort-key'. It then erases the
|
||||
|
@ -306,7 +306,14 @@ buffer and inserts the entries with `tabulated-list-printer'.
|
|||
|
||||
Optional argument REMEMBER-POS, if non-nil, means to move point
|
||||
to the entry with the same ID element as the current line and
|
||||
recenter window line accordingly."
|
||||
recenter window line accordingly.
|
||||
|
||||
Non-nil UPDATE argument means to use an alternative printing
|
||||
method which is faster if most entries haven't changed since the
|
||||
last print. The only difference in outcome is that tags will not
|
||||
be removed from entries that haven't changed (see
|
||||
`tabulated-list-put-tag'). Don't use this immediately after
|
||||
changing `tabulated-list-sort-key'."
|
||||
(let ((inhibit-read-only t)
|
||||
(entries (if (functionp tabulated-list-entries)
|
||||
(funcall tabulated-list-entries)
|
||||
|
@ -319,18 +326,47 @@ recenter window line accordingly."
|
|||
(count-screen-lines (window-start) (point))))
|
||||
(setq entry-id (tabulated-list-get-id))
|
||||
(setq saved-col (current-column)))
|
||||
(erase-buffer)
|
||||
(unless tabulated-list-use-header-line
|
||||
(tabulated-list-print-fake-header))
|
||||
;; Sort the entries, if necessary.
|
||||
(setq entries (sort entries sorter))
|
||||
(unless (functionp tabulated-list-entries)
|
||||
(setq tabulated-list-entries entries))
|
||||
;; Without a sorter, we have no way to just update.
|
||||
(when (and update (not sorter))
|
||||
(setq update nil))
|
||||
(if update (goto-char (point-min))
|
||||
;; Redo the buffer, unless we're just updating.
|
||||
(erase-buffer)
|
||||
(unless tabulated-list-use-header-line
|
||||
(tabulated-list-print-fake-header)))
|
||||
;; Finally, print the resulting list.
|
||||
(dolist (elt entries)
|
||||
(and entry-id
|
||||
(equal entry-id (car elt))
|
||||
(setq saved-pt (point)))
|
||||
(apply tabulated-list-printer elt))
|
||||
(let ((id (car elt)))
|
||||
(and entry-id
|
||||
(equal entry-id id)
|
||||
(setq entry-id nil
|
||||
saved-pt (point)))
|
||||
;; If the buffer this empty, simply print each elt.
|
||||
(if (eobp)
|
||||
(apply tabulated-list-printer elt)
|
||||
(while (let ((local-id (tabulated-list-get-id)))
|
||||
;; If we find id, then nothing to update.
|
||||
(cond ((equal id local-id)
|
||||
(forward-line 1)
|
||||
nil)
|
||||
;; If this entry sorts after id (or it's the
|
||||
;; end), then just insert id and move on.
|
||||
((funcall sorter elt
|
||||
;; FIXME: Might be faster if
|
||||
;; don't construct this list.
|
||||
(list local-id (tabulated-list-get-entry)))
|
||||
(apply tabulated-list-printer elt)
|
||||
nil)
|
||||
;; We find an entry that sorts before id,
|
||||
;; it needs to be deleted.
|
||||
(t t)))
|
||||
(let ((old (point)))
|
||||
(forward-line 1)
|
||||
(delete-region old (point)))))))
|
||||
(set-buffer-modified-p nil)
|
||||
;; If REMEMBER-POS was specified, move to the "old" location.
|
||||
(if saved-pt
|
||||
|
|
Loading…
Add table
Reference in a new issue