Whenever I run M-x shell, a buffer appears almost randomly somewhere - splitting current windows as it sees fit. I cannot work out the logic behind it.

The docstring says:

(shell &optional BUFFER)

If BUFFER exists but shell process is not running, make new shell.

If BUFFER exists and shell process is running, just switch to BUFFER.

This just tells me it will open a shell if it already exists, otherwise start a new one.

I only care about the position of the buffer. If I have the window configuration set how I need it, running shell usually ruins that setup.

I did look into the source as far as I could, but am not familiar enough with the underlying eLisp.

I would like to have a function that splits the current window, opens a shell buffer - I perform some short operation - then I can close the newly created window, restoring the previous window configuration exactly as it was.

I have this working for eshell, which I stole from Howard Abrams. It looks like this:

(defun eshell-here ()
  "Opens up a new shell in the directory associated with the
current buffer's file. The eshell is renamed to match that
directory to make multiple eshell windows easier."
  (let* ((parent (if (buffer-file-name)
                     (file-name-directory (buffer-file-name))
         (height (/ (window-total-height) 3))
         (name   (car (last (split-string parent "/" t)))))
    (split-window-vertically (- height))
    (other-window 1)
    (eshell "new")
    (rename-buffer (concat "*eshell: " name "*"))

    (insert (concat "ls"))

And the function to close the new buffer:

(defun eshell-close ()
  "Closes the window created by the function 'eshell-here'"
  (insert "exit")

I first tried simply putting replacing eshell with shell, but that led to the random buffer positions.

  • 1
    As to *shell*, see this identical/related thread: emacs.stackexchange.com/a/28924/2287
    – lawlist
    Commented Sep 19, 2018 at 21:19
  • As to *eshell*, see this identical/related thread: emacs.stackexchange.com/a/28730/2287 You can use my-display-buffer (from the previous linked thread) with eshell-get-buffer-create.
    – lawlist
    Commented Sep 19, 2018 at 21:23
  • @lawlist - Thanks for the links. Your solution: shell-get-buffer-create seems to work great for opening a new buffer in a predictable location. The shell-pop package also does a great job - like Howard Abrams eshell-functions I posted above.
    – n1k31t4
    Commented Sep 19, 2018 at 21:35

1 Answer 1


Here's what I have for this. It opens a shell in the current window.

(add-to-list 'display-buffer-alist
             '("^\\*shell\\*$" . (display-buffer-same-window)))

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.