I'd like to make a simple change to Emacs so that the next-buffer and previous-buffer commands (which I have bound to C-x <RIGHT> and C-x <LEFT> will skip over the *Messages* buffer.
I'm using Emacs 24 and the Emacs Starter Kit.
I've read the following related questions and answers, but they are not what I want:
Buffer cycling in Emacs: avoiding scratch and Messages buffer
Emacs disable *Messages* buffer
Emacs Lisp Buffer out of focus function?
Here are some of the reasons why they don't work:
I'd like to keep it as simple as possible. Fewer configuration changes are better.
I don't want to kill or prevent *Messages* altogether.
(add-to-list 'ido-ignore-buffers "^\*Messages\*" helps with my C-x b (ido-switch-buffer) but does not change how next-buffer and previous-buffer behave.
This way you can avoid the infinite loop:
(defun next-code-buffer ()
(interactive)
(let (( bread-crumb (buffer-name) ))
(next-buffer)
(while
(and
(string-match-p "^\*" (buffer-name))
(not ( equal bread-crumb (buffer-name) )) )
(next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)
This code loops over non-starred buffers ("^\*"). For your case (only avoid *Messages*) it would be:
(defun next-code-buffer ()
(interactive)
(let (( bread-crumb (buffer-name) ))
(next-buffer)
(while
(and
(equal "*Messages*" (buffer-name))
(not ( equal bread-crumb (buffer-name) )) )
(next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)
You can write previous-code-buffer just replacing every next-buffer with previous-buffer.
The simplest I can think of is defining an advice for both functions. Here it is for next-buffer. Similarly would be for previous-buffer. You can also define a configuration variable to enable/disable the behavior (or activating/deactivating the advice):
(defadvice next-buffer (after avoid-messages-buffer-in-next-buffer)
"Advice around `next-buffer' to avoid going into the *Messages* buffer."
(when (string= "*Messages*" (buffer-name))
(next-buffer)))
;; activate the advice
(ad-activate 'next-buffer)
Maybe you can compare buffers in some other way instead of its string name, but that will work. The code for previous buffer is almost the same. I don't know either if there is a way of calling the original function without triggering the advice once inside the advice itself, but again, the code will work even if the name of the buffer is tested afterwards (will fail if you just have one buffer, and it is the messages buffer; some code can check if there is just one buffer and don't call next-buffer again).
If you want to use a standalone function that does the same thing:
(defun my-next-buffer ()
"next-buffer, only skip *Messages*"
(interactive)
(next-buffer)
(when (string= "*Messages*" (buffer-name))
(next-buffer)))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-next-buffer)
This is what I'm using, based on Diego's answer:
(setq skippable-buffers '("*Messages*" "*scratch*" "*Help*"))
(defun my-next-buffer ()
"next-buffer that skips certain buffers"
(interactive)
(next-buffer)
(while (member (buffer-name) skippable-buffers)
(next-buffer)))
(defun my-previous-buffer ()
"previous-buffer that skips certain buffers"
(interactive)
(previous-buffer)
(while (member (buffer-name) skippable-buffers)
(previous-buffer)))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
It is not great yet, because it will hang if there are no buffers other than the skippable-buffers I list. I use C-g to break out of the loop when it happens as a hackaround.
As RubenCaro's answer points out, the other answers can enter infinite loops. I thought David James' approach of a skippable buffers list was a bit nicer, though, so here's a variant of that.
(setq my-skippable-buffers '("*Messages*" "*scratch*" "*Help*"))
(defun my-change-buffer (change-buffer)
"Call CHANGE-BUFFER until current buffer is not in `my-skippable-buffers'."
(let ((initial (current-buffer)))
(funcall change-buffer)
(let ((first-change (current-buffer)))
(catch 'loop
(while (member (buffer-name) my-skippable-buffers)
(funcall change-buffer)
(when (eq (current-buffer) first-change)
(switch-to-buffer initial)
(throw 'loop t)))))))
(defun my-next-buffer ()
"`next-buffer' that skips `my-skippable-buffers'."
(interactive)
(my-change-buffer 'next-buffer))
(defun my-previous-buffer ()
"`previous-buffer' that skips `my-skippable-buffers'."
(interactive)
(my-change-buffer 'previous-buffer))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
Related
And I dont want this behavior. Actually, not everytime is focus switched. For example, buffers like *Help* or *Message* does not have this behavior, this unwanted feature is active only when closing regular file buffers.
How to disable this feature completelly ?
My solution for this problem is simply write my own handler for buffer kill. Hope it will help someone in future.
(global-set-key (kbd "C-w")
(lambda ()
(interactive)
(if (string= (substring (buffer-name) 0 2) " *")
(progn
(message "You can not kill protected BUFFER"))
(progn
(if (string= (substring (buffer-name) 0 1) "*")
(progn
(call-interactively 'kill-buffer))
(progn
(call-interactively 'kill-buffer)
(run-at-time "0.5 sec" nil
(lambda ()
(call-interactively 'windmove-right)))))))))
You need to have installed ace-window package for windmove-right, that feature with protected buffers is not relevant to this answer so you can freely remove it.
I'd like to make a simple change to Emacs so that the next-buffer and previous-buffer commands (which I have bound to C-x <RIGHT> and C-x <LEFT> will skip over the *Messages* buffer.
I'm using Emacs 24 and the Emacs Starter Kit.
I've read the following related questions and answers, but they are not what I want:
Buffer cycling in Emacs: avoiding scratch and Messages buffer
Emacs disable *Messages* buffer
Emacs Lisp Buffer out of focus function?
Here are some of the reasons why they don't work:
I'd like to keep it as simple as possible. Fewer configuration changes are better.
I don't want to kill or prevent *Messages* altogether.
(add-to-list 'ido-ignore-buffers "^\*Messages\*" helps with my C-x b (ido-switch-buffer) but does not change how next-buffer and previous-buffer behave.
This way you can avoid the infinite loop:
(defun next-code-buffer ()
(interactive)
(let (( bread-crumb (buffer-name) ))
(next-buffer)
(while
(and
(string-match-p "^\*" (buffer-name))
(not ( equal bread-crumb (buffer-name) )) )
(next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)
This code loops over non-starred buffers ("^\*"). For your case (only avoid *Messages*) it would be:
(defun next-code-buffer ()
(interactive)
(let (( bread-crumb (buffer-name) ))
(next-buffer)
(while
(and
(equal "*Messages*" (buffer-name))
(not ( equal bread-crumb (buffer-name) )) )
(next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)
You can write previous-code-buffer just replacing every next-buffer with previous-buffer.
The simplest I can think of is defining an advice for both functions. Here it is for next-buffer. Similarly would be for previous-buffer. You can also define a configuration variable to enable/disable the behavior (or activating/deactivating the advice):
(defadvice next-buffer (after avoid-messages-buffer-in-next-buffer)
"Advice around `next-buffer' to avoid going into the *Messages* buffer."
(when (string= "*Messages*" (buffer-name))
(next-buffer)))
;; activate the advice
(ad-activate 'next-buffer)
Maybe you can compare buffers in some other way instead of its string name, but that will work. The code for previous buffer is almost the same. I don't know either if there is a way of calling the original function without triggering the advice once inside the advice itself, but again, the code will work even if the name of the buffer is tested afterwards (will fail if you just have one buffer, and it is the messages buffer; some code can check if there is just one buffer and don't call next-buffer again).
If you want to use a standalone function that does the same thing:
(defun my-next-buffer ()
"next-buffer, only skip *Messages*"
(interactive)
(next-buffer)
(when (string= "*Messages*" (buffer-name))
(next-buffer)))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-next-buffer)
This is what I'm using, based on Diego's answer:
(setq skippable-buffers '("*Messages*" "*scratch*" "*Help*"))
(defun my-next-buffer ()
"next-buffer that skips certain buffers"
(interactive)
(next-buffer)
(while (member (buffer-name) skippable-buffers)
(next-buffer)))
(defun my-previous-buffer ()
"previous-buffer that skips certain buffers"
(interactive)
(previous-buffer)
(while (member (buffer-name) skippable-buffers)
(previous-buffer)))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
It is not great yet, because it will hang if there are no buffers other than the skippable-buffers I list. I use C-g to break out of the loop when it happens as a hackaround.
As RubenCaro's answer points out, the other answers can enter infinite loops. I thought David James' approach of a skippable buffers list was a bit nicer, though, so here's a variant of that.
(setq my-skippable-buffers '("*Messages*" "*scratch*" "*Help*"))
(defun my-change-buffer (change-buffer)
"Call CHANGE-BUFFER until current buffer is not in `my-skippable-buffers'."
(let ((initial (current-buffer)))
(funcall change-buffer)
(let ((first-change (current-buffer)))
(catch 'loop
(while (member (buffer-name) my-skippable-buffers)
(funcall change-buffer)
(when (eq (current-buffer) first-change)
(switch-to-buffer initial)
(throw 'loop t)))))))
(defun my-next-buffer ()
"`next-buffer' that skips `my-skippable-buffers'."
(interactive)
(my-change-buffer 'next-buffer))
(defun my-previous-buffer ()
"`previous-buffer' that skips `my-skippable-buffers'."
(interactive)
(my-change-buffer 'previous-buffer))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
I have various things set up in my 'before-save-hook. For example, I run 'delete-trailing-whitespace. This is what I want in almost all occasions.
But sometimes, I'm working on files that are shared with other people, and the file already has a bunch of trailing whitespace. If I save the file, I'll get a big diff that's pretty confusing, as my change is buried in dozens or hundreds of meaningless changes. Yes, everyone could just tell their diff tool to not show whitespace changes, but that's something that everyone has to do every time they look at the diff. I'd rather not even have the whitespace change.
Is there anything I can do to save the file without the whitespace changes, short of starting a new instance of Emacs with no init.el file, or with a modified init.el that doesn't have the hook?
Here is how I save without triggering delete-trailing-whitespace:
C-x C-q C-x C-s C-x C-q: read-only, save, revert read-only
A simpler solution I came up with is that my fundamental-mode has no hooks installed, because I want it to be as plain as possible. Thus if I want to save a file without running hooks, I temporarily switch to fundamental-mode.
Based on a comment discussion with #Stefan, here are two possible (untested) solutions:
Use let:
(defun save-buffer-without-dtw ()
(interactive)
(let ((b (current-buffer))) ; memorize the buffer
(with-temp-buffer ; new temp buffer to bind the global value of before-save-hook
(let ((before-save-hook (remove 'delete-trailing-whitespace before-save-hook)))
(with-current-buffer b ; go back to the current buffer, before-save-hook is now buffer-local
(let ((before-save-hook (remove 'delete-trailing-whitespace before-save-hook)))
(save-buffer)))))))
Use unwind-protect:
(defun save-buffer-without-dtw ()
(interactive)
(let ((restore-global
(memq 'delete-trailing-whitespace (default-value before-save-hook)))
(restore-local
(and (local-variable-p 'before-save-hook)
(memq 'delete-trailing-whitespace before-save-hook))))
(unwind-protect
(progn
(when restore-global
(remove-hook 'before-save-hook 'delete-trailing-whitespace))
(when restore-local
(remove-hook 'before-save-hook 'delete-trailing-whitespace t))
(save-buffer))
(when restore-global
(add-hook 'before-save-hook 'delete-trailing-whitespace))
(when restore-local
(add-hook 'before-save-hook 'delete-trailing-whitespace nil t)))))
The problem with the second solution is that the order of functions in the before-save-hook may change.
Here's another solution:
(defvar my-inhibit-dtw nil)
(defun my-delete-trailing-whitespace ()
(unless my-inhibit-dtw (delete-trailing-whitespace)))
(add-hook 'before-save-hook 'my-delete-trailing-whitespace)
and then
(defun my-inhibit-dtw ()
(interactive)
(set (make-local-variable 'my-inhibit-dtw) t))
so you can M-x my-inhibit-dtw RET in the buffers where you don't want to trim whitespace.
I wrote a command inspired by Nicholas Douma's solution.
(defun olav-save-buffer-as-is ()
"Save file \"as is\", that is in read-only-mode."
(interactive)
(if buffer-read-only
(save-buffer)
(read-only-mode 1)
(save-buffer)
(read-only-mode 0)))
What we need to do is remove 'delete-trailing-whitespace from before-save-hook, save the buffer, then add it back.
This code will do that, but only remove and add it if it's there to begin with.
;; save the buffer, removing and readding the 'delete-trailing-whitespace function
;; to 'before-save-hook if it's there
(defun save-buffer-no-delete-trailing-whitespace ()
(interactive)
(let ((normally-should-delete-trailing-whitespace (memq 'delete-trailing-whitespace before-save-hook)))
(when normally-should-delete-trailing-whitespace
(remove-hook 'before-save-hook 'delete-trailing-whitespace))
(save-buffer)
(when normally-should-delete-trailing-whitespace
(add-hook 'before-save-hook 'delete-trailing-whitespace))))
(global-set-key (kbd "C-c C-s") 'save-buffer-no-delete-trailing-whitespace)
It also binds the command to (kbd C-c C-s), for convenience.
I'm using the following code, to open ansi-term. I found this here.
(require 'term)
(defun visit-ansi-term ()
"If the current buffer is:
1) a running ansi-term named *ansi-term*, rename it.
2) a stopped ansi-term, kill it and create a new one.
3) a non ansi-term, go to an already running ansi-term
or start a new one while killing a defunt one"
(interactive)
(let ((is-term (string= "term-mode" major-mode))
(is-running (term-check-proc (buffer-name)))
(term-cmd "/usr/local/bin/bash")
(anon-term (get-buffer "*ansi-term*")))
(if is-term
(if is-running
(if (string= "*ansi-term*" (buffer-name))
(call-interactively 'rename-buffer)
(if anon-term
(switch-to-buffer "*ansi-term*")
(ansi-term term-cmd)))
(kill-buffer (buffer-name))
(ansi-term term-cmd))
(if anon-term
(if (term-check-proc "*ansi-term*")
(switch-to-buffer "*ansi-term*")
(kill-buffer "*ansi-term*")
(ansi-term term-cmd))
(ansi-term term-cmd)))))
(global-set-key (kbd "<f2>") 'visit-ansi-term)
Now I want to modify this, such that after renaming a buffer it remembers its name and when I use a keyboard shortcut to iterate through the renamed buffers list.
so if I press [F2] and it finds that ansi-term is running, it asks me if I want to rename it. I rename it to say, BUILD. I would like a function and bind to Say [F3] to iterate thorough the list of ansi-terms opened.
I'm a ELISP illiterate. would be glad it someone pointed be references which might help me doing this.
Thanks.
The following code/binding cycles through all the buffers whose major mode is term-mode:
(global-set-key (kbd "<f3>") 'cycle-ansi-term)
(defun cycle-ansi-term ()
"cycle through buffers whose major mode is term-mode"
(interactive)
(when (string= "term-mode" major-mode)
(bury-buffer))
(let ((buffers (cdr (buffer-list))))
(while buffers
(when (with-current-buffer (car buffers) (string= "term-mode" major-mode))
(switch-to-buffer (car buffers))
(setq buffers nil))
(setq buffers (cdr buffers)))))
How do I close all but the current buffer in Emacs? Similar to "Close other tabs" feature in modern web browsers?
For a more manual approach, you can list all buffers with C-x C-b, mark buffers in the list for deletion with d, and then use x to remove them.
I also recommend replacing list-buffers with the more advanced ibuffer: (global-set-key (kbd "C-x C-b") 'ibuffer). The above will work with ibuffer, but you could also do this:
m (mark the buffer you want to keep)
t (toggle marks)
D (kill all marked buffers)
I also use this snippet from the Emacs Wiki, which would further streamline this manual approach:
;; 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)
From 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)))))
Edit: updated with feedback from Gilles
There isn't a way directly in emacs to do this.
You could write a function to do this. The following will close all the buffers:
(defun close-all-buffers ()
(interactive)
(mapc 'kill-buffer (buffer-list)))
There is a built in command m-x kill-some-buffers (I'm using 24.3.50) In my nextstep gui (not tried in a terminal but sure it's similar) you can then approve which buffers to kill.
(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)))))
It works as you expected.
And after reading #Starkey's answer, I think this will be better:
(defun only-current-buffer ()
(interactive)
(mapc 'kill-buffer (cdr (buffer-list (current-buffer)))))
(buffer-list (current-buffer)) will return a list that contains all the existing buffers, with the current buffer at the head of the list.
This is my first answer on StackOverflow. Hope it helps :)
I found this solution to be the simplest one. This deletes every buffer except the current one. You have to add this code to your .emacs file
(defun kill-other-buffers ()
"Kill all other buffers."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
Of course, then you use it with M-x kill-other-buffers RET or you paste the following code in the .emacs file too and then just press C-xC-b
(global-set-key (kbd "C-x C-b") 'kill-other-buffers)
You can like this one as well - kill all buffers except current one, *Messages* and *scratch* (which are handy to have, I call them "toolkit"), close redundant windows as well, living you which one window which current buffer.
(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))
I've use crux-kill-other-buffers for some months.
But I want dired buffers get deleted too. #Euge's and #wenjun.yan's answers solve this. But it will delete special buffers (e.g *git-credential-cache--daemon*, *scratch*, helm operation, and etc). So I came up with this (current) solution.
(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)))))
Inspired from kill-matching-buffers. You can add more condition on other buffer-name to exclude, if you want to.
Hope it helps :)
I've used one of the solutions in this list for years, but now I have a new one of my own.
(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 has buffers built in as a collection that you can iterate over. It gives you a chance to parse out anything you don't want to close. Here, I've made sure that it doesn't close anything you've modified, and it uses buffer-file-name instead of just buffer-name so it doesn't kill special buffers. I also added an 'unless' to take out the current buffer (though you could obviously add it to the 'when', I just thought this was clearer).
But for an even more generic solution, we can define this as a macro, and pass in a function that will apply to all these buffers.
(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)))
Now if you want to kill all buffers that match this, you can call it like this
(operate-on-file-buffers 'kill-buffer)
This is what you want:
C-x 1
source: https://blasphemousbits.wordpress.com/2007/05/04/learning-emacs-part-4-buffers-windows-and-frames/