Skip to content

Commit fbc9a50

Browse files
committed
Allow restoring the original order in 'tabulated-list-mode'
* lisp/emacs-lisp/tabulated-list.el (tabulated-list-sort): Allow restoring the original order (bug#13411). (tabulated-list--sort-by-column-name): Store the original order. (tabulated-list--original-order): New buffer-local variable.
1 parent 335a5fd commit fbc9a50

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

etc/NEWS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,14 @@ summaries will include the failing condition.
21852185

21862186
** Miscellaneous
21872187

2188+
---
2189+
*** 'tabulated-list-mode' can now restore original display order.
2190+
Many commands (like 'C-x C-b') are derived from 'tabulated-list-mode',
2191+
and that mode allow the user to sort on any column. There was
2192+
previously no easy way to get back to the original displayed order
2193+
after sorting, but giving a -1 numerical prefix to the sorting command
2194+
will now restore the original order.
2195+
21882196
+++
21892197
*** New utility function 'insert-into-buffer'.
21902198
This is like 'insert-buffer-substring', but works in the opposite

lisp/emacs-lisp/tabulated-list.el

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636

3737
;;; Code:
3838

39+
(eval-when-compile (require 'cl-lib))
40+
3941
(defgroup tabulated-list nil
4042
"Tabulated-list customization group."
4143
:group 'convenience
@@ -645,18 +647,41 @@ this is the vector stored within it."
645647

646648
(defun tabulated-list-sort (&optional n)
647649
"Sort Tabulated List entries by the column at point.
648-
With a numeric prefix argument N, sort the Nth column."
650+
With a numeric prefix argument N, sort the Nth column.
651+
652+
If the numeric prefix is -1, restore order the list was
653+
originally displayed in."
649654
(interactive "P")
650-
(let ((name (if n
651-
(car (aref tabulated-list-format n))
652-
(get-text-property (point)
653-
'tabulated-list-column-name))))
654-
(if (nth 2 (assoc name (append tabulated-list-format nil)))
655-
(tabulated-list--sort-by-column-name name)
656-
(user-error "Cannot sort by %s" name))))
655+
(if (equal n -1)
656+
;; Restore original order.
657+
(progn
658+
(unless tabulated-list--original-order
659+
(error "Order is already in original order"))
660+
(setq tabulated-list-entries
661+
(sort tabulated-list-entries
662+
(lambda (e1 e2)
663+
(< (gethash e1 tabulated-list--original-order)
664+
(gethash e2 tabulated-list--original-order)))))
665+
(setq tabulated-list-sort-key nil)
666+
(tabulated-list-init-header)
667+
(tabulated-list-print t))
668+
;; Sort based on a column name.
669+
(let ((name (if n
670+
(car (aref tabulated-list-format n))
671+
(get-text-property (point)
672+
'tabulated-list-column-name))))
673+
(if (nth 2 (assoc name (append tabulated-list-format nil)))
674+
(tabulated-list--sort-by-column-name name)
675+
(user-error "Cannot sort by %s" name)))))
657676

658677
(defun tabulated-list--sort-by-column-name (name)
659678
(when (and name (derived-mode-p 'tabulated-list-mode))
679+
(unless tabulated-list--original-order
680+
;; Store the original order so that we can restore it later.
681+
(setq tabulated-list--original-order (make-hash-table))
682+
(cl-loop for elem in tabulated-list-entries
683+
for i from 0
684+
do (setf (gethash elem tabulated-list--original-order) i)))
660685
;; Flip the sort order on a second click.
661686
(if (equal name (car tabulated-list-sort-key))
662687
(setcdr tabulated-list-sort-key
@@ -717,6 +742,8 @@ Interactively, N is the prefix numeric argument, and defaults to
717742

718743
;;; The mode definition:
719744

745+
(defvar tabulated-list--original-order nil)
746+
720747
(define-derived-mode tabulated-list-mode special-mode "Tabulated"
721748
"Generic major mode for browsing a list of items.
722749
This mode is usually not used directly; instead, other major
@@ -757,6 +784,7 @@ as the ewoc pretty-printer."
757784
(setq-local glyphless-char-display
758785
(tabulated-list-make-glyphless-char-display-table))
759786
(setq-local text-scale-remap-header-line t)
787+
(setq-local tabulated-list--original-order nil)
760788
;; Avoid messing up the entries' display just because the first
761789
;; column of the first entry happens to begin with a R2L letter.
762790
(setq bidi-paragraph-direction 'left-to-right)

0 commit comments

Comments
 (0)