Here\'s my problem: I use Emacs and get lots of buffers that are pretty useless all the time, like *Messages* or *Completions*.
I want to bind \\C-y to close all buf
Keep in mind elisp isn't scheme, or even common lisp. The syntax and semantics are different. For example, defun
requires a parameters list surrounded by parentheses. Also, currying isn't really possible in elisp.
Fortunately, elisp has builtins for most of what you want to do. For string-prefix
you can use the string-prefix-p
builtin. For filter
, you can use remove-if-not
, or remove-if
for the inverse.
For the currying you can use the apply-partially
builtin function. To get a function that matches strings with the prefix "*shell*"
, try something like this:
(apply-partially 'string-prefix-p "*shell*")
You can use it like this:
(mapcar
(apply-partially 'string-prefix-p "*shell*")
'("*shell*" "foo" "*shell*<2>"))
; results in
(t nil t)
(require 'cl) ; for remove-if
(remove-if
(apply-partially 'string-prefix-p "*shell*")
'("*shell*" "foo" "*shell*<2>"))
; results in
("foo")
An alternate approach:
(require 'cl)
(defun is-useless-buffer (buffer)
(let ((name (buffer-name buffer)))
(and (= ?* (aref name 0))
(not (string-match "^\\*shell\\*" name)))))
(defun kill-useless-buffers ()
(interactive)
(loop for buffer being the buffers
do (and (is-useless-buffer buffer) (kill-buffer buffer))))
To kill all other buffers
(defun px-kill-other-buffers ()
"Kill all other buffers."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
To search the beginning of a string
(defun string-starts-with-p (string prefix)
"Return t if STRING starts with prefix."
(and
(string-match (rx-to-string `(: bos ,prefix) t) string)
t))
C-h f kill-matching-buffers
RET
kill-matching-buffers is an interactive compiled Lisp function in `files.el'.
(kill-matching-buffers REGEXP &optional INTERNAL-TOO)
Kill buffers whose name matches the specified REGEXP. The optional second argument indicates whether to kill internal buffers too.
I found kill-matching-functions
prompted me for unmodified buffers, which isn't what I wanted. The function below will kill buffers matching a prefix (as in the title of the question). Not exactly what you wanted, but maybe people like me who come here from Google will find this useful.
(require 'cl)
(defun kill-buffers-with-prefix (prefix)
"Kill buffers whose names start with the given prefix"
(interactive "sPrefix to kill: ")
(loop for buffer in (buffer-list)
do (if (string-prefix-p prefix (buffer-name buffer))
(kill-buffer buffer))))
It can be a good idea to see what you will delete before deleting it, to play safe.
In Icicles, by default C-x k
is a multi-command that you can use to kill any number of buffers that match your minibuffer input. In this case, you would type * TAB
to see all buffer names starting with *
as completion candidates.
You can then narrow the matches, in several ways. When all of the matches remaining are what you want, hit C-!
to delete all of those buffers.
In the case you presented, you do not want to delete buffers named *shell...
. So after * TAB
you would hit S-SPC
and then enter another pattern to match: shell
, then S-TAB
. That narrows to only the *shell...
buffers that you do not want to kill. You then hit C-~
to subtract those matches (complement). That leaves all of the buffers except the shell buffers. Hit C-!
and they're all killed.
You can also kill individual buffers by just control-clicking their names in *Completions*
: C-mouse-2
.
More generally, in Icicles every multi-command that reads a buffer name lets you use S-delete
(Shift + the Delete key) to kill buffer candidates.
http://www.emacswiki.org/emacs/Icicles_-_Multi-Commands
http://www.emacswiki.org/emacs/Icicles_-_More_About_Multi-Commands