So I generally have 3 buffers open in Emacs.
One buffer for the actual code I am writing.
One buffer for the unit test for said code.
A third buffer that displays the results of the unit test. This buffer comes into being
below the two other buffers when I run my unit test C-x SPACE.
How do I disable this third buffer such that when I press C-x o I am only switching between buffer 1 and buffer 2? Currently, I switch between buffer 1, then buffer 2, then buffer 3, then buffer 1, etc. To be specific, I want C-x o to only switch between buffer 1 and 2.
Thank you.
A general solution to this (can look) something like the following:
(defvar ignore-windows-containing-buffers-matching-res '("\\*Help")
"List of regular expressions specifying windows to skip (if window contains buffer that matches, skip)")
(defadvice other-window (before other-window-ignore-windows-containing activate)
"skip over windows containing buffers which match regular expressions in 'ignore-windows-containing-buffers-matching-res"
(if (and (= 1 (ad-get-arg 0)) (interactive-p))
(let* ((win (next-window))
(bname (buffer-name (window-buffer win))))
(when (some 'identity (mapcar '(lambda (re)
(string-match re bname))
ignore-windows-containing-buffers-matching-res))
(ad-set-arg 0 2)))))
Customize the variable to be a regular expression matching the buffer names you want to skip.
Trey's answer will do exactly what you want (at least it looks like it will; I haven't tried it). A more generic solution would be to use swbuff with either swbuff-x or my own swbuff-advice. Info about all three can be found on the Emacs Wiki swbuff page.
Related
Edit: What the poster calls a "window", Emacs calls a "frame". I fixed the title.
Concisely, the question is: in a window, how do I switch quickly to a buffer previously visited in that window, even if it's already opened in another window?
A more detailed description follows.
Normally, in order to switch window to previous buffer one just types C-x b RET. That is, the default argument to switch-to-buffer (or ido-switch-buffer) is the previous buffer.
This is not, however, the case when that (previous) buffer is already shown in another window. That's exactly what bugs me.
Let's consider an example. Suppose I have three buffers (A, B and C) and two windows showing buffers A and B (C is not visible at this point).
Then I open buffer A in the second window, too. So, now I have buffer A shown in both windows. Then I switch (C-x b RET) to B again. After that, C-x b RET will bring me not to A, but to C because A is already shown in the other window.
How do I make C-x b RET behave more consistently?
Update
After this problem had been solved, I realized I needed more: namely, for point position to be remembered per-window, not per buffer. Luckily, there're ready-made solutions:
winpoint
per-window-point
They're quite similar; for a discussion of differences see here.
I've found a fix for switch-to-buffer. It eventually calls
(other-buffer (current-buffer))
while in order to fix your problem, the call needs to look like this:
(other-buffer (current-buffer) t)
i.e. the visible-ok argument needs to be t.
Here's an advice to have it always at t. Hopefully it won't break other stuff that uses other-buffer:
(defadvice other-buffer (around fix-switch-to-buffer
(&optional buffer visible-ok frame) activate)
(setq visible-ok t)
ad-do-it)
Note that ido-switch-to-buffer uses a different machinery, so a different method is needed to fix it.
update: fix for ido-switch-to-buffer
I needed to re-define ido-make-buffer-list:
(defun ido-make-buffer-list (default)
(let* ((ido-current-buffers (list (buffer-name (current-buffer))))
(ido-temp-list (ido-make-buffer-list-1 (selected-frame) ido-current-buffers)))
(if ido-temp-list
(nconc ido-temp-list ido-current-buffers)
(setq ido-temp-list ido-current-buffers))
(if default
(setq ido-temp-list
(cons default (delete default ido-temp-list))))
(if (bound-and-true-p ido-enable-virtual-buffers)
(ido-add-virtual-buffers-to-list))
(run-hooks 'ido-make-buffer-list-hook)
ido-temp-list))
The diff is just one line, but it's too messy to advice it.
update: use new advice system for other-buffer
The old stuff should still work for quite a while, but here's the new approach:
(defun other-buffer-advice (orig-fun &optional buffer visible-ok frame)
(funcall orig-fun buffer t frame))
(advice-add 'other-buffer :around #'other-buffer-advice)
;; (advice-remove 'other-buffer :around #'other-buffer-advice)
Instead of advising the built-in function other-buffer, you can pre-select visible buffers using a package.
1 Using Ivy
If you're using Ivy, you can use abo-abo's approach to override the lower-use function ivy-switch-buffer.
(defun user/ivy-switch-buffer ()
"Switch to another buffer with visible-ok preselection."
(interactive)
(ivy-read "Switch to buffer: " #'internal-complete-buffer
:keymap ivy-switch-buffer-map
:preselect (buffer-name (other-buffer (current-buffer) t))
:action #'ivy--switch-buffer-action
:matcher #'ivy--switch-buffer-matcher
:caller 'ivy-switch-buffer))
(advice-add 'ivy-switch-buffer :override #'user/ivy-switch-buffer)
2 Using Ido mode
2.1 Switching to a buffer shown in another frame
If by "window" you really mean "frame" (i.e., you'd like to ido-switch-buffer to a buffer that is currently shown in another frame), then ido-mode gives you the behavior you're looking for when you change ido-default-buffer-method from its default value of raise-frame to selected-window:
(setq ido-default-buffer-method 'selected-window)
Emacs constructs an independent buffer list for each frame, so the only thing you have to do is to configure Ido to avoid jumping to another frame when you switch buffers.
2.2 Switching to a buffer that is shown in another window inside the same frame
To get this behavior across windows within the same frame, you should hook a function that reorders the buffer list onto ido-make-buffer-list-hook.
From ido.el:
;; Changing the list of files
;; --------------------------
;; By default, the list of current files is most recent first,
;; oldest last, with the exception that the files visible in the
;; current frame are put at the end of the list. A hook exists to
;; allow other functions to order the list. For example, if you add:
;;
;; (add-hook 'ido-make-buffer-list-hook 'ido-summary-buffers-to-end)
;;
;; then all files matching "Summary" are moved to the end of the
;; list. (I find this handy for keeping the INBOX Summary and so on
;; out of the way.) It also moves files matching "output\*$" to the
;; end of the list (these are created by AUCTeX when compiling.)
;; Other functions could be made available which alter the list of
;; matching files (either deleting or rearranging elements.)
In an Emacs dired buffer, if I navigate point over a filename and hit o for dired-find-file-other-window, dired successfully produces desired behavior: opening the file in a secondary window.
But if I then navigate point over a SECOND filename and again hit o, dired splits the frame AGAIN and opens the file in a THIRD window.
How do I direct dired to reuse the second window, such that I always have a maximum of two windows in a frame?
Tried to solve the same problem using by modifying value of split-width-threshold, but found that it often stops working when monitor configuration changes. Ended up writing an advice for window-splittable-p.
(setq split-width-threshold (- (window-width) 10))
(setq split-height-threshold nil)
(defun count-visible-buffers (&optional frame)
"Count how many buffers are currently being shown. Defaults to selected frame."
(length (mapcar #'window-buffer (window-list frame))))
(defun do-not-split-more-than-two-windows (window &optional horizontal)
(if (and horizontal (> (count-visible-buffers) 1))
nil
t))
(advice-add 'window-splittable-p :before-while #'do-not-split-more-than-two-windows)
Raise value of split-height-threshold to the extend it will not do another split.
You might have to raise split-width-threshold also - in case Emacs thinks it's smart to split that way than.
WRT questions in comment:
The value to choose IMO depends from number of lines displayed at window. Let's assume 40 lines are displayed. If a window is split, 20 are left. Then a `split-height-threshold' of 15 should prevent further split. Preventing further side-by-side split should work respective, just consider the columns displayed.
BTW would expect a way to adapt that dynamically.
How can we close temporary buffers which are enclosed with * automatically. For e.g. messages, completions buffer needs to be closed. Killing all these buffers manually after use is painful.
Is there a way to close temporary buffers created by emacs (not by us)?
Do you really need to close those buffers? If you use a proper buffer switching method like iswitchb then you don't have to care about temporary or other buffers, because you can go directly to any buffer you want.
I'd second the suggestion you use ido or iswitchb to avoid being bothered by temporary buffers. The presence of those buffers is a natural consequence of using emacs, so don't try to swim upstream!
On the other hand, if you're irritated by the growing list of open buffers, you can use midnight.el to automatically close inactive buffers after a period of time, or you can use ibuffer to easily select and close unwanted buffers en masse.
Personally, I leave buffers open for a long time, I tidy them up occasionally using ibuffer, and I rely on ido to switch buffers quickly. In Emacs 24, you can set ido-use-virtual-buffers to t, and then ido will let you switch to closed files, reopening them as necessary.
To avoid having those buffers in your way, you could define key-bindings to cycle through «user buffers» and «useless buffers» :
http://ergoemacs.org/emacs/effective_emacs.html , section «Switching Next/Previous User Buffers»
but some useful buffers start with a *, like shells, compilation buffer, ielm, etc.
As user said, it would be better to use a smart buffer-switching package such as iswitchb and ido. iswitchb's iswitchb-buffer-ignore and ido's ido-ignore-buffers variables allow us to specify what buffers to ignore using regular expressions.
However, if you really want to kill those buffers, a program like this will be helpful to you:
(require 'cl)
(defvar kill-star-buffers-except
'("\\`\\*scratch\\*\\'"
"\\`\\*Messages\\*\\'"
"\\` \\*Minibuf-[[:digit:]]+\\*\\'"
"\\` \\*Echo Area [[:digit:]]+\\*\\'")
"Exception list for `kill-star-buffers'")
(defun kill-star-buffers ()
"Kill all star buffers except those in `kill-star-buffers-except'"
(interactive)
(mapc (lambda (buf)
(let ((buf-name (buffer-name buf)))
(when (and
;; if a buffer's name is enclosed by * with optional leading
;; space characters
(string-match-p "\\` *\\*.*\\*\\'" buf-name)
;; and the buffer is not associated with a process
;; (suggested by "sanityinc")
(null (get-buffer-process buf))
;; and the buffer's name is not in `kill-star-buffers-except'
(notany (lambda (except) (string-match-p except buf-name))
kill-star-buffers-except))
(kill-buffer buf))))
(buffer-list)))
When switching buffers with emacs ido mode enabled, a list of completions are displayed in the minibuffer. It appears there is a "feature" that buffers that are already open are put to the end of the list. I, however, often open the same buffer in multiple panes.
Is there a way to either turn this "feature" off, or alternatively do the opposite: have the buffers that are already open be at the front of the completion list?
The main point of ido mode is that you don't use arrows to navigate between buffers in the minibuffer. Instead you type the part of the buffer's name. In this case it doesn't matter where the buffer is in the list.
This is not possible unless you want to wade deep in ido's intestines.
As eGlyph already said: You're likely using ido wrongly (and there's also C-s for <right> and C-r for <left>; no need for arrow keys).
But you can define command for choosing among the already shown buffers (here only from the current frame, if you want all shown buffers you have to collect the windows first via `frame-list):
(defun choose-from-shown-buffers ()
(interactive)
(let ((buffers (mapcar (lambda (window)
(buffer-name (window-buffer window)))
(window-list))))
(pop-to-buffer (ido-completing-read "Buffer: " buffers))))
Is there a way to search all the open buffers for a particular pattern?
C-s interactively searches current buffer.
Similarly, is there something that searches all the open buffers?
I know I can use "occur", but "Occur" brings a new buffer and changes/messes with the buffer organization.
The built-in multi-occur-in-matching-buffers hasn't been mentioned. I use a modified version of this (because I invariably want to search all buffers, and specifying a buffer name pattern each time is annoying).
(defun my-multi-occur-in-matching-buffers (regexp &optional allbufs)
"Show lines matching REGEXP in all file-visiting buffers.
Given a prefix argument, search in ALL buffers."
(interactive (occur-read-primary-args))
(multi-occur-in-matching-buffers "." regexp allbufs))
(global-set-key (kbd "M-s /") 'my-multi-occur-in-matching-buffers)
To invert the behaviour of the prefix argument so that the default behaviour is to search all buffers, change the call to:
(multi-occur-in-matching-buffers "." regexp (not allbufs))
(and, of course, update the docstring accordingly.)
I've fixed the TODO:
;; I know that string is in my Emacs somewhere!
(require 'cl)
(defcustom search-all-buffers-ignored-files (list (rx-to-string '(and bos (or ".bash_history" "TAGS") eos)))
"Files to ignore when searching buffers via \\[search-all-buffers]."
:type 'editable-list)
(require 'grep)
(defun search-all-buffers (regexp prefix)
"Searches file-visiting buffers for occurence of REGEXP. With
prefix > 1 (i.e., if you type C-u \\[search-all-buffers]),
searches all buffers."
(interactive (list (grep-read-regexp)
current-prefix-arg))
(message "Regexp is %s; prefix is %s" regexp prefix)
(multi-occur
(if (member prefix '(4 (4)))
(buffer-list)
(remove-if
(lambda (b) (some (lambda (rx) (string-match rx (file-name-nondirectory (buffer-file-name b)))) search-all-buffers-ignored-files))
(remove-if-not 'buffer-file-name (buffer-list))))
regexp))
(global-set-key [f7] 'search-all-buffers)
ibuffer might help you. Have a look at this article. I imagine that this might be most interesting for you:
'O' - ibuffer-do-occur
- Do an occur on the selected buffers.
This does a regex search on all the selected buffers and displays the result in an occur window. It is unbelievably useful when browsing through code. It becomes truly awesome when you combine it with the ‘filter’ powers of ibuffer (coming up ahead). Eg: Do C-x C-b, mark all files using (say) Perl major-mode, do occur to find out all places where a certain function is mentioned in these files. Navigate to the point at will through the Occur window.
'M-s a C-s' - ibuffer-do-isearch
- Do an incremental search in the marked buffers.
This is so awesome that you have to try it right this instant. Select two or more buffers, hit the hotkey, search for something that occurs in all these buffers. These two features alone are enough to make me a lifelong fan of IBuffer. Go do it now!
Taking a clue from Leo's comment to Bozhidar:
(defun my-isearch-buffers ()
"isearch multiple buffers."
(interactive)
(multi-isearch-buffers
(delq nil (mapcar (lambda (buf)
(set-buffer buf)
(and (not (equal major-mode 'dired-mode))
(not (string-match "^[ *]" (buffer-name buf)))
buf))
(buffer-list)))))
You might have to tweak the conditions inside the and to filter whatever other kinds of buffers you want to ignore.
Although this is not exactly what you're asking for, I search multiple files using grep (M-X grep) and grep-find (M-X grep-find).
This sort of does what you want, in that when you've come to the end of matches for the string/regexp you're searching for, the next search command will start in a new buffer.
(setq isearch-wrap-function 'isearch-bury-buffer-instead-of-wrap)
(defun isearch-bury-buffer-instead-of-wrap ()
"bury current buffer, try to search in next buffer"
(bury-buffer))
It doesn't switch to a different buffer when the search fails, and when you "back up" the search results by pressing <backspace>, you won't pop back into the previous buffers searched.
In Icicles, C-c ' is command icicle-occur, which can search multiple buffers.
C-u C-c ' searches a set of buffers that you choose. You can choose by dynamically filtering the buffer names with your minibuffer input, then hit C-! to search all of those buffers whose names match. Similarly, C-99 C-c ' searches only the buffers that are visiting files.
Like occur and grep, icicle-occur searches line by line. More generally, instead of using lines as the search contexts you can use any buffer portions at all. C-c ` (backquote instead of quote) is command icicle-search. With a non-negative prefix arg it searches a set of buffers that you choose.
The first thing you do is give it a regexp that defines the search contexts. E.g., if you give it .* then it acts like icicle-occur: each search context is a line. If you give it a regexp that matches only function definitions then those are the search contexts, and so on.
http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview