-
-
Notifications
You must be signed in to change notification settings - Fork 112
Switch to buffer
(require 'dash)
(require 's)
;; Return name of the first n buffers from (buffer-list).
(defun my/name-of-buffers (n)
(let* ((bns (--remove
(s-starts-with? " " it)
(--map (buffer-name it) (buffer-list))))
;; Exclude the first element which is the current buffer.
(k (- (length bns) 1)))
(-take (if (> n k) k n) (-drop 1 bns))))
;; Given ("a", "b", "c"), return "1. a, 2. b, 3. c".
(defun my/number-names (list)
(let ((nseq (--map (number-to-string it)
(number-sequence 1 (length list)))))
(mapconcat 'identity
(--zip-with (concat it ". " other) nseq list)
", ")))
;; Visit the (n - 1)th element in list. If other-window is not nil,
;; call switch-to-buffer-other-window.
(defun my/visit-buffer (list n &optional other-window)
(let ((k (length list))
(n (if (< n 1) 1 n))
(f (if other-window 'switch-to-buffer-other-window 'switch-to-buffer)))
(if (> n k) (error "No buffer at index %d" n))
(funcall f (get-buffer (nth (- n 1) list)))))
(let ((list nil)
(names nil))
(global-set-key
"\C-o"
(defhydra my/switch-to-buffer
(:exit t
:body-pre (setq list (my/name-of-buffers 4)
names (my/number-names list)))
"
_o_ther buffers: %s(identity names)
"
("o" (lambda (n) (interactive "p") (my/visit-buffer list n)) "this window")
("O" (lambda (n) (interactive "p") (my/visit-buffer list n t)) "other window")
("<escape>" nil))))Pressing C-o activates the hydra with names of the first 4 most recently visited "other" buffers listed:
-
A single o switches to the first buffer in that list, same as what M-:
(switch-to-buffer (other-buffer))would do. In other words, you can quickly switch between two buffers back and forth with C-o o. -
Prefixed with a numeric prefix, say, 2 o, selects the 2nd buffer from the list, 3 o selects the 3rd, ... Negative prefixes and the numeric prefix 1 are same as no prefix - all select the first buffer.
-
O does the same as o except that the buffer is switched in the "other window" - i.e. by
switch-to-buffer-other-window.
In practice, this hydra usually can have more heads to call, for example, ido-find-file, ido-switch-buffer, etc.
If you don't need to visit buffers in the "other window", a variant of this hydra can be:
(let ((list nil)
(names nil))
(global-set-key
"\C-o"
(defhydra my/switch-to-buffer
(:exit t
:body-pre (setq list (my/name-of-buffers 4)
names (my/number-names list)))
"
other buffers: %s(identity names)
"
("o" (my/visit-buffer list 1))
("1" (my/visit-buffer list 1))
("2" (my/visit-buffer list 2))
("3" (my/visit-buffer list 3))
("4" (my/visit-buffer list 4))
("<escape>" nil))))Then C-o 1 selects the 1st buffer, C-o 2 selects the 2nd, and so on, and still retain the quick C-o o.
- Binding-Styles
- Basics
- Verbosity
- Verbosity-Long-Short
- Conditional-Hydra
- defcustom
- Hydra-Colors
- internals
- Nesting-Hydras
- Prefix-map