Package: emacs;
Reported by: Tino Calancha <tino.calancha <at> gmail.com>
Date: Tue, 29 Nov 2016 09:29:02 UTC
Severity: normal
Tags: patch
Found in version 26.0.50
Done: Tino Calancha <tino.calancha <at> gmail.com>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Tino Calancha <tino.calancha <at> gmail.com> To: 25058 <at> debbugs.gnu.org Subject: bug#25058: 26.0.50; ibuffer-decompose-filter-group: unwanted side effects Date: Tue, 29 Nov 2016 18:28:07 +0900
`ibuffer-decompose-filter-group' has unwanted side effects: it might modify `ibuffer-saved-filter-groups'. emacs -Q -eval "(dired (expand-file-name source-directory))" ;; Evaluate following form: (progn (ibuffer) (setq ibuffer-show-empty-filter-groups nil ibuffer-saved-filter-groups '(("saved-filters" ("Shell" (used-mode . shell-mode)) ("Elisp" (or (used-mode . emacs-lisp-mode) (used-mode . lisp-interaction-mode))) ("Dired" (used-mode . dired-mode)) ("Info" (or (used-mode . help-mode) (used-mode . debugger-mode) (used-mode . Custom-mode) (used-mode . completion-list-mode) (name . "\\`[*]Messages[*]\\'")))))) (ibuffer-switch-to-saved-filter-groups "saved-filters")) ;; Now we call `ibuffer-decompose-filter-group' followed by ;; `ibuffer-filter-disable' and `ibuffer-switch-to-saved-filter-groups'. ;; These commands should bring us back to the initial Ibuffer status: /D Elisp RET // /R ;; Elisp group is missing without calling `ibuffer-delete-saved-filter-groups' M-: (assoc "Elisp" (cdar ibuffer-saved-filter-groups)) RET => nil The reason seems to be that `ibuffer-saved-filter-groups' and `ibuffer-filter-groups' share elements. (eq (cdar ibuffer-saved-filter-groups) ibuffer-filter-groups) => t Then, the destructive function `ibuffer-delete-alist' applied on `ibuffer-filter-groups' will modify the other list as well. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 45f95151de799fc1acd19353a40b22d6783ad1a6 Mon Sep 17 00:00:00 2001 From: Tino Calancha <tino.calancha <at> gmail.com> Date: Tue, 29 Nov 2016 18:14:32 +0900 Subject: [PATCH] ibuffer-decompose-filter-group avoid unwanted side effects * lisp/ibuf-ext.el (ibuffer-delete-alist): Remove it. (ibuffer-remove-alist): New defun; it supersedes 'ibuffer-delete-alist'. All callers changed (Bug#25058). * test/lisp/ibuffer-tests.el (ibuffer-test-Bug25058): Add test. --- lisp/ibuf-ext.el | 23 +++++++++++------------ test/lisp/ibuffer-tests.el | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index 5ef0746..7f35ce6 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -38,12 +38,11 @@ (require 'cl-lib)) ;;; Utility functions -(defun ibuffer-delete-alist (key alist) - "Delete all entries in ALIST that have a key equal to KEY." - (let (entry) - (while (setq entry (assoc key alist)) - (setq alist (delete entry alist))) - alist)) +(defun ibuffer-remove-alist (key alist) + "Remove all entries in ALIST that have a key equal to KEY." + (while (ibuffer-awhen (assoc key alist) + (setq alist (remove it alist)) it)) + alist) ;; borrowed from Gnus (defun ibuffer-remove-duplicates (list) @@ -281,7 +280,7 @@ ibuffer-interactive-filter-by-mode (let ((buf (ibuffer-current-buffer))) (if (assq 'mode ibuffer-filtering-qualifiers) (setq ibuffer-filtering-qualifiers - (ibuffer-delete-alist 'mode ibuffer-filtering-qualifiers)) + (ibuffer-remove-alist 'mode ibuffer-filtering-qualifiers)) (ibuffer-push-filter (cons 'mode (buffer-local-value 'major-mode buf))))) (ibuffer-update nil t)) @@ -556,7 +555,7 @@ ibuffer-generate-filter-groups (append ibuffer-filter-groups (list (cons "Default" nil)))))) ;; (dolist (hidden ibuffer-hidden-filter-groups) - ;; (setq filter-group-alist (ibuffer-delete-alist + ;; (setq filter-group-alist (ibuffer-remove-alist ;; hidden filter-group-alist))) (let ((vec (make-vector (length filter-group-alist) nil)) (i 0)) @@ -640,7 +639,7 @@ ibuffer-decompose-filter-group (interactive (list (ibuffer-read-filter-group-name "Decompose filter group: " t))) (let ((data (cdr (assoc group ibuffer-filter-groups)))) - (setq ibuffer-filter-groups (ibuffer-delete-alist + (setq ibuffer-filter-groups (ibuffer-remove-alist group ibuffer-filter-groups) ibuffer-filtering-qualifiers data)) (ibuffer-update nil t)) @@ -688,7 +687,7 @@ ibuffer-kill-filter-group (ibuffer-aif (assoc name ibuffer-filter-groups) (progn (push (copy-tree it) ibuffer-filter-group-kill-ring) - (setq ibuffer-filter-groups (ibuffer-delete-alist + (setq ibuffer-filter-groups (ibuffer-remove-alist name ibuffer-filter-groups)) (setq ibuffer-hidden-filter-groups (delete name ibuffer-hidden-filter-groups))) @@ -778,7 +777,7 @@ ibuffer-delete-saved-filter-groups (completing-read "Delete saved filter group: " ibuffer-saved-filter-groups nil t)))) (setq ibuffer-saved-filter-groups - (ibuffer-delete-alist name ibuffer-saved-filter-groups)) + (ibuffer-remove-alist name ibuffer-saved-filter-groups)) (ibuffer-maybe-save-stuff) (ibuffer-update nil t)) @@ -949,7 +948,7 @@ ibuffer-delete-saved-filters (completing-read "Delete saved filters: " ibuffer-saved-filters nil t)))) (setq ibuffer-saved-filters - (ibuffer-delete-alist name ibuffer-saved-filters)) + (ibuffer-remove-alist name ibuffer-saved-filters)) (ibuffer-maybe-save-stuff) (ibuffer-update nil t)) diff --git a/test/lisp/ibuffer-tests.el b/test/lisp/ibuffer-tests.el index 3a4def3..260469e 100644 --- a/test/lisp/ibuffer-tests.el +++ b/test/lisp/ibuffer-tests.el @@ -66,5 +66,38 @@ (mapc (lambda (buf) (when (buffer-live-p buf) (kill-buffer buf))) (list buf1 buf2))))) +(ert-deftest ibuffer-test-Bug25058 () + "Test for http://debbugs.gnu.org/25058 ." + (ibuffer) + (let ((orig-filters ibuffer-saved-filter-groups) + (tmp-filters '(("saved-filters" + ("Shell" + (used-mode . shell-mode)) + ("Elisp" + (or + (used-mode . emacs-lisp-mode) + (used-mode . lisp-interaction-mode))) + ("Dired" + (used-mode . dired-mode)) + ("Info" + (or + (used-mode . help-mode) + (used-mode . debugger-mode) + (used-mode . Custom-mode) + (used-mode . completion-list-mode) + (name . "\\`[*]Messages[*]\\'"))))))) + (unwind-protect + (progn + (setq ibuffer-saved-filter-groups tmp-filters) + (ibuffer-switch-to-saved-filter-groups "saved-filters") + (ibuffer-decompose-filter-group "Elisp") + (ibuffer-filter-disable) + (ibuffer-switch-to-saved-filter-groups "saved-filters") + (should (assoc "Elisp" (cdar ibuffer-saved-filter-groups)))) + (setq ibuffer-saved-filter-groups orig-filters) + (ibuffer-awhen (get-buffer "*Ibuffer*") + (and (buffer-live-p it) (kill-buffer it)))))) + + (provide 'ibuffer-tests) ;; ibuffer-tests.el ends here -- 2.10.2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; In GNU Emacs 26.0.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.22.4) of 2016-11-28 Repository revision: 2c8a7e50d24daf19ea7d86f1cfeaa98a41c56085
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.