unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
@ 2015-04-29 17:55 Filipp Gunbin
  2015-04-30  7:12 ` Glenn Morris
  0 siblings, 1 reply; 9+ messages in thread
From: Filipp Gunbin @ 2015-04-29 17:55 UTC (permalink / raw)
  To: 20463

[-- Attachment #1: Type: text/plain, Size: 345 bytes --]

What about these new commands in buffer-menu?  I find these useful in
sessions with lots of buffers.

`D m' Prompt for major mode name and delete all buffers in that mode.

`D b' Prompt for regexp and mark for deletion all buffers with matching
names.

`D f' Prompt for regexp and mark for deletion all buffers with mathing
file names.

Filipp


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: buf-menu-by-mode.patch --]
[-- Type: text/x-patch, Size: 5208 bytes --]

diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el
index 91bc038..18264f2 100644
--- a/lisp/buff-menu.el
+++ b/lisp/buff-menu.el
@@ -96,6 +96,9 @@ This is set by the prefix argument to `buffer-menu' and related
 commands.")
 (make-variable-buffer-local 'Buffer-menu-files-only)
 
+(defvar Buffer-menu--regexp-history nil
+  "History list for buffer name regular expressions.")
+
 (defvar Info-current-file) ; from info.el
 (defvar Info-current-node) ; from info.el
 
@@ -130,6 +133,9 @@ commands.")
     (define-key map (kbd "M-s a C-s")   'Buffer-menu-isearch-buffers)
     (define-key map (kbd "M-s a M-C-s") 'Buffer-menu-isearch-buffers-regexp)
     (define-key map (kbd "M-s a C-o") 'Buffer-menu-multi-occur)
+    (define-key map (kbd "D m") 'Buffer-menu-delete-by-major-mode)
+    (define-key map (kbd "D b") 'Buffer-menu-delete-by-buffer-name-regexp)
+    (define-key map (kbd "D f") 'Buffer-menu-delete-by-file-name-regexp)
 
     (define-key map [mouse-2] 'Buffer-menu-mouse-select)
     (define-key map [follow-link] 'mouse-face)
@@ -243,7 +249,13 @@ In Buffer Menu mode, the following commands are defined:
 \\[Buffer-menu-toggle-read-only]    Toggle read-only status of buffer on this line.
 \\[revert-buffer]    Update the list of buffers.
 \\[Buffer-menu-toggle-files-only]    Toggle whether the menu displays only file buffers.
-\\[Buffer-menu-bury]    Bury the buffer listed on this line."
+\\[Buffer-menu-bury]    Bury the buffer listed on this line.
+\\[Buffer-menu-delete-by-major-mode]  Prompt for major mode name and
+     delete all buffers in that mode.
+\\[Buffer-menu-delete-by-buffer-name-regexp]  Prompt for regexp and
+     mark for deletion all buffers with matching names.
+\\[Buffer-menu-delete-by-file-name-regexp]  Prompt for regexp and
+     mark for deletion all buffers with mathing file names."
   (set (make-local-variable 'buffer-stale-function)
        (lambda (&optional _noconfirm) 'fast))
   (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t))
@@ -270,7 +282,7 @@ Menu."
   (interactive "P")
   (switch-to-buffer (list-buffers-noselect arg))
   (message
-   "Commands: d, s, x, u; f, o, 1, 2, m, v; ~, %%; q to quit; ? for help."))
+   "Commands: d, s, x, u; f, o, 1, 2, m, v; ~, %%; D m, D b, D f; q to quit; ? for help."))
 
 (defun buffer-menu-other-window (&optional arg)
   "Display the Buffer Menu in another window.
@@ -282,7 +294,7 @@ ARG, show only buffers that are visiting files."
   (interactive "P")
   (switch-to-buffer-other-window (list-buffers-noselect arg))
   (message
-   "Commands: d, s, x, u; f, o, 1, 2, m, v; ~, %%; q to quit; ? for help."))
+   "Commands: d, s, x, u; f, o, 1, 2, m, v; ~, %%; D m, D b, D f; q to quit; ? for help."))
 
 ;;;###autoload
 (defun list-buffers (&optional arg)
@@ -651,6 +663,70 @@ means list those buffers and no others."
     (setq tabulated-list-entries (nreverse entries)))
   (tabulated-list-init-header))
 
+(defun Buffer-menu--delete-by-predicate (pred)
+  (let ((count 0))
+    (save-excursion
+      (Buffer-menu-beginning)
+      (while (not (eobp))
+	(let ((buffer (tabulated-list-get-id))
+	      (entry (tabulated-list-get-entry)))
+	  (if (funcall pred buffer entry)
+	      (progn
+		(Buffer-menu-delete 1)
+		(setq count (1+ count)))
+	    (forward-line 1)))))
+    (message "Marked %d buffers" count)))
+
+(defun Buffer-menu-delete-by-major-mode (mode)
+  "Mark for deletion all buffers whose mode symbol's name is MODE.  Interactively,
+ask for the MODE, providing completion."
+  (interactive
+   (list
+    (let ((this-line-buffer (tabulated-list-get-id))
+	  modes)
+      (save-excursion
+	(Buffer-menu-beginning)
+	(while (not (eobp))
+	  (let ((buffer (tabulated-list-get-id)))
+	    (add-to-list 'modes (with-current-buffer buffer
+				  (symbol-name major-mode))))
+	  (forward-line 1)))
+      (completing-read
+       "Buffer major mode: " (sort modes (function string<))
+       nil t nil nil
+       (when this-line-buffer
+	 (with-current-buffer this-line-buffer
+	   (symbol-name major-mode)))))))
+  (or mode (error "MODE is nil"))
+  (Buffer-menu--delete-by-predicate
+   (lambda (buf entry)
+     (string= (with-current-buffer buf
+		(symbol-name major-mode))
+	      mode))))
+
+(defun Buffer-menu-delete-by-buffer-name-regexp (regexp)
+  "Mark for deletion all buffers whose buffer name matches REGEXP"
+  (interactive
+   (list
+    (read-regexp "Buffer name regexp: " 'regexp-history-last
+		 Buffer-menu--regexp-history)))
+  (or regexp (error "REGEXP is nil"))
+  (Buffer-menu--delete-by-predicate
+   (lambda (buf entry)
+     (string-match regexp (buffer-name buf)))))
+
+(defun Buffer-menu-delete-by-file-name-regexp (regexp)
+  "Mark for deletion all buffers whose file name matches REGEXP"
+  (interactive
+   (list
+    (read-regexp "File name regexp: " 'regexp-history-last
+		 Buffer-menu--regexp-history)))
+  (or regexp (error "REGEXP is nil"))
+  (Buffer-menu--delete-by-predicate
+   (lambda (buf entry)
+     (and (buffer-file-name buf)
+	  (string-match regexp (buffer-file-name buf))))))
+
 (defun tabulated-list-entry-size-> (entry1 entry2)
   (> (string-to-number (aref (cadr entry1) 4))
      (string-to-number (aref (cadr entry2) 4))))

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-04-29 17:55 bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH] Filipp Gunbin
@ 2015-04-30  7:12 ` Glenn Morris
  2015-04-30 16:06   ` Filipp Gunbin
  0 siblings, 1 reply; 9+ messages in thread
From: Glenn Morris @ 2015-04-30  7:12 UTC (permalink / raw)
  To: Filipp Gunbin; +Cc: 20463

Filipp Gunbin wrote:

> What about these new commands in buffer-menu?  I find these useful in
> sessions with lots of buffers.
>
> `D m' Prompt for major mode name and delete all buffers in that mode.
>
> `D b' Prompt for regexp and mark for deletion all buffers with matching
> names.
>
> `D f' Prompt for regexp and mark for deletion all buffers with mathing
> file names.


