154
votes

I am using Emacs 23.3.1 on windows 7. I know that I can run shell from emacs using M-x shell. I would like to have multiple shell windows in the same time, but typing M-x shell a second time just opens me the same shell window.

Is there a way to have different shell windows?

7

7 Answers

220
votes

C-u M-x shell will do it.

It will prompt for a name for the new shell, just hit return for the default (which will be something like *shell*<2>.

Also works with eshell.

Another trick, if you use eshell: just as M-x eshell takes you back to *eshell* (rather than starting a new eshell), if you use a numeric prefix argument it will take you to that eshell buffer. For instance, C-3M-xeshell will take you to *eshell*<3>. Sadly if you use shell (rather than eshell), this trick doesn't seem to work (in my Emacs 24.0.50.1 at least.)

36
votes

You can rename the buffer of your shell with M-x rename-buffer. Then you will be able to launch a second shell.

8
votes

Look at MultiTerm, it makes managing multiple terminals in Emacs much easier.

7
votes

After more than four years, I see that some people are still looking at this issue sometimes, so I will publish a quick function I wrote to load a shell and ask for its name. That way you can name a shell "sort-files" if it is dedicated to sorting files and another one "hive" if it's dedicated to run hive queries. I use that everyday now (on emacs 24):

(defun create-shell ()
    "creates a shell with a given name"
    (interactive);; "Prompt\n shell name:")
    (let ((shell-name (read-string "shell name: " nil)))
    (shell (concat "*" shell-name "*"))))
5
votes

It might also be useful to use a screen-like interface to your shells. I've written my own, but there are others out there, like EmacsScreen.

4
votes

This will autogenerate a new shell instance in whatever buffer you happen to be using; bind it to M-S or somethings like that and instant joy:

(defun new-shell ()
  (interactive)

  (let (
        (currentbuf (get-buffer-window (current-buffer)))
        (newbuf     (generate-new-buffer-name "*shell*"))
       )

   (generate-new-buffer newbuf)
   (set-window-dedicated-p currentbuf nil)
   (set-window-buffer currentbuf newbuf)
   (shell newbuf)
  )
)

Many thanks to phils for recommending a rewrite using let, even though the result is even more awful parentheses...:\

0
votes

This will open a new shell each time you invoke the function and rename it automatically if needed. The added plus is if you are editing files remotely (dired/tramp...), this will open a shell on the remote host and rename it automatically with the remote hostname:

(defun ggshell (&optional buffer)
(interactive)
(let* (
       (tramp-path (when (tramp-tramp-file-p default-directory)
             (tramp-dissect-file-name default-directory)))
       (host (tramp-file-name-real-host tramp-path))
       (user (if (tramp-file-name-user tramp-path)
         (format "%s@" (tramp-file-name-user tramp-path)) ""))
       (new-buffer-nameA (format "*shell:%s*" host))
       (new-buffer-nameB (generate-new-buffer-name new-buffer-nameA))
       (currentbuf (get-buffer-window (current-buffer)))
       )
  (generate-new-buffer new-buffer-nameB)
  (set-window-dedicated-p currentbuf nil)
  (set-window-buffer currentbuf new-buffer-nameB)
  (shell new-buffer-nameB)
  ))