Mad Wombat
Mad Wombat

Reputation: 15105

More than one emacs terminal

I am getting more and more used to doing everything from inside emacs, but it seems that eshell, shell and term will only run one instance each. Is there a way to run multiple terminals (preferably term) inside emacs?

Upvotes: 14

Views: 3418

Answers (8)

robru
robru

Reputation: 2383

Here's a super lightweight little function that you can call to automatically rename the term you're on, and then start a new term:

(defun new-ansi-term ()
  (interactive)
  (if (string= "*ansi-term*" (buffer-name))
      (rename-uniquely))
  (ansi-term "/bin/bash"))

Then to bind that within ansi-term, I found this works:

(defvar ansi-term-after-hook nil)
(add-hook 'ansi-term-after-hook
          '(lambda ()
             (define-key term-raw-map (kbd "C-t") 'new-ansi-term)))
(defadvice ansi-term (after ansi-term-after-advice (org))
  (run-hooks 'ansi-term-after-hook))
(ad-activate 'ansi-term)

If you then also bind new-ansi-term to C-t in the normal way, you'll find that when you're not looking at an ansi-term, C-t will focus the ansi-term buffer, and then if you are looking at an ansi-term, C-t will rename it to some unique name, and then open a new ansi-term for you. This works really well in combination with tabbar, which will show you all your opened ansi-terms just above the first line of the buffer. Easy to switch between them ;-)

Upvotes: 0

tjb
tjb

Reputation: 11728

I modified the accepted answer by Harpo so that it starts a new shell without prompting, shells will be named in the form *shell-1*,*shell-2*,*shell-3* etc.:

(setq bash-counter 1)
(defun bash ()
  "Start a bash shell"
  (interactive)
  (setq bash-counter (+ bash-counter 1))
  (let
    ((explicit-shell-file-name "/bin/bash"))
    (shell (concat "*shell-" (number-to-string bash-counter) "*"))
    ))

Upvotes: 0

Harpo
Harpo

Reputation: 116

You just have to rename the buffer, here's a function to start zsh and prompt for the buffer name:

(defun zsh (buffer-name)
  "Start a terminal and rename buffer."
  (interactive "sbuffer name: ")
  (term "/bin/zsh")
  (rename-buffer buffer-name t))

Upvotes: 10

Trey Jackson
Trey Jackson

Reputation: 74430

I personally use a screen-like package I wrote, and there's another version available on the wiki here: elscreen. It provides convenient key bindings to jump to/between the different shells.

Upvotes: 1

user178399
user178399

Reputation:

You can rename a term and start a new one. I'm using something like that, took it from someone else .emacs.

(require 'term)
(defun visit-ansi-term ()
  "If the current buffer is:
     1) a running ansi-term named *ansi-term*, rename it.
     2) a stopped ansi-term, kill it and create a new one.
     3) a non ansi-term, go to an already running ansi-term
        or start a new one while killing a defunt one"
  (interactive)
  (let ((is-term (string= "term-mode" major-mode))
        (is-running (term-check-proc (buffer-name)))
        (term-cmd "/bin/bash")
        (anon-term (get-buffer "*ansi-term*")))
    (if is-term
        (if is-running
            (if (string= "*ansi-term*" (buffer-name))
                (call-interactively 'rename-buffer)
              (if anon-term
                  (switch-to-buffer "*ansi-term*")
                (ansi-term term-cmd)))
          (kill-buffer (buffer-name))
          (ansi-term term-cmd))
      (if anon-term
          (if (term-check-proc "*ansi-term*")
              (switch-to-buffer "*ansi-term*")
            (kill-buffer "*ansi-term*")
            (ansi-term term-cmd))
        (ansi-term term-cmd)))))

Or you can have just one and start a screen session in it.

Upvotes: 2

dnolen
dnolen

Reputation: 18556

You can always create a new shell with C-u M-x shell

Upvotes: 6

Scott Wales
Scott Wales

Reputation: 11696

Use the command M-x rename-buffer to give the current shell buffer a new name, then you can start a new shell.

Upvotes: 18

Related Questions