161

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?

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
S4M
  • 4,561
  • 6
  • 37
  • 47

7 Answers7

235

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.)

Matt Curtis
  • 23,168
  • 8
  • 60
  • 63
  • 2
    OK, this one works. C-u M-x shell asks me the name of the new shell. Thanks! – S4M Jun 30 '11 at 10:37
  • 1
    No problems S4M. I added a tip for eshell; as you asked about shell I don't know if you'll find it useful, but eshell users with the same question might find it useful. – Matt Curtis Jun 30 '11 at 10:44
  • Thanks, Matt. What does C-u mean/do here? – Tim Sep 22 '14 at 11:34
  • 4
    `C-u` runs the command `universal-argument`. It's a way of injecting an argument into the next command. You can read more about it with `C-h k C-u` (`C-h k` runs `describe-key`, very handy!) – Matt Curtis Sep 28 '14 at 01:35
  • Then `C-h f eshell` (`C-h f` runs `describe-function`) shows that the function `eshell` takes an optional argument. Quote: A numeric prefix arg (as in `C-u 42 M-x eshell RET`) switches to the session with that number, creating it if necessary. A nonnumeric prefix arg means to create a new session. – Matt Curtis Sep 28 '14 at 01:40
  • 1
    I use this all the time. I have a pet peeve, though which is that I end up with a line in the Ibuffer that says `*shell*<2> 3038 Shell (shell<1> run) ~/` and when you are trying to quit, emacs refers to the shell as shell<1> even though the name is shell<2>. Sure, I can edit the suggested default name parameter, but I don't do that. – nroose Mar 01 '16 at 21:31
  • How can you do this in Spacemacs? – Midiparse Oct 23 '17 at 21:41
  • Looks like Spacemacs has its own thing going on. Try `SPC : shell C-u RET` (sources: https://github.com/syl20bnr/spacemacs/blob/master/doc/DOCUMENTATION.org#universal-argument and http://boyanangelov.com/spacemacs/doc/DOCUMENTATION.html#orgheadline55) – Matt Curtis Nov 03 '17 at 22:55
44

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

Giann
  • 3,142
  • 3
  • 23
  • 33
  • 2
    I prefer to go with Matt Curtis's solution. Running a shell under a new name seems to me easier than renaming the current one and then run a new one. – S4M Jun 30 '11 at 10:58
9

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

Victor Deryagin
  • 11,895
  • 1
  • 29
  • 38
8

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 "*"))))
S4M
  • 4,561
  • 6
  • 37
  • 47
5

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.

Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
4

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...:\

bjsdaiyu
  • 93
  • 8
  • 1
    You need to `let`-bind variables if they're intended for local use. As it is you now have global values for `currentbuf` and `newbuf`. – phils May 28 '13 at 07:14
  • how does the new-shell function compare with my create-shell function? – S4M May 28 '13 at 07:21
  • 1
    @S4M it's mainly an issue of preference, I'm lazy and want my shell immediately, in the currently active window and without having to type a buffername up front. – bjsdaiyu May 29 '13 at 19:35
  • @phils thanks for the tip, i'm not at all familiar with lisp so will rework it using local assignment.:-) – bjsdaiyu May 29 '13 at 19:36
  • hmm, I think you can take my function and add a default name that would be something like *shell_n*, where n would be the n-th shell open, while C-u create-shell would prompt a name for the shell. – S4M May 29 '13 at 20:53
1

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)
  ))