branch: master
commit c654e1b4a7e6d1683c0472074ef96ab624833698
Author: nathan moreau <[email protected]>
Commit: Oleh Krehel <[email protected]>

    Add a command to switch to shell buffers.
    
    Use the prefix argument to force the creation of a new shell buffer.
    This corresponds to what the `shell' commands does.
    
    Fixes #990
---
 counsel.el | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/counsel.el b/counsel.el
index a46871c..b5607aa 100644
--- a/counsel.el
+++ b/counsel.el
@@ -3751,6 +3751,50 @@ active."
   :group 'ivy
   :type 'boolean)
 
+(defun counsel-list-buffers-with-mode (mode)
+  "List all buffers with major-mode MODE.
+
+MODE is a symbol."
+  (save-current-buffer
+    (let (bufs)
+      (dolist (buf (buffer-list) bufs)
+        (set-buffer buf)
+        (and (equal major-mode mode)
+             (push (buffer-name buf) bufs))))))
+
+;;;###autoload
+(defun counsel-switch-to-shell-buffer (force-create)
+  "Switch to a shell buffer, or create one.
+
+List all the buffers in `shell-mode'. Is there is none or
+if FORCE-CREATE is non nil, create one; if there is exactly one,
+switch to it; otherwise, select one of them and switch to it."
+  (interactive "P")
+  (require 'pcase)
+  (counsel-switch-to-buffer-or-window
+   (pcase (counsel-list-buffers-with-mode 'shell-mode)
+     ((or (guard force-create) `())
+      (shell (read-string "Buffer name: "
+                          (generate-new-buffer-name "*shell*"))))
+     (`(,buf) buf)
+     ((and `(,_ . ,_) bufs) (ivy-read "Switch to shell buffer: " bufs)))))
+
+(defun counsel-switch-to-buffer-or-window (buffer-or-name)
+  "Display buffer BUFFER-OR-NAME and select its window.
+
+This behaves as `switch-to-buffer', except when the buffer is
+already visible; in that case, select the window corresponding to
+the buffer."
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+    (let (window-of-buffer-visible)
+      (catch 'found
+        (walk-windows (lambda (window)
+                        (and (equal (window-buffer window) buffer)
+                             (throw 'found (setq window-of-buffer-visible 
window))))))
+      (if window-of-buffer-visible
+          (select-window window-of-buffer-visible)
+        (switch-to-buffer buffer)))))
+
 ;;;###autoload
 (define-minor-mode counsel-mode
   "Toggle Counsel mode on or off.

Reply via email to