Đóng tất cả các bộ đệm ngoài bộ đệm hiện tại trong Emacs


91

Làm cách nào để đóng tất cả ngoại trừ bộ đệm hiện tại trong Emacs? Tương tự như tính năng "Đóng các tab khác" trong các trình duyệt web hiện đại?

Câu trả lời:


99

Đối với cách tiếp cận thủ công hơn, bạn có thể liệt kê tất cả các bộ đệm bằng C-x C-b, đánh dấu các bộ đệm trong danh sách để xóa bằng dvà sau đó sử dụng xđể xóa chúng.

Tôi cũng khuyên bạn nên thay thế danh sách-đệm với ibuffer cao cấp hơn: (global-set-key (kbd "C-x C-b") 'ibuffer). Ở trên sẽ hoạt động với ibuffer, nhưng bạn cũng có thể làm điều này:

m(đánh dấu vùng đệm bạn muốn giữ lại)
t(dấu chuyển đổi)
D( xóa tất cả các vùng đệm đã đánh dấu)

Tôi cũng sử dụng đoạn mã này từ Emacs Wiki, đoạn mã này sẽ hợp lý hóa hơn nữa phương pháp thủ công này:

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

Tôi có thể trở về từ ibufferđâu? @phils
alper

1
Tôi không chắc bạn đang hỏi gì, nhưng có thể q? Sử dụng C-h mđể tìm hiểu các liên kết chính, giống như với bất kỳ chế độ nào khác.
phils

53

Từ 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)))))

Chỉnh sửa : cập nhật với phản hồi từ Gilles


3
Tại sao bộ đệm dired không bị giết? Tôi cũng muốn xóa nó
swdev

bộ đệm dired không được thiết lập buffer-file-namevà do đó lệnh gọi đến remove-if-nottrong ví dụ trên sẽ bảo toàn bộ đệm dired (cũng như bộ đệm đầu, bộ đệm thuật ngữ, bộ đệm trợ giúp, v.v., bất kỳ thứ gì không truy cập vào tệp). Tôi không thể nghĩ ra một bài kiểm tra dễ dàng có thể đóng cả bộ đệm tệp và bộ đệm dired, về cơ bản bạn cần một lệnh gọi toàn bộ thứ hai của mapc với một bài kiểm tra khác cho bộ đệm dired.
robru

một sửa đổi đơn giản để giết những bộ đệm cũng bị đào thải (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)))))
frinkr

Có vẻ như trong video này, người đàn ông có thể làm được điều đó. Anh ta mở một bộ đệm Slime mới trong khi đóng bộ đệm GNU và những bộ đệm khác. Bạn có biết cách anh ấy làm điều đó không? youtube.com/watch?v=BKFcznZ28BE&t=310s
MadPhysicist

Thay thế cl-remove-if-notbằng remove-if-notcác tác phẩm nhưng điều này không giết *helm..bộ đệm
alper

21

Không có cách nào trực tiếp trong emacs để làm điều này.

Bạn có thể viết một hàm để làm điều này. Thao tác sau sẽ đóng tất cả các bộ đệm:

(làm mờ bộ đệm đóng tất cả ()
  (tương tác)
  (mapc 'kill-buffer (buffer-list)))

4
À, nhưng điều này sẽ đóng tất cả các bộ đệm.
Sridhar Ratnakumar

14

Có một lệnh tích hợp sẵn m- x kill-some-buffers(Tôi đang sử dụng 24.3.50) Trong gui bước tiếp theo của tôi (không thử trong thiết bị đầu cuối nhưng chắc chắn rằng nó tương tự) sau đó bạn có thể phê duyệt bộ đệm nào cần giết.


2
Điều này đặc biệt hữu ích khi bạn có hơn 1000 bộ đệm được tải.
ocodo

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

Nó hoạt động như bạn mong đợi.

Và sau khi đọc câu trả lời của @ Starkey, tôi nghĩ điều này sẽ tốt hơn:

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

(buffer-list (bộ đệm hiện tại)) sẽ trả về một danh sách chứa tất cả các bộ đệm hiện có, với bộ đệm hiện tại ở đầu danh sách.

Đây là câu trả lời đầu tiên của tôi trên StackOverflow. Hy vọng nó giúp :)


2
Và điều này bạn bè của tôi là cách tao nhã giải pháp phát sinh từ những người chia sẻ ý tưởng của họ
Chris Clark

4

Tôi thấy giải pháp này là giải pháp đơn giản nhất. Thao tác này sẽ xóa mọi bộ đệm ngoại trừ bộ đệm hiện tại. Bạn phải thêm mã này vào .emacstệp của mình

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

Tất nhiên, sau đó bạn sử dụng nó với M-x kill-other-buffers RET hoặc bạn cũng dán mã sau vào .emacstệp và sau đó chỉ cần nhấnC-xC-b

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

1

Tôi đã sử dụng điểm mấu chốt-kill-other-buffer trong vài tháng.

Nhưng tôi muốn bộ đệm dired cũng bị xóa. Câu trả lời của @ Euge và @ wenjun.yan giải quyết vấn đề này. Nhưng nó sẽ xóa các bộ đệm đặc biệt (ví dụ: * git-credential-cache - daemon *, * xước *, hoạt động helm, và v.v.). Vì vậy, tôi đã đưa ra giải pháp (hiện tại) này.

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

Lấy cảm hứng từ bộ đệm kết hợp tiêu diệt . Bạn có thể bổ sung thêmcondition tên bộ đệm khác để loại trừ, nếu bạn muốn.

Hy vọng nó giúp :)


Xem điều này cho giải pháp cải tiến của tôi.
azzamsa

0

Bạn cũng có thể thích cái này - loại bỏ tất cả các bộ đệm ngoại trừ bộ đệm hiện tại, * Tin nhắn * và * cào * (rất tiện để có, tôi gọi chúng là "bộ công cụ"), đóng các cửa sổ dư thừa, cho bạn biết cửa sổ nào hiện tại đệm.

(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))cũng giống như (eq x (current-buffer)), chỉ kém hiệu quả hơn. Phần còn lại orcó thể được đơn giản hóa thành(member (buffer-name x) '("*Messages*" "*scratch*"))
Stefan

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.