IMO the right solution is to replace buffer-menu with the more
featureful ibuffer, which already does all those things and more.

It's a long-standing TODO item; eg
http://lists.gnu.org/archive/html/emacs-devel/2010-10/msg00305.html

(the length of that thread suggests it's one of those "fun" Emacs topics
with more heat than light.)





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-04-30  7:12 ` Glenn Morris
@ 2015-04-30 16:06   ` Filipp Gunbin
  2015-05-01  1:43     ` Stefan Monnier
  0 siblings, 1 reply; 9+ messages in thread
From: Filipp Gunbin @ 2015-04-30 16:06 UTC (permalink / raw)
  To: Glenn Morris; +Cc: 20463

On 30/04/2015 03:12 -0400, Glenn Morris wrote:

> Filipp Gunbin wrote:
>
>> What about these new commands in buffer-menu?  I find these useful in
>> sessions with lots of buffers.
>>
>> `D m' Prompt for major mode name and delete all buffers in that mode.
>>
>> `D b' Prompt for regexp and mark for deletion all buffers with matching
>> names.
>>
>> `D f' Prompt for regexp and mark for deletion all buffers with mathing
>> file names.
>
>
> IMO the right solution is to replace buffer-menu with the more
> featureful ibuffer, which already does all those things and more.
>
> It's a long-standing TODO item; eg
> http://lists.gnu.org/archive/html/emacs-devel/2010-10/msg00305.html
>
> (the length of that thread suggests it's one of those "fun" Emacs topics
> with more heat than light.)

