From: Tino Calancha <tino.calancha@gmail.com>
To: Drew Adams <drew.adams@oracle.com>
Cc: 24880@debbugs.gnu.org, Tino Calancha <tino.calancha@gmail.com>
Subject: bug#24880: 26.0.50; buff-menu: Command to unmark all buffers
Date: Mon, 14 Nov 2016 19:29:14 +0900 (JST) [thread overview]
Message-ID: <alpine.DEB.2.20.1611141920190.23355@calancha-pc> (raw)
In-Reply-To: <f2ea1e61-4f88-4dcf-b73c-a8d7f85f2336@default>
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
next prev parent reply other threads:[~2016-11-14 10:29 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-05 10:04 bug#24880: 26.0.50; buff-menu: Command to unmark all buffers Tino Calancha
2016-11-05 10:17 ` Eli Zaretskii
2016-11-06 12:21 ` Tino Calancha
2016-11-06 17:22 ` Drew Adams
2016-11-14 10:29 ` Tino Calancha [this message]
2016-11-15 16:03 ` Eli Zaretskii
2016-11-16 10:09 ` Tino Calancha
2016-11-18 10:09 ` Eli Zaretskii
2016-11-18 10:17 ` Tino Calancha
2016-11-18 11:05 ` Eli Zaretskii
2016-11-07 18:38 ` Eli Zaretskii
2016-11-22 6:30 ` Tino Calancha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.DEB.2.20.1611141920190.23355@calancha-pc \
--to=tino.calancha@gmail.com \
--cc=24880@debbugs.gnu.org \
--cc=drew.adams@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).