Emacs 终止名称以特定字符串开头的缓冲区
我的问题是: 我使用Emacs,得到很多一直都很无用的缓冲区,比如*消息*或*完成* 我想绑定\C-y以关闭所有以*开头的缓冲区,但*shell*(和*shell*Emacs 终止名称以特定字符串开头的缓冲区,emacs,lisp,elisp,Emacs,Lisp,Elisp,我的问题是: 我使用Emacs,得到很多一直都很无用的缓冲区,比如*消息*或*完成* 我想绑定\C-y以关闭所有以*开头的缓冲区,但*shell*(和*shell*)缓冲区除外 为此,我想在.Emacs文件中添加一些Emacs Lisp: (defun string-prefix s1 s2 (if (> (string-length s1) (string-length s2)) nil (string=? s1 (substring s2 0 (string-length
(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测试了字符串前缀
和curry2
,并且过滤器
看起来非常简单。
可悲的是,我无法让杀死无用的正常工作
它显示过滤器:无效函数:(curry2字符串前缀)
现在,问题是我在Emacs Lisp方面有点差劲,除了Scheme,我实际上不使用任何Lisp,在Scheme(麻省理工学院)中,这是有效的:
(filter ((curry2 string-prefix?) "*shell") '("*shell*" "*sh22" "eel"))
;Value 5: ("*shell*")
我想:
修复我的代码的方法
关于如何以不同方式执行此操作的建议
谢谢 请记住,elisp不是scheme,甚至不是常见的lisp。语法和语义是不同的。例如,defun
需要一个用括号括起来的参数列表。此外,在elisp中,咖喱也不太可能
幸运的是,elisp为您想做的大部分事情提供了内置功能。对于string-prefix
,可以使用string-prefix-p
builtin。对于filter
,您可以使用remove if not
,或remove if
进行反向操作
对于currying,您可以使用部分应用
内置功能。要获取与前缀为“”*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")
您可以这样使用它:
(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")
(地图车)
(部分应用“字符串前缀-p”*shell*”)
(“*shell*”foo“*shell*”)
; 导致
(t零t)
(要求“cl”);用于删除如果
(如有必要,请删除。)
(部分应用“字符串前缀-p”*shell*”)
(“*shell*”foo“*shell*”)
; 导致
(“富”)
C-h fkill匹配缓冲区
RET
kill matching buffers是中的一个交互式编译Lisp函数
`文件.el'
(kill匹配缓冲区REGEXP&可选内部-TOO)
终止名称与指定REGEXP匹配的缓冲区。
可选的第二个参数指示是否也终止内部缓冲区
另一种方法:
(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))))
为了安全起见,最好在删除之前查看要删除的内容
在ICICICLES中,默认情况下,C-x k
是一个多命令,您可以使用该命令杀死任何数量的与minibuffer输入匹配的缓冲区。在这种情况下,您可以键入*TAB
,以查看所有以*
开头的缓冲区名称作为完成候选
然后可以通过多种方式缩小匹配范围。当剩下的所有匹配项都是您想要的时,点击C-
删除所有这些缓冲区
在您介绍的示例中,您不希望删除名为*shell…
的缓冲区。因此,在*TAB
之后,您将点击S-SPC
,然后输入另一个模式进行匹配:shell
,然后点击S-TAB
。这仅限于您不想杀死的*shell…
缓冲区。然后点击C-~
减去这些匹配项(补码)。这将留下除shell缓冲区之外的所有缓冲区。点击C-他们都被杀了
您还可以通过在*Completions*
中控制单击各个缓冲区的名称来杀死它们:C-mouse-2
更一般地说,在ICICICLES中,每个读取缓冲区名称的多命令都允许您使用S-delete
(Shift+delete键)杀死候选缓冲区
我发现终止匹配函数
提示我输入未修改的缓冲区,这不是我想要的。下面的函数将杀死匹配前缀的缓冲区(如问题的标题所示)。这不完全是你想要的,但也许像我这样从谷歌来到这里的人会发现这很有用
(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))))
要杀死所有其他缓冲区
(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))
*消息*
缓冲区非常有用:每次Emacs告诉你一些事情时,它都会让它出现在那里,因此你可以复制并粘贴到google上,在google上找到解决方案。还要注意的是,当你可能会使用一些模式(比如magit)时,谁会以一种有用的方式使用这种缓冲区。是的,我最终也保留了那个缓冲区。谢谢你的提示!我最喜欢这种方法。我还添加了一个检查,以保留*Messages*缓冲区。恭喜肖恩!你赢了:)另外,(require'cl)
到底做了什么?它引入了Emacs的公共Lisp包,这就是(非常方便的)“loop”宏所在的地方。整个软件包非常有用;.emacs文件中的第一行是(require'cl)。请参阅@EmmanuelGoldstein,然后您可以添加一些日志记录,以查看您认为无用的缓冲区是否真的是无用的,根据是无用的缓冲区
。例如,您可以在执行上述代码后(例如,运行Emacs时,将消息“Buffer%s%s无用”(Buffer name Buffer)(if(is无用的Buffer Buffer)“is”“is not”))将do(和…
部分更改为do(消息“Buffer%s无用”(Buffer name Buffer)(if(is无用的Buffer Buffer)”更改为“\is not”)
@EmmanuelGoldstein,如果不清楚的话),您仍然需要通过键入M-x
(按住meta/alt并按x
)、kill untible buffers
和返回键来运行kill untible buffers
命令。此外,除非您在运行该命令时碰巧看到缓冲区,否则不会显示缓冲区已被终止。我刚刚启动了Emacs,创建了一些名为*foo*
、*bar*
和*baz*
的缓冲区,然后运行了该命令,这些缓冲区被删除。要更改此代码以删除除名称以星号开头的缓冲区以外的所有缓冲区,只需更改是无用的缓冲区
函数的主体(从第二行的开始括号到下一个到最后一个结束括号