bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#24880: 26.0.50; buff-menu: Command to unmark all buffers


From: Tino Calancha
Subject: bug#24880: 26.0.50; buff-menu: Command to unmark all buffers
Date: Mon, 14 Nov 2016 19:29:14 +0900 (JST)
User-agent: Alpine 2.20 (DEB 67 2015-01-07)



On Sun, 6 Nov 2016, Drew Adams wrote:

It would be far better, IMHO, to take the approach used by
Dired for this.

In Dired, `M-DEL' (or `* ?') unmarks a specific mark (e.g. D).
Or if it is followed directly by `RET', it unmarks all marks.

This is relevant and useful behavior for all contexts, such
as `*Buffer List*' (aka Buffer Menu), that let you mark
things in more than one way.

Users should be able to use `M-DEL' to selectively remove
any one of the marks (D, S, >,...) _or_ all marks together
(via `M-DEL RET').

The same approach should be taken for other, similar
buffers that list objects that can be marked in more than
one way, whether the objects be buffers (e.g. Ibuffer),
packages, files, bookmarks, or whatever else.

Besides giving users much more control, this provides a
consistent UI.  Users will then use `M-DEL RET' as the
standard way to completely unmark an object.

This is the approach I took with Bookmark+, for instance.
It takes a tiny bit more work to implement, but the result
is far more useful for users.

Thank you.  I totally agree with your suggestion.
I have added a command `Buffer-menu-unmark-all-buffers' which
remove a specific flag.  I bind it to `M-DEL'.
That is for buff-menu.el and ebuff-menu.el.
In bs.el i haven't added such command because this file does
support just one flag: if you push 'd' it doesn't flag for deletion,
it just delete the buffer at point.

This is the amended patch:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From 7a4d4bdfc8a31ff9e4607081cea294c4aa101839 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Mon, 14 Nov 2016 19:11:40 +0900
Subject: [PATCH] buff-menu: Add command to unmark all buffers

Bind 'U' in buff-menu, bs and electric-buff-menu to commands
to unmark all buffers (Bug#24880).
* lisp/emacs-lisp/tabulated-list.el (tabulated-list-header-overlay-p):
New predicate; return non-nil if tabulated-list has a fake header.
* lisp/buff-menu.el (Buffer-menu-unmark-all-buffers):
New command; remove all flags that use a particular mark from all the lines.
Bind it to 'M-DEL'.
(Buffer-menu-unmark-all):
New command; remove all flags from all the lines.  Bind it to 'U'.
(Buffer-menu-marker-char, Buffer-menu-del-char): New variables.
(Buffer-menu-delete, Buffer-menu-mark): Use them.
(Buffer-menu-mode-map): Update menus.
(Buffer-menu-mode): Update mode doc.
* lisp/bs.el (bs-unmark-all, bs-unmark-previous): New commands.
(bs-mode-map): Bind them to 'U' and '<backspace>' respectively.
(bs-mode): Update mode doc.
* lisp/ebuff-menu.el (electric-buffer-menu-mode-map):
Bind Buffer-menu-unmark-all to 'U' and Buffer-menu-unmark-all-buffers
to 'M-DEL'.
(electric-buffer-list): Update mode doc.
* doc/emacs/buffers.texi (Several Buffers): Mention Buffer-menu-unmark-all
and Buffer-menu-unmark-all-buffers.
; * etc/NEWS: Add an entry per each new feature.
---
 doc/emacs/buffers.texi            | 12 +++++++++++
 etc/NEWS                          | 18 +++++++++++++++++
 lisp/bs.el                        | 33 ++++++++++++++++++++++++++++++
 lisp/buff-menu.el                 | 42 ++++++++++++++++++++++++++++++++++++---
 lisp/ebuff-menu.el                |  3 +++
 lisp/emacs-lisp/tabulated-list.el |  6 ++++++
 6 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi
index 2eb837f..561289a 100644
--- a/doc/emacs/buffers.texi
+++ b/doc/emacs/buffers.texi
@@ -411,6 +411,18 @@ Several Buffers
 @kindex DEL @r{(Buffer Menu)}
 Move to the previous line and remove all flags on that line
 (@code{Buffer-menu-backup-unmark}).
+
+@item M-@key{DEL} @var{markchar}
+@findex Buffer-menu-unmark-all-buffers
+@kindex M-DEL @r{(Buffer Menu)}
+Remove all flags that use the character @var{markchar} from all lines
+(@code{Buffer-menu-unmark-all-buffers}).
+
+@item U
+@findex Buffer-menu-unmark-all
+@kindex U @r{(Buffer Menu)}
+Remove all flags from all the lines
+(@code{Buffer-menu-unmark-all}).
 @end table

 @noindent
diff --git a/etc/NEWS b/etc/NEWS
index 03c4990..037dd0d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -269,6 +269,24 @@ the file's actual content before prompting the user.

 * Changes in Specialized Modes and Packages in Emacs 26.1

+** Electric-Buffer-menu
+
++++
+*** Key 'U' is bound to 'Buffer-menu-unmark-all' and key 'M-DEL' is
+bound to 'Buffer-menu-unmark-all-buffers'.
+
+** bs
+
+---
+*** Two new commands 'bs-unmark-all', bound to 'U', and
+'bs-unmark-previous', bound to <backspace>.
+
+** Buffer-menu
+
++++
+*** Two new commands 'Buffer-menu-unmark-all', bound to 'U' and
+'Buffer-menu-unmark-all-buffers', bound to 'M-DEL'.
+
 ** Ibuffer

 ---
diff --git a/lisp/bs.el b/lisp/bs.el
index 8351169..f5f4436 100644
--- a/lisp/bs.el
+++ b/lisp/bs.el
@@ -491,6 +491,8 @@ bs-mode-map
     (define-key map "t"       'bs-visit-tags-table)
     (define-key map "m"       'bs-mark-current)
     (define-key map "u"       'bs-unmark-current)
+    (define-key map "U"       'bs-unmark-all)
+    (define-key map "\177"    'bs-unmark-previous)
     (define-key map ">"       'scroll-right)
     (define-key map "<"       'scroll-left)
     (define-key map "?"       'bs-help)
@@ -635,6 +637,8 @@ bs-mode
 \\[bs-clear-modified] -- clear modified-flag on that buffer.
 \\[bs-mark-current] -- mark current line's buffer to be displayed.
 \\[bs-unmark-current] -- unmark current line's buffer to be displayed.
+\\[bs-unmark-all] -- unmark all buffer lines.
+\\[bs-unmark-previous] -- unmark previous line's buffer to be displayed.
 \\[bs-show-sorted] -- display buffer list sorted by next sort aspect.
 \\[bs-set-configuration-and-refresh] -- ask user for a configuration and \
 apply selected configuration.
@@ -882,6 +886,35 @@ bs-unmark-current
                   (lambda (buf)
                     (setq bs--marked-buffers (delq buf bs--marked-buffers)))))

+(defun bs-unmark-previous (count)
+  "Unmark previous COUNT buffers.
+Move cursor vertically up COUNT lines."
+  (interactive "p")
+  (when (natnump count)
+    (setq count (- count)))
+  (forward-line count)
+  (save-excursion
+    (bs-unmark-current (- count))))
+
+(defun bs-unmark-all ()
+  "Unmark all buffers."
+  (interactive)
+  (let ((marked (string-to-char bs-string-marked))
+        (current (string-to-char bs-string-current))
+        (marked-cur (string-to-char bs-string-current-marked))
+        (unmarked (string-to-char bs-string-show-normally))
+        (inhibit-read-only t))
+    (save-excursion
+      (goto-char (point-min))
+      (forward-line 2)
+      (while (not (eobp))
+        (if (eq (char-after) marked)
+            (subst-char-in-region (point) (1+ (point)) marked unmarked)
+          (when (eq (char-after) marked-cur)
+            (subst-char-in-region (point) (1+ (point)) marked-cur current)))
+        (forward-line 1))
+      (setq bs--marked-buffers nil))))
+
 (defun bs--show-config-message (what)
   "Show message indicating the new showing status WHAT.
 WHAT is a value of nil, `never', or `always'."
diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el
index 4742628..42fd032 100644
--- a/lisp/buff-menu.el
+++ b/lisp/buff-menu.el
@@ -37,6 +37,12 @@ Buffer-menu
   :group 'tools
   :group 'convenience)

+(defvar Buffer-menu-marker-char ?>
+  "The mark character for marked buffers.")
+
+(defvar Buffer-menu-del-char ?D
+  "Character used to flag buffers for deletion.")
+
 (defcustom Buffer-menu-use-header-line t
   "If non-nil, use the header line to display Buffer Menu column titles."
   :type 'boolean
@@ -121,6 +127,8 @@ Buffer-menu-mode-map
     (define-key map "\177" 'Buffer-menu-backup-unmark)
     (define-key map "~" 'Buffer-menu-not-modified)
     (define-key map "u" 'Buffer-menu-unmark)
+    (define-key map "\M-\C-?" 'Buffer-menu-unmark-all-buffers)
+    (define-key map "U" 'Buffer-menu-unmark-all)
     (define-key map "m" 'Buffer-menu-mark)
     (define-key map "t" 'Buffer-menu-visit-tags-table)
     (define-key map "%" 'Buffer-menu-toggle-read-only)
@@ -197,6 +205,12 @@ Buffer-menu-mode-map
     (bindings--define-key menu-map [umk]
       '(menu-item "Unmark" Buffer-menu-unmark
                 :help "Cancel all requested operations on buffer on this line and 
move down"))
+    (bindings--define-key menu-map [umkab]
+      '(menu-item "Unmark all buffers with mark" Buffer-menu-unmark-all-buffers
+                  :help "Cancel a requested operation on buffers"))
+    (bindings--define-key menu-map [umka]
+      '(menu-item "Unmark all" Buffer-menu-unmark-all
+                  :help "Cancel all requested operations on buffers"))
     (bindings--define-key menu-map [mk]
       '(menu-item "Mark" Buffer-menu-mark
                 :help "Mark buffer on this line for being displayed by v 
command"))
@@ -239,6 +253,8 @@ Buffer-menu-mode
 \\[Buffer-menu-execute]    Delete or save marked buffers.
 \\[Buffer-menu-unmark]    Remove all marks from current line.
      With prefix argument, also move up one line.
+\\[Buffer-menu-unmark-all-buffers]    Remove a particular mark from all lines.
+\\[Buffer-menu-unmark-all]    Remove all marks from all lines.
 \\[Buffer-menu-backup-unmark]  Back up a line and remove marks.
 \\[Buffer-menu-toggle-read-only]    Toggle read-only status of buffer on this 
line.
 \\[revert-buffer]    Update the list of buffers.
@@ -346,7 +362,7 @@ Buffer-menu-mark
   "Mark the Buffer menu entry at point for later display.
 It will be displayed by the \\<Buffer-menu-mode-map>\\[Buffer-menu-select] 
command."
   (interactive)
-  (tabulated-list-set-col 0 ">" t)
+  (tabulated-list-set-col 0 (char-to-string Buffer-menu-marker-char) t)
   (forward-line))

 (defun Buffer-menu-unmark (&optional backup)
@@ -356,6 +372,26 @@ Buffer-menu-unmark
   (Buffer-menu--unmark)
   (forward-line (if backup -1 1)))

+(defun Buffer-menu-unmark-all-buffers (mark)
+  "Cancel a requested operation on all buffers."
+  (interactive "cRemove marks (RET means all):")
+  (save-excursion
+    (goto-char (point-min))
+    (when (tabulated-list-header-overlay-p)
+      (forward-line))
+    (while (not (eobp))
+      (let ((xmarks (list (aref (tabulated-list-get-entry) 0)
+                          (aref (tabulated-list-get-entry) 2))))
+        (when (or (char-equal mark ?\r)
+                  (member (char-to-string mark) xmarks))
+          (Buffer-menu--unmark)))
+      (forward-line))))
+
+(defun Buffer-menu-unmark-all ()
+  "Cancel all requested operations on buffers."
+  (interactive)
+  (Buffer-menu-unmark-all-buffers ?\r))
+
 (defun Buffer-menu-backup-unmark ()
   "Move up and cancel all requested operations on buffer on line above."
   (interactive)
@@ -382,12 +418,12 @@ Buffer-menu-delete
       (setq arg 1))
   (while (> arg 0)
     (when (Buffer-menu-buffer)
-      (tabulated-list-set-col 0 "D" t))
+      (tabulated-list-set-col 0 (char-to-string Buffer-menu-del-char) t))
     (forward-line 1)
     (setq arg (1- arg)))
   (while (< arg 0)
     (when (Buffer-menu-buffer)
-      (tabulated-list-set-col 0 "D" t))
+      (tabulated-list-set-col 0 (char-to-string Buffer-menu-del-char) t))
     (forward-line -1)
     (setq arg (1+ arg))))

diff --git a/lisp/ebuff-menu.el b/lisp/ebuff-menu.el
index 5536f94..48be32a 100644
--- a/lisp/ebuff-menu.el
+++ b/lisp/ebuff-menu.el
@@ -55,6 +55,8 @@ electric-buffer-menu-mode-map
     (define-key map "\177" 'Buffer-menu-backup-unmark)
     (define-key map "~" 'Buffer-menu-not-modified)
     (define-key map "u" 'Buffer-menu-unmark)
+    (define-key map "\M-\C-?" 'Buffer-menu-unmark-all-buffers)
+    (define-key map "U" 'Buffer-menu-unmark-all)
     (let ((i ?0))
       (while (<= i ?9)
        (define-key map (char-to-string i) 'digit-argument)
@@ -114,6 +116,7 @@ electric-buffer-list
 \\[Buffer-menu-save] -- mark that buffer to be saved.
 \\[Buffer-menu-delete] or \\[Buffer-menu-delete-backwards] -- mark that buffer 
to be deleted.
 \\[Buffer-menu-unmark] -- remove all kinds of marks from current line.
+\\[Buffer-menu-unmark-all] -- remove all kinds of marks from all lines.
 \\[Electric-buffer-menu-mode-view-buffer] -- view buffer, returning when done.
 \\[Buffer-menu-backup-unmark] -- back up a line and remove marks."
   (interactive "P")
diff --git a/lisp/emacs-lisp/tabulated-list.el 
b/lisp/emacs-lisp/tabulated-list.el
index cf297f1..9523d5e 100644
--- a/lisp/emacs-lisp/tabulated-list.el
+++ b/lisp/emacs-lisp/tabulated-list.el
@@ -259,6 +259,12 @@ tabulated-list-print-fake-header
                     (make-overlay (point-min) (point))))
       (overlay-put tabulated-list--header-overlay 'face 'underline))))

+(defsubst tabulated-list-header-overlay-p (&optional pos)
+  "Return non-nil if there is a fake header.
+Optional arg POS is a buffer position where to look for a fake header;
+defaults to `point-min'."
+  (overlays-at (or pos (point-min))))
+
 (defun tabulated-list-revert (&rest ignored)
   "The `revert-buffer-function' for `tabulated-list-mode'.
 It runs `tabulated-list-revert-hook', then calls `tabulated-list-print'."
--
2.10.2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 26.0.50.2 (x86_64-pc-linux-gnu, GTK+ Version 3.22.2)
 of 2016-11-14
Repository revision: db43613307bb05d0f43d2d5649b5bb2f29876cee





reply via email to

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