By M-x eshell or M-x shell Emacs opens a shell or an eshell in the current window. How to open this shell or eshell in a new window?

  • 1
    The function eshell is only 15 lines of actual code (excluding the doc-string). In my opinion, there is no need to advice or write a fixer function. Instead, just copy the function eshell over the .emacs or init.el file and call it something new -- e.g., eshell-other-window -- change (pop-to-buffer-same-window buf) to (switch-to-buffer-other-window buf). Creating a new function for shell can be done much the same way -- it doesn't really matter that it's a few more lines long, because you will only be changing one line of code and changing the name of the function itself.
    – lawlist
    Jun 30, 2015 at 21:59

3 Answers 3


Here's a simple command to open a shell in a new window:

(defun shell-other-window ()
  "Open a `shell' in a new window."
  (let ((buf (shell)))
    (switch-to-buffer (other-buffer buf))
    (switch-to-buffer-other-window buf)))

Edit: If you want shell to open in a new frame rather than new window, replace switch-to-buffer-other-window with switch-to-buffer-other-frame.

  • And is it possible to make this the default behavior?
    – Name
    Jun 30, 2015 at 20:24
  • @Name: you could probably adapt this code to write some advice for shell.
    – Dan
    Jun 30, 2015 at 20:26

The canonical way of altering the display behaviour for a buffer is to customize display-buffer-alist:

(setq display-buffer-alist '(("\\`\\*e?shell" display-buffer-pop-up-window)))
(setq display-buffer-alist '(("\\`\\*e?shell" display-buffer-pop-up-frame)))

It's a bit easier with my shackle package though:

(setq shackle-rules '(("\\`\\*e?shell" :regexp t :popup t)))
(setq shackle-rules '(("\\`\\*e?shell" :regexp t :frame t)))

I wanted to have different functions for opening eshell as a popup and normally. I decided that I could just use a different buffer name for popups and add a different rule to display-buffer-alist:

(defun eshell-popup (&optional buffer-name)
  (unless buffer-name (setq buffer-name "*eshell-popup*"))
  (let ((eshell-buffer-name buffer-name))

(add-to-list 'display-buffer-alist
               (display-buffer-in-side-window (side . bottom))))

That way you can call eshell or eshell-popup depending on what you want.

Hope it helps someone in my situation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.