Skip to content

Instantly share code, notes, and snippets.

@pnkfelix
Created April 13, 2013 01:21
Show Gist options
  • Save pnkfelix/5376416 to your computer and use it in GitHub Desktop.
Save pnkfelix/5376416 to your computer and use it in GitHub Desktop.
Explanation of why buffer switching in emacs is filtering out candidates that are already visible in the frame
;; OTHER-BUFFER is the one that is screwing things up for us,
;; through the call-chain:
;; SWITCH-TO-BUFFER ->
;; READ-BUFFER-TO-SWITCH ->
;; OTHER-BUFFER
;;
;; Do M-x help f other-buffer
;; to see the help text explaining the interface for OTHER-BUFFER
;; which tells us why the fix I offer below fixes things.
(defun read-buffer-to-switch-impl (prompt)
"Read the name of a buffer to switch to, prompting with PROMPT.
Return the name of the buffer as a string.
This function is intended for the `switch-to-buffer' family of
commands since these need to omit the name of the current buffer
from the list of completions and default values."
(let ((rbts-completion-table (internal-complete-buffer-except)))
(minibuffer-with-setup-hook
(lambda ()
(setq minibuffer-completion-table rbts-completion-table)
;; Since rbts-completion-table is built dynamically, we
;; can't just add it to the default value of
;; icomplete-with-completion-tables, so we add it
;; here manually.
(if (and (boundp 'icomplete-with-completion-tables)
(listp icomplete-with-completion-tables))
(set (make-local-variable 'icomplete-with-completion-tables)
(cons rbts-completion-table
icomplete-with-completion-tables))))
;; FSK: The below call to OTHER-BUFFER is where the Niko's issue
;; is arising; other-buffer is specified to act in the manner
;; that annoys him, as specified "Buffers not visible in windows
;; are preferred to visible buffers, unless optional second
;; argument VISIBLE-OK is non-nil." (In the original code,
;; the optional second argument is not included in the invocation.)
(read-buffer prompt (other-buffer (current-buffer) t)
(confirm-nonexistent-file-or-buffer)))))
(defun switch-to-buffer-no-ignorance (buffer-or-name &optional norecord force-same-window)
"Switch to buffer BUFFER-OR-NAME in the selected window.
If called interactively, prompt for the buffer name using the
minibuffer. The variable `confirm-nonexistent-file-or-buffer'
determines whether to request confirmation before creating a new
buffer.
BUFFER-OR-NAME may be a buffer, a string (a buffer name), or
nil. If BUFFER-OR-NAME is a string that does not identify an
existing buffer, create a buffer with that name. If
BUFFER-OR-NAME is nil, switch to the buffer returned by
`other-buffer'.
Optional argument NORECORD non-nil means do not put the buffer
specified by BUFFER-OR-NAME at the front of the buffer list and
do not make the window displaying it the most recently selected
one.
If FORCE-SAME-WINDOW is non-nil, BUFFER-OR-NAME must be displayed
in the selected window; signal an error if that is
impossible (e.g. if the selected window is minibuffer-only). If
nil, BUFFER-OR-NAME may be displayed in another window.
Return the buffer switched to."
(interactive
(list (read-buffer-to-switch-impl "Switch to buffer: ") nil 'force-same-window))
(let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
(cond
;; Don't call set-window-buffer if it's not needed since it
;; might signal an error (e.g. if the window is dedicated).
((eq buffer (window-buffer)))
((window-minibuffer-p)
(if force-same-window
(error "Cannot switch buffers in minibuffer window")
(pop-to-buffer buffer norecord)))
((eq (window-dedicated-p) t)
(if force-same-window
(error "Cannot switch buffers in a dedicated window")
(pop-to-buffer buffer norecord)))
(t (set-window-buffer nil buffer)))
(unless norecord
(select-window (selected-window)))
(set-buffer buffer)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment