关闭 Emacs 中除当前缓冲区之外的所有缓冲区

问题描述 投票:0回答:12

如何关闭 Emacs 中除当前缓冲区之外的所有缓冲区?类似于现代网络浏览器中的“关闭其他选项卡”功能?

emacs elisp
12个回答
109
投票

对于更手动的方法,您可以使用 C-x C-b 列出所有缓冲区,使用 d 标记列表中要删除的缓冲区,然后使用 x 删除它们。

我还建议用更高级的 ibuffer 替换列表缓冲区:

(global-set-key (kbd "C-x C-b") 'ibuffer)
。上面的代码适用于 ibuffer,但你也可以这样做:

m(标记要保留的缓冲区)
t(切换标记)
D(杀死所有标记的缓冲区)

我还使用了 Emacs Wiki 中的这段代码,这将进一步简化此手动方法:

;; Ensure ibuffer opens with point at the current buffer's entry.
(defadvice ibuffer
  (around ibuffer-point-to-most-recent) ()
  "Open ibuffer with cursor pointed to most recent buffer name."
  (let ((recent-buffer-name (buffer-name)))
    ad-do-it
    (ibuffer-jump-to-buffer recent-buffer-name)))
(ad-activate 'ibuffer)

62
投票

来自 EmacsWiki:杀死缓冲区

(defun kill-other-buffers ()
    "Kill all other buffers."
    (interactive)
    (mapc 'kill-buffer 
          (delq (current-buffer) 
                (remove-if-not 'buffer-file-name (buffer-list)))))

编辑:根据 Gilles 的反馈进行更新


22
投票

emacs 中没有直接执行此操作的方法。

您可以编写一个函数来执行此操作。以下将关闭所有缓冲区:

(defun 关闭所有缓冲区 ()
  (交互的)
  (mapc 'kill-buffer(缓冲区列表)))

19
投票

有一个内置命令 m-x

kill-some-buffers
(我正在使用 24.3.50)在我的下一步 gui(未在终端中尝试过,但确信它是相似的)中,您可以批准要杀死哪些缓冲区。


12
投票
 (defun only-current-buffer () 
   (interactive)
   (let ((tobe-killed (cdr (buffer-list (current-buffer)))))
     (while tobe-killed
       (kill-buffer (car tobe-killed))
       (setq tobe-killed (cdr tobe-killed)))))

它按您的预期工作。

阅读@Starkey的回答后,我认为这样会更好:

(defun only-current-buffer () 
  (interactive)                                                                   
    (mapc 'kill-buffer (cdr (buffer-list (current-buffer)))))

(buffer-list (current-buffer)) 将返回一个包含所有现有缓冲区的列表,当前缓冲区位于列表的头部。

这是我在 StackOverflow 上的第一个回答。希望有帮助:)


7
投票

我发现这个解决方案是最简单的。这将删除除当前缓冲区之外的所有缓冲区。您必须将此代码添加到您的

.emacs
文件

(defun kill-other-buffers ()
      "Kill all other buffers."
      (interactive)
      (mapc 'kill-buffer (delq (current-buffer) (buffer-list))))

当然,然后您可以将其与 M-x

kill-other-buffers
RET 一起使用,也可以将以下代码粘贴到
.emacs
文件中,然后只需按 C-xC-b

(global-set-key (kbd "C-x C-b") 'kill-other-buffers)

2
投票

你也可以喜欢这个 - 杀死除当前缓冲区之外的所有缓冲区,*消息*和*scratch*(它们很方便,我称之为“工具包”),也关闭多余的窗口,让你知道哪个窗口是哪个当前缓冲区。

(defun my/kill-all-buffers-except-toolbox ()
  "Kill all buffers except current one and toolkit (*Messages*, *scratch*). Close other windows."
  (interactive)
  (mapc 'kill-buffer (remove-if
                       (lambda (x)
                         (or
                           (eq x (current-buffer))
                           (member (buffer-name x) '("*Messages*" "*scratch*"))))
                       (buffer-list)))
  (delete-other-windows))

1
投票

我已经使用 crux-kill-other-buffers 几个月了。

但我希望重复的缓冲区也被删除。 @Euge 和 @wenjun.yan 的答案解决了这个问题。但它会删除特殊缓冲区(例如 *git-credential-cache--daemon*、*scratch*、helm 操作等)。所以我想出了这个(当前)解决方案。

(defun aza-kill-other-buffers ()
  "Kill all buffers but current buffer and special buffers"
  (interactive)
  (dolist (buffer (delq (current-buffer) (buffer-list)))
    (let ((name (buffer-name buffer)))
      (when (and name (not (string-equal name ""))
             (/= (aref name 0) ?\s)
             (string-match "^[^\*]" name))
        (funcall 'kill-buffer buffer)))))

受到kill-matching-buffers的启发。如果您愿意,您可以在其他缓冲区名称上添加更多

condition
来排除。

希望有帮助:)


0
投票

我多年来一直使用此列表中的解决方案之一,但现在我有了自己的新解决方案。

(defun kill-all-file-buffers ()
  "Kills all buffers that are open to files. Does not kill
modified buffers or special buffers."
  (interactive)
  (mapc 'kill-buffer (cl-loop for buffer being the buffers
                              when (and (buffer-file-name buffer)
                                        (not (buffer-modified-p buffer)))
                              unless (eq buffer (current-buffer))
                              collect buffer)))

cl-loop 将缓冲区内置为一个集合,您可以对其进行迭代。它让您有机会解析出您不想关闭的任何内容。在这里,我确保它不会关闭您修改的任何内容,并且它使用缓冲区文件名而不仅仅是缓冲区名称,因此它不会杀死特殊缓冲区。我还添加了一个“除非”来取出当前缓冲区(尽管您显然可以将其添加到“何时”,我只是认为这更清楚)。

但是对于更通用的解决方案,我们可以将其定义为宏,并传入一个将应用于所有这些缓冲区的函数。

(defmacro operate-on-file-buffers (func)
  "Takes any function that takes a single buffer as an argument
and applies that to all open file buffers that haven't been
modified, and aren't the current one."
  `(mapc ,func (cl-loop for buffer being the buffers
                            when (and (buffer-file-name buffer)
                                      (not (buffer-modified-p buffer)))
                            unless (eq buffer (current-buffer))
                            collect buffer)))

现在如果你想杀死所有与此匹配的缓冲区,你可以这样调用它

(operate-on-file-buffers 'kill-buffer)

0
投票
(defun px/kill-other-buffers ()
  "Kill all other buffers."
  (interactive)
  (mapc (lambda (buffer)
          (when (and (buffer-file-name buffer) (not (eq buffer (current-buffer))))
            (kill-buffer buffer)))
        (buffer-list)))

0
投票
(defvar my/kill-buffer-exceptions '("Messages" "emacs-file" "scratch"))
(defun my/kill-buffer-testfn (key lcar)
  ;; (print (list lcar key (string-match-p (regexp-quote key) lcar)))
  (string-match-p (regexp-quote key) lcar))

(defun my/kill-other-buffers ()
    "Kill all other buffers."
    (interactive)
    (mapc 'kill-buffer
          (delq (current-buffer) ; filter current buder
                ;; filter alive and not system
                (seq-filter (lambda (b) (and (buffer-live-p b) ; filter alive
                                             (/= (aref (buffer-name b) 0) ?\s) ; filter system
                                             ;; filter exceptions
                                             (not (seq-contains-p my/kill-buffer-exceptions
                                                             (downcase (buffer-name b))
                                                             #'my/kill-buffer-testfn))))
                            (seq-uniq (buffer-list))))))

(global-set-key (kbd "C-!") #'my/kill-other-buffers)

© www.soinside.com 2019 - 2024. All rights reserved.