From d94febc93f840a28187cd9e3831be0deb0fa4c61 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Mon, 29 May 2023 19:23:12 +0300 Subject: [PATCH] Maintain tags when filtering packages Allow 'tabulated-list-mode' derivatives to maintain tags when repopulating the buffer. Enable this option in 'package-menu-mode'. * lisp/emacs-lisp/tabulated-list.el (tabulated-list-tags-alist) (tabulated-list-maintain-tags): New buffer-local variables. (tabulated-list-put-tag): Associate entries with tags in 'tabulated-list-tags-alist'. (tabulated-list-print): Restore tags if 'tabulated-list-maintain-tags' is non-nil. * lisp/emacs-lisp/package.el (package-menu-mode): Enable 'tabulated-list-maintain-tags'. (Bug#63785) --- lisp/emacs-lisp/package.el | 1 + lisp/emacs-lisp/tabulated-list.el | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 69595601bc8..a050f405ba0 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -3145,6 +3145,7 @@ package-menu-mode ("Description" 0 package-menu--description-predicate)]) (setq tabulated-list-padding 2) (setq tabulated-list-sort-key (cons "Status" nil)) + (setq tabulated-list-maintain-tags t) (add-hook 'tabulated-list-revert-hook #'package-menu--refresh nil t) (tabulated-list-init-header) (setq revert-buffer-function 'package-menu--refresh-contents) diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index ddac6ed1746..e1922279039 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -167,6 +167,12 @@ tabulated-list-sort-key non-nil, means to invert the resulting sort.") (put 'tabulated-list-sort-key 'permanent-local t) +(defvar-local tabulated-list-tags-alist nil + "Association between entry ids and their tags in the current buffer.") + +(defvar-local tabulated-list-maintain-tags nil + "When non-nil, maintain tags when repopulating the current tabulated list.") + (defsubst tabulated-list-get-id (&optional pos) "Return the entry ID of the Tabulated List entry at POS. The value is an ID object from `tabulated-list-entries', or nil. @@ -200,6 +206,8 @@ tabulated-list-put-tag (make-string (- tabulated-list-padding width) ?\s)) (truncate-string-to-width tag tabulated-list-padding)))) (delete-region beg (+ beg tabulated-list-padding))))) + (when-let ((id (tabulated-list-get-id))) + (setf (alist-get id tabulated-list-tags-alist) tag)) (if advance (forward-line))) @@ -497,6 +505,14 @@ tabulated-list-print (setq entries (cdr entries))) (when update (delete-region (point) (point-max))) + (when tabulated-list-maintain-tags + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (when-let ((id (tabulated-list-get-id)) + (tag (alist-get id tabulated-list-tags-alist))) + (tabulated-list-put-tag tag)) + (forward-line)))) (set-buffer-modified-p nil) ;; If REMEMBER-POS was specified, move to the "old" location. (if saved-pt -- 2.40.1