Закройте все буферы, кроме текущего в Emacs


92

Как мне закрыть в Emacs все буферы, кроме текущего? Похоже на функцию «Закрыть другие вкладки» в современных веб-браузерах?

Ответы:


100

Для более ручного подхода вы можете перечислить все буферы с помощью 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)

Как я могу вернуться ibuffer? @phils
ALPER

1
Я не уверен, о чем вы спрашиваете, но может быть q? Используйте C-h mдля изучения сочетаний клавиш, как и в любом другом режиме.
филс

53

Из EmacsWiki: Буферы уничтожения :

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

Изменить : обновлено с учетом отзывов Жиля


3
Почему dired буфер не убивается? Я тоже хочу удалить это
swdev

dired буферы не устанавливаются, buffer-file-nameи поэтому вызов remove-if-notв приведенном выше примере сохранит dired буферы (а также рабочий буфер, термические буферы, справочные буферы и т.д., все, что не обращается к файлу). Я не могу придумать простой тест, который бы закрыл как файловые буферы, так и dired буферы, вам понадобится в основном целый второй вызов mapc с другим тестом для dired буферов.
robru

простая модификация, (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)))))
убивающая

Похоже, что на этом видео мужчина на это способен. Он открывает новый буфер Slime, закрывая при этом буферы GNU и другие. Ты хоть представляешь, как он это делает? youtube.com/watch?v=BKFcznZ28BE&t=310s
MadPhysicist

Замена cl-remove-if-notна remove-if-notработает, но при этом не убивает *helm..буферы
alper

21

В emacs нет возможности сделать это напрямую.

Вы можете написать для этого функцию. Следующее закроет все буферы:

(defun закрыть все-буферы ()
  (интерактивный)
  (mapc 'kill-buffer (список-буферов)))

4
Ах, но это закроет все буферы.
Шридхар Ратнакумар

(delete (current-buffer) (buffer-list))должен предоставить вам список буферов, который вы можете сопоставить kill-bufferи избежать уничтожения текущего буфера.
NickD

16

Существует встроенная команда m- x kill-some-buffers(я использую 24.3.50). В моем графическом интерфейсе nextstep (не пробовал в терминале, но уверен, что он похож) вы можете затем утвердить, какие буферы убивать.


2
Это особенно полезно, когда у вас загружено более 1000 буферов.
ocodo 06

11
 (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. Надеюсь, это поможет :)


2
И вот как изящные решения возникают, друзья мои, люди,
Крис Кларк,

Я не знаю, buffer-listизменилась ли спецификация с годами, но (buffer-list (current-buffer))работать, как указывает ответ выше, НЕ будет работать. Сделайте C-h f buffer-list RETдля текущей спецификации.
NickD

4

Я нашел это решение самым простым. Это удаляет все буферы, кроме текущего. Вы должны добавить этот код в свой .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)

1

Несколько месяцев я использую crux-kill-other-buffers .

Но я хочу, чтобы удаленные буферы тоже были удалены. Ответы @ 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)))))

Вдохновленный буферами сопоставления уничтожений . Вы можете добавить conditionдругие имена буфера для исключения, если хотите.

Надеюсь, это поможет :)


Смотрите здесь мое улучшенное решение.
azzamsa

0

Вам также может понравиться этот - уничтожьте все буферы, кроме текущего, * Сообщения * и * царапины * (которые удобно иметь, я называю их «инструментарием»), также закройте избыточные окна, оставив вам одно окно, которое текущее буфер.

(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
                           (string-equal (buffer-name) (buffer-name x))
                           (string-equal "*Messages*" (buffer-name x))
                           (string-equal "*scratch*" (buffer-name x))))
                       (buffer-list)))
  (delete-other-windows))

(string-equal (buffer-name) (buffer-name x))то же самое (eq x (current-buffer)), только менее эффективно. Остальное orможно упростить до(member (buffer-name x) '("*Messages*" "*scratch*"))
Стефан

-4

1
Я думаю, причина, по которой вы проголосовали против, заключалась в том, что OP просит закрыть другие буферы , а не окна . Терминология Emacs может немного сбивать с толку.
fengshaun
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.