In Emacs, is there a way to auto-complete only from one specified buffer? - emacs

When using M-/, the text in the current buffer is autocompleted with suggestions out of all active buffers.
Is there a way to limit the suggestions to only one specific buffer?

Assuming you are talking about dabbrev-expand (M-/ is the usual binding), then there are a variety of options depending on your requirements.
To search only a specific white list of buffers, the simplest approach is to set the variable dabbrev-search-these-buffers-only:
"If non-nil, a list of buffers which dabbrev should search.
If this variable is non-nil, dabbrev will only look in these buffers.
It will not even look in the current buffer if it is not a member of
this list."
Here's an example from a custom mode of mine (I rebind M-/ to this function for this mode)
(defun tks-dabbrev-expand (arg)
"Expand either aliases or descriptions, depending on context."
(interactive "*P")
(let* ((candidates
(if (looking-back "^\\S-+")
" *tks-aliases*"
" *tks-descriptions*"))
(dabbrev-search-these-buffers-only (list (get-buffer candidates))))
(dabbrev-expand arg)))
Note that there are several other ways in which you can filter the list of buffers which dabbrev will search inside. The dabbrev customize group has the details:
M-x customize-group RET dabbrev RET

Related

Tell ido to ignore all star buffers except for some

Normally I want ido to ignore all non-user buffers, i.e. all buffers which start with a *. I have achieved this using the following setting:
(setq ido-ignore-buffers '("\\` " "^\*"))
However, this poses a problem when working with a shell or an interpreter, e.g. ielm, where the interaction buffer is named *ielm*. Obviously adding all buffers to be ignored manually is not really an option because the list can get quite long with a lot of different emacs packages loaded. I know about C-a which disabled the ignore pattern from within ido, however, I don't want to hit C-a every time I switch to an ielm buffer.
My question is:
Is there some variable which allows to specify buffers which ido should not ignore (although they match the normal ignore list)? Or is there some other approach for solving this?
The list that the ido-ignore-buffers variable points to may contain not only regular expressions but also functions (any mix of them, actually). It's easy to provide a function to filter out all non-user buffers except *ielm*:
(defun ido-ignore-non-user-except-ielm (name)
"Ignore all non-user (a.k.a. *starred*) buffers except *ielm*."
(and (string-match "^\*" name)
(not (string= name "*ielm*"))))
(setq ido-ignore-buffers '("\\` " ido-ignore-non-user-except-ielm))
Here's an example of having multiple unignored buffer names:
(setq my-unignored-buffers '("*ielm*" "*scratch*" "*foo*" "*bar*"))
(defun my-ido-ignore-func (name)
"Ignore all non-user (a.k.a. *starred*) buffers except those listed in `my-unignored-buffers'."
(and (string-match "^\*" name)
(not (member name my-unignored-buffers))))
(setq ido-ignore-buffers '("\\` " my-ido-ignore-func))
An interesting example of using ignore functions can be found among comments in the ido.el source code (I've removed ;; at the beginning of each line):
(defun ido-ignore-c-mode (name)
"Ignore all c mode buffers -- example function for ido."
(with-current-buffer name
(derived-mode-p 'c-mode)))
Basically, once you've got buffer name, you can do any checking/ignoring you want.

Iswitchb ignore dired buffer

Is there any way to tell iswitchb to ignore buffers based on mode not string? I would like to exclude the buffers opened in dired mode which are very often the most numerous and it's hard to find opened files in minibuffer among them. Any help on this would be appreciated.
You can add a custom function to iswitchb-buffer-ignore to do this. There is actually an example in iswitchb.el -- based on that, this will do the trick:
(defun iswitchb-ignore-dired-mode (name)
"Ignore all dired mode buffers."
(with-current-buffer name
(derived-mode-p 'dired-mode)))
(setq iswitchb-buffer-ignore '("^ " iswitchb-ignore-dired-mode))
This preserves the default behavior of ignoring buffer names that begin with a space, and adds the filter for dired-mode buffers.
Based on a similar example in the iswitchb source code:
(defun iswitchb-ignore-dired-buffers (buffer)
(with-current-buffer buffer
(eq major-mode 'dired-mode)))
(add-to-list 'iswitchb-buffer-ignore 'iswitchb-ignore-dired-buffers)

Close all temporary buffers automatically in emacs

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

Emacs ido start with open buffers first in cycle 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))))

emacs: interactively search open 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