这是我的问题: 我使用Emacs并获得大量无用的缓冲区,如* Messages *或* Completions *。
我想绑定\ C-y来关闭所有以*开头的缓冲区,除了* shell *(和* shell *< k>)缓冲区。
要做到这一点,我想在我的.emacs文件中添加一些Emacs-Lisp:
(defun string-prefix s1 s2
(if (> (string-length s1) (string-length s2)) nil
(string=? s1 (substring s2 0 (string-length s1))) ))
(defun curry2
(lambda (f)
(lambda (x)
(lambda (y)
(f x y) ))))
(defun filter
(lambda (f l)
(if (null? l) '()
(let ((rest (cdr l)))
(if (f (car l)) (cons (car l) rest)
rest) ))))
(defun kill-useless (arg)
(interactive "p")
(map 'kill-buffer
(filter
(not ((curry2 string-prefix) "*shell*"))
(list-buffers)
) ))
(global-set-key "\C-y" 'kill-useless)
我已经使用Scheme测试了string-prefix
和curry2
,而filter
似乎非常简单。
可悲的是,我无法让kill-useless
正常工作。
它说filter: Invalid function: (curry2 string-prefix)
。
现在,问题是我对Emacs-Lisp感到厌烦,除了Scheme之外我没有真正使用任何Lisp,而在Scheme(MIT)中,这有效:
(filter ((curry2 string-prefix?) "*shell") '("*shell*" "*sh22" "eel"))
;Value 5: ("*shell*")
我想:
谢谢!
答案 0 :(得分:28)
C-h f kill-matching-buffers
RET
kill-matching-buffers是一个交互式编译的Lisp函数 `files.el”。
(kill-matching-buffers REGEXP& optional INTERNAL-TOO)
终止名称与指定REGEXP匹配的缓冲区。 可选的第二个参数表示是否也杀死内部缓冲区。
答案 1 :(得分:12)
另一种方法:
(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))))
答案 2 :(得分:5)
请记住,elisp不是方案,甚至不是普通的lisp。语法和语义不同。例如,defun
需要括号括起来的参数列表。此外,在elisp中实际上不可能进行currying。
幸运的是,elisp已经建成了你想要做的大部分事情。对于string-prefix
,您可以使用string-prefix-p
内置版。对于filter
,您可以使用remove-if-not
或remove-if
作为反转。
对于currying,您可以使用apply-partially
内置函数。要获得匹配前缀为"*shell*"
的字符串的函数,请尝试以下操作:
(apply-partially 'string-prefix-p "*shell*")
你可以像这样使用它:
(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")
答案 3 :(得分:0)
最好在删除之前查看删除内容,以便安全地播放。
在 Icicles 中,默认情况下C-x k
是一个多命令,可用于杀死与迷你缓冲区输入匹配的任意数量的缓冲区。在这种情况下,您可以键入* TAB
以查看以*
开头的所有缓冲区名称作为完成候选项。
然后,您可以通过多种方式缩小比赛范围。如果剩下的所有匹配项都是您想要的,请点击C-!
删除所有这些缓冲区。
如果您提供,则不希望删除名为*shell...
的缓冲区。因此,在* TAB
之后,您会点击S-SPC
,然后输入另一个匹配的模式:shell
,然后S-TAB
。这只会缩小到 想要杀死的*shell...
个缓冲区。然后,您点击C-~
减去这些匹配(补码)。这会留下除shell缓冲区之外的所有缓冲区。点击C-!
,他们都被杀了。
您也可以通过在*Completions*
C-mouse-2
{@ 1}}中按住Ctrl键点击其名称来杀死个人缓冲区。
更一般地说,在 Icicles 中,每个读取缓冲区名称的多命令都允许您使用S-delete
(Shift + Delete键)来杀死缓冲区候选项
http://www.emacswiki.org/emacs/Icicles_-_Multi-Commands
http://www.emacswiki.org/emacs/Icicles_-_More_About_Multi-Commands
答案 4 :(得分:0)
我发现kill-matching-functions
提示我未经修改的缓冲区,这不是我想要的。下面的函数将终止匹配前缀的缓冲区(如问题标题中所示)。不完全是你想要的,但也许像我这样来自谷歌的人会觉得这很有用。
(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))))
答案 5 :(得分:0)
杀死所有其他缓冲区
(defun px-kill-other-buffers ()
"Kill all other buffers."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
搜索字符串的开头
(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))