Oh, yes, ibuffer.  Probably it's cool, but for me it's a bit overloaded
with features.

The intent for the commands above was to simplify buffer set cleanup
(which I do at most daily).  Like extended `kill-matching-buffers'.

Maybe add a few commands similar to `kill-matching-buffers' instead of
extending buffer-menu?  A user option could be used to control whether
to query or not (I don't want to be queried 100 times in a row).

Filipp





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-04-30 16:06   ` Filipp Gunbin
@ 2015-05-01  1:43     ` Stefan Monnier
  2015-05-01  2:05       ` Filipp Gunbin
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2015-05-01  1:43 UTC (permalink / raw)
  To: Filipp Gunbin; +Cc: 20463

> The intent for the commands above was to simplify buffer set cleanup
> (which I do at most daily).  Like extended `kill-matching-buffers'.

Have you maybe looked at clean-buffer-list?


        Stefan





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-05-01  1:43     ` Stefan Monnier
@ 2015-05-01  2:05       ` Filipp Gunbin
  2015-05-01  2:20         ` Alexis
  2015-05-01 17:56         ` Stefan Monnier
  0 siblings, 2 replies; 9+ messages in thread
From: Filipp Gunbin @ 2015-05-01  2:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 20463

On 30/04/2015 21:43 -0400, Stefan Monnier wrote:

>> The intent for the commands above was to simplify buffer set cleanup
>> (which I do at most daily).  Like extended `kill-matching-buffers'.
>
> Have you maybe looked at clean-buffer-list?

Not yet, but now I have, and I see that my meaning of "cleanup" is
different from what this command suggests.  I prefer to manage that
manually, so go and kill "all java files" or "all remote files accessed
via ssh" or something like that - with the ability to "post-process" the
selected set manually before killing - that's why I wrote those
commands.  I could provide them as a package, of course if someone else
finds them useful - I'm not sure now whether that is true.

I see there's also "bs" package (not the best name, by the way..), but I
didn't find many differences between standard buffer-menu and this
package, except maybe for sorting commands and more buffer set
configurations in contrast to buffer-menu's "all" or "only files".

Another thing that could be interesting is "show only remote files" and
"kill all remote files".

It would be interesting to know what others use for buffer management.

Filipp





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-05-01  2:05       ` Filipp Gunbin
@ 2015-05-01  2:20         ` Alexis
  2015-05-01 17:56         ` Stefan Monnier
  1 sibling, 0 replies; 9+ messages in thread
From: Alexis @ 2015-05-01  2:20 UTC (permalink / raw)
  To: 20463


Filipp Gunbin <fgunbin@fastmail.fm> writes:

> It would be interesting to know what others use for buffer 
> management.

i use `ibuffer'. Only a fraction of its complete functionality, 
true, but the power and flexibility are there if needed.


Alexis.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-05-01  2:05       ` Filipp Gunbin
  2015-05-01  2:20         ` Alexis
@ 2015-05-01 17:56         ` Stefan Monnier
  2015-05-08 11:18           ` Filipp Gunbin
  1 sibling, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2015-05-01 17:56 UTC (permalink / raw)
  To: Filipp Gunbin; +Cc: 20463

As mentioned by someone else, we'd like to bring Ibuffer and buffer-menu
closer to each other, in terms of code and behavior.

So I'm not opposed to adding the kind of feature you're requesting, but
as much as possible it should be done in a way that narrows the gap
between buffer-menu and Ibuffer.  Code reuse would be ideal.


        Stefan





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-05-01 17:56         ` Stefan Monnier
@ 2015-05-08 11:18           ` Filipp Gunbin
  2016-02-23 10:38             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 9+ messages in thread
From: Filipp Gunbin @ 2015-05-08 11:18 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 20463

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

On 01/05/2015 13:56 -0400, Stefan Monnier wrote:

> As mentioned by someone else, we'd like to bring Ibuffer and buffer-menu
> closer to each other, in terms of code and behavior.
>
> So I'm not opposed to adding the kind of feature you're requesting, but
> as much as possible it should be done in a way that narrows the gap
> between buffer-menu and Ibuffer.  Code reuse would be ideal.

Yes, that should be better than my proposal, I see.

I thought about what I really need once again and I see two cases:

1) kill all log files

2) kill all remote files opened via ssh - they have "/ssh:" in their
names

So I wrote this simple function.  What do you think?

Sorry for the noise if no one is interested.

Filipp


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: kill-matching-buffers-file-name.patch --]
[-- Type: text/x-patch, Size: 816 bytes --]

diff --git a/lisp/files.el b/lisp/files.el
index ef6ac7b..a7b989f 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5827,6 +5827,15 @@ The optional second argument indicates whether to kill internal buffers too."
                  (string-match regexp name))
         (kill-buffer-ask buffer)))))
 
+(defun kill-matching-buffers-file-name (regexp)
+  "Kill buffers whose visited file name matches the specified REGEXP."
+  (interactive "sKill buffers visiting files matching this regular expression: ")
+  (dolist (buffer (buffer-list))
+    (let ((file-name (buffer-file-name buffer)))
+      (when (and file-name 
+                 (string-match regexp file-name))
+        (kill-buffer-ask buffer)))))
+
 \f
 (defun rename-auto-save-file ()
   "Adjust current buffer's auto save file name for current conditions.

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH]
  2015-05-08 11:18           ` Filipp Gunbin
@ 2016-02-23 10:38             ` Lars Ingebrigtsen
  0 siblings, 0 replies; 9+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-23 10:38 UTC (permalink / raw)
  To: Filipp Gunbin; +Cc: 20463, Stefan Monnier

Filipp Gunbin <fgunbin@fastmail.fm> writes:

> +(defun kill-matching-buffers-file-name (regexp)
> +  "Kill buffers whose visited file name matches the specified REGEXP."
> +  (interactive "sKill buffers visiting files matching this regular expression: ")
> +  (dolist (buffer (buffer-list))
> +    (let ((file-name (buffer-file-name buffer)))
> +      (when (and file-name 
> +                 (string-match regexp file-name))
> +        (kill-buffer-ask buffer)))))

I'm not sure this sounds like a generally useful function...  I tend to
think that most users would just be using ibuffer for this stuff, and if
you want to programmatically kill lots of buffers, you don't really want
`kill-buffer-ask'.  It falls between two chairs, I think.

So I'm closing this bug report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-02-23 10:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-29 17:55 bug#20463: 25.0.50; New deletion commands in buffer-menu [PATCH] Filipp Gunbin
2015-04-30  7:12 ` Glenn Morris
2015-04-30 16:06   ` Filipp Gunbin
2015-05-01  1:43     ` Stefan Monnier
2015-05-01  2:05       ` Filipp Gunbin
2015-05-01  2:20         ` Alexis
2015-05-01 17:56         ` Stefan Monnier
2015-05-08 11:18           ` Filipp Gunbin
2016-02-23 10:38             ` Lars Ingebrigtsen

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).