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

Posted

技术标签:

【中文标题】关闭 Emacs 中除当前缓冲区之外的所有缓冲区【英文标题】:Close all buffers besides the current one in Emacs 【发布时间】:2011-03-25 22:49:02 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

我还建议将列表缓冲区替换为更高级的 ibuffer:(global-set-key (kbd "C-x C-b") 'ibuffer)。以上将适用于 ibuffer,但您也可以这样做:

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

我还使用 Emacs Wiki 中的这个 sn-p,这将进一步简化这种手动方法:

;; 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)

【讨论】:

如何从ibuffer返回? @phils 我不确定你在问什么,但也许q?使用C-h m 学习键绑定,就像使用任何其他模式一样。【参考方案2】:

来自EmacsWiki: Killing Buffers:

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

编辑:根据 Gilles 的反馈更新

【讨论】:

为什么dired缓冲区没有被杀死?我也喜欢删除它 dired 缓冲区没有设置 buffer-file-name,因此在上面的示例中调用 remove-if-not 将保留 dired 缓冲区(以及暂存缓冲区、术语缓冲区、帮助缓冲区等,任何不访问文件)。我想不出一个简单的测试可以同时关闭文件缓冲区和 dired 缓冲区,你基本上需要第二次调用 mapc 并对 dired 缓冲区进行不同的测试。 一个简单的修改来杀死也被删除的缓冲区(defun kill-other-buffers () "Kill all other buffers." (interactive) (mapc 'kill-buffer (delq (current-buffer) (remove-if-not '(lambda (x) (or (buffer-file-name x) (eq 'dired-mode (buffer-local-value 'major-mode x)))) (buffer-list))))) 看起来这个视频中的人能够做到这一点。他在关闭 GNU 缓冲区和其他缓冲区的同时打开了一个新的 Slime 缓冲区。你知道他是怎么做到的吗? youtube.com/watch?v=BKFcznZ28BE&t=310s remove-if-not 替换cl-remove-if-not 有效,但这不会杀死*helm.. 缓冲区【参考方案3】:

没有办法直接在 emacs 中执行此操作。

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

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

【讨论】:

啊,但这会关闭所有个缓冲区。 (delete (current-buffer) (buffer-list)) 应该给你一个缓冲区列表,你可以映射 kill-buffer 并避免杀死当前缓冲区。 @NickD:是的,工作正常。谢谢!【参考方案4】:

有一个内置命令 m-x kill-some-buffers(我正在使用 24.3.50)在我的下一步 gui 中(未在终端中尝试过,但确定类似)然后您可以批准要杀死哪些缓冲区。

【讨论】:

这在您加载了 1000 多个缓冲区时特别有用。 @ocodo 你是字面意思还是比喻意思【参考方案5】:
 (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)) 将返回一个包含所有现有缓冲区的列表,当前缓冲区位于列表的头部。

这是我在 *** 上的第一个答案。希望对你有帮助:)

【讨论】:

我的朋友们,这就是人们分享他们的想法所产生的优雅解决方案 我不知道这些年来buffer-list 的规范是否发生了变化,但(buffer-list (current-buffer)) 的工作正如上面的答案所表明的那样不会 工作。为当前规范执行C-h f buffer-list RET【参考方案6】:

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

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

当然,然后你将它与 Mx kill-other-buffers RET 一起使用,你也将以下代码粘贴到 .emacs 文件中然后只需按 CxCb

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

【讨论】:

【参考方案7】:

你也可以喜欢这个 - 杀死除当前缓冲区之外的所有缓冲区,*Messages* 和 *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))

【讨论】:

(string-equal (buffer-name) (buffer-name x))(eq x (current-buffer)) 相同,只是效率较低。剩下的or可以简化为(member (buffer-name x) '("*Messages*" "*scratch*"))【参考方案8】:

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

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

(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 以排除。

希望对你有帮助:)

【讨论】:

请参阅 this 了解我的改进解决方案。【参考方案9】:

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

(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)

【讨论】:

【参考方案10】:

这就是你想要的:

C-x 1

来源:https://blasphemousbits.wordpress.com/2007/05/04/learning-emacs-part-4-buffers-windows-and-frames/

【讨论】:

我认为你被否决的原因是 OP 要求关闭其他 buffers,而不是 windows。 Emacs 术语可能有点混乱。

以上是关于关闭 Emacs 中除当前缓冲区之外的所有缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

Emacs常用快捷键

如何在emacs中进行缓冲区拆分后切换焦点?

如何在 Emacs 中保存所有文件(或保存所有缓冲区)?

如何在emacs中自动关闭自动加密模式缓冲区?

如何检查 Emacs 中是不是存在当前缓冲区?

当磁盘上的文件发生更改时,如何让 Emacs 自动刷新所有缓冲区?