杀死名称以特定字符串开头的缓冲区

Dan*_*mon 15 lisp emacs elisp

这是我的问题:我使用Emacs并获得大量无用的缓冲区,如*Messages*或*Completions*.

我想绑定\ Cy来关闭所有以*开头的缓冲区,除了*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)
Run Code Online (Sandbox Code Playgroud)

我已经测试string-prefixcurry2使用Scheme,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*")
Run Code Online (Sandbox Code Playgroud)

我想要:

  1. 一种修复我的代码的方法
  2. 关于如何以不同方式做到这一点的建议

谢谢!

phi*_*ils 29

C-h f kill-matching-buffers RET

kill-matching-buffers是`files.el'中的交互式编译Lisp函数.

(kill-matching-buffers REGEXP和可选的INTERNAL-TOO)

终止名称与指定REGEXP匹配的缓冲区.可选的第二个参数指示是否也杀死内部缓冲区.

  • 它一直在问我是否要关闭每个缓冲区(即使未经修改) - 有没有办法避免这种情况? (3认同)
  • +1内置函数,虽然如何使用它的实际示例会更有帮助. (2认同)

Sea*_*ean 13

另一种方法:

(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))))
Run Code Online (Sandbox Code Playgroud)


ata*_*lor 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*")
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

(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")
Run Code Online (Sandbox Code Playgroud)