MultiTerm

What is multi-term.el ?

MultiTerm is a mode based on term.el, for managing multiple terminal buffers in Emacs.

Why the need for multi-term.el ?

By default, term.el provides a great terminal emulator in Emacs. But I have some troubles with term-mode:
    1. term.el just provides commands ‘term’ or ‘ansi-term’ for creating a terminal buffer. There is no special command to create or switch between multiple terminal buffers quickly.
    2. By default, the keystrokes of term.el conflict with global-mode keystrokes, which makes it difficult for the user to integrate term.el with Emacs.
    3. By default, executing the *NIX command “exit” from term-mode will leave an unused buffer.
    4. term.el won’t quit running sub-process when you kill terminal buffer forcibly.
    5. It doesn’t have a dedicated window for a debugging program.
And multi-term.el is enhanced with those features.

Install

Put Lisp:multi-term.el in your load-path, then add
        (require 'multi-term)
in ~/.emacs .
Add
        (setq multi-term-program "/bin/bash")
in ~/.emacs .
Or any shell program you like. 😊
That’s all.

Note

I found that some some people like to run emacs-within-emacs by calling “emacs -nw” inside a multi-term.el (though surely this is just for bragging rights!). However, by default the prefix keys “C-x” and “C-c” are unbound by multi-term (that is, they are processed by the host Emacs). But this means that you can’t quit your nested emacs session with “C-x C-c”. If if you want to do this, remove “C-x” and “C-c” from option ‘term-unbind-key-list’, and remove “C-c C-c” from the option ‘term-bind-key-alist’.

You may have to experiment to get the behavior you want.

Usage

multi-term.el provides the following interactive functions:

Tips

                (defun multi-term-foo ()
                  "Make a multi-term buffer running foo."
                  (let ((multi-term-program "/bin/foo"))
                    (multi-term)))

Customize

All options below can be customized by: M-x RET customize-group RET multi-term RET .

“multi-term-program” default is nil, so when create a new terminal buffer, it will try to take the shell path from an environment variable (“SHELL”, “ESHELL”, and finally default to “/bin/sh”). If you failed to create a terminal buffer, make sure setup this option with a valid shell program.
“multi-term-default-dir” default is “~/”. This is only used when the current buffer is not in a real directory.
“multi-term-buffer-name” is the base name of terminal buffer, with format *terminal<index>*.
“multi-term-scroll-show-maximum-output” if non-nil, show maximum output when the window is scrolled. Otherwise, don’t show.
“multi-term-scroll-to-bottom-on-output” if non-nil or ‘all’, scroll all windows to bottom. If ‘this’, scroll only the selected window. If ‘others’ scroll only those that are not the selected window.
“multi-term-switch-after-close” try to switch to another ‘multi-term’ buffer after closing the current one. If you don’t like this feature just set it with nil.
The keystroke list to unbind when terminal is created.
The format is ‘(“KEY-A” “KEY-B” “KEY-C”)
The keystroke alist to bind when terminal is created.
The format is ‘((“KEY-A” . COMMAND-A) (“KEY-B” . COMMAND-B) (“KEY-C” . COMMAND-C))
“multi-term-dedicated-window-height” is the height of the dedicated terminal window.
“multi-term-dedicated-max-window-height” is the maximum height limit for the dedicated terminal window.
“multi-term-dedicated-skip-other-window-p” controls whether to skip dedicated terminal window when using the command ‘other-window’ to cycle through windows. This useful when you have complex window layout for programming. Note that you can use the command “multi-term-dedicated-select” to select the dedicated window in any time.
“multi-term-dedicated-select-after-open-p” Default, multi-term won’t focus terminal window after you open dedicated window. Please make this option with t if you want focus terminal window.

Related

Have many people asked “How to setup color of multi-term?”, option ‘term-default-bg-color’ and ‘term-default-fg-color’ control foreground color and background color, so just setup like below:
    (custom-set-variables
     '(term-default-bg-color "#000000")        ;; background color (black)
     '(term-default-fg-color "#dddd00"))       ;; foreground color (yellow)
The plain old ‘term’ command never creates a new term buffer, if one already exists. On the other hand, ‘multi-term’ always creates a new one. Both behaviors are limiting when it comes to keybindings. For most of the time, when a user presses a button to get himself a terminal, he expects one he was working with before (otherwise he would probably close it earlier), but sometimes he wants a fresh new one. The following code either switches to the term buffer used last or creates a new one, if a term buffer is already selected.
    (defun last-term-buffer (l)
      "Return most recently used term buffer."
      (when l
  (if (eq 'term-mode (with-current-buffer (car l) major-mode))
      (car l) (last-term-buffer (cdr l)))))

    (defun get-term ()
      "Switch to the term buffer last used, or create a new one if
    none exists, or if the current buffer is already a term."
      (interactive)
      (let ((b (last-term-buffer (buffer-list))))
  (if (or (not b) (eq 'term-mode major-mode))
      (multi-term)
    (switch-to-buffer b))))

Screenshot

MultiTermShotPage

MultiTermDedicatedShotPage

Comment

Please write at below if you have any suggestion or bug, or mail to me. Thanks! – AndyStewart

Hi Andy. Thank you for a great mode. I love it and now use it all the time. However I found one deficiency:

- I bound (multi-term-dedicated-toggle) to a function key and use it all the time when I quickly need to do something in a term

- I set (setq multi-term-dedicated-select t) to have the dedicated buffer selected and ready to be used once it opens

- When I am done I run (multi-term-dedicated-toggle) again to get rid of the terminal. At this point I’d like the cursor return to the position it was before I opened the dedicated terminal window. However If I had more than one buffer, the cursor doesn’t always return back to the old position. I worked around it with this (this is my first lisp function; sorry if it is not pretty):

(defun it-multi-term-dedicated-toggle ()
  "jump back to previous location after toggling ded term off"
  (interactive)
  (if (multi-term-dedicated-exist-p)
      (progn
  (multi-term-dedicated-toggle)
  (switch-to-buffer-other-window old-buf))
    (progn
      (setq old-buf (current-buffer))
      (multi-term-dedicated-toggle))
    )
  )

It may be a good idea to add this functionality to multi-term.el

After multi-term.el 0.8.13 , you just need use below code to make you happy: – AndyStewart

(setq multi-term-dedicated-close-back-to-open-buffer-p t)

Ilya - you might watch to use select-window and selected-window rather than switching buffers when you restore state. —MPH

Sorry Ilya, i have LeaveEmacs , haven’t time write any elisp code even i really want help you. So sorry.

   -- AndyStewart

Hi! it seems pretty cool. I used to run M-x shell in my emacs and play a lot of my daily job in it. But I found that in the terminal mode I just not able to send a Ctrl-r charactor to my shell. You know it used to invoke a (reverse-i-search) in bash command history. Anytime when I type C-r in the terminal it just invoke (isearch-backward) in Emacs, even when I type C-q C-r. I can unset the default key binding on C-r in Emacs, but it seems not work for terminal mode. Then I made a term-mode-hook and it really runs, but the key binding of C-r is still there. It’s quite strange.

(add-hook 'term-mode-hook
    (lambda()
      (global-unset-key (kbd "C-r"))
;	    (local-unset-key (kbd "C-r"))
      (message "%s" "This is in term mode and hook enabled.")
))

Of course I can copy a ^R charactor from somewhere else and paste it into terminal window, it really works but it’s too annoying. Does anybody has good idea?

   -- DoveYoung
Try type M-r i think that’s your need. 😊
Because C-r is default keystroke for isearch-backward, for avoid conflict with C-r, i binding M-r to send “C-r” character to shell.
You can use option term-bind-key-alist/term-unbind-key-list to binding/unbinding special keystroke in multi-term.el, and don’t use term-mode-hook. 😊 – AndyStewart

Hi. I’m wondering how I can get the ESC key to forward on an actual terminal escape (C-[) to the shell process. Currently it’s being interpreted as meta. Since I am able to actually successfully press the meta key on my own, I don’t need ESC to duplicate that functionality. I’ve tried removing “<ESC>” from term-unbind-key-list, but still when I hit the ESC key, it’s being used by Emacs.

May be the following code will help you.

Define a function like the following one.

(defun term-send-esc ()
  "Send ESC in term mode."
  (interactive)
  (term-send-raw-string "\e"))

Then use a convenient key to send ESC to terminal. I am fine with “C-c C-e”

(add-to-list 'term-bind-key-alist '("C-c C-e" . term-send-escape))

--Noorul

I have merge term-send-esc feature in lastest multi-term.el , thanks Noorul – AndyStewart

Hi! Please add 256 color support to multiterm!

--Daniel

Hi Andy - thanks for multiterm 😊 I’m experiencing an odd issue in FreeBSD, which seems shell-independent (happens with sh and zsh). On Linux, if I change directory inside a multi-term, that changes the default directory for the containing buffer in Emacs. So I can cd into a directory in a multiterm, then do a find-file-in-project and it’ll run from the directory I’ve changed into. On FreeBSD that doesn’t happen; the default directory for the buffer remains unchanged after issuing a cd inside multiterm.

– duncan_bayne

What’s the dedicated-open for? -Mike

Mike, it opens a dedicated window for multi-term. You can read about dedicated windows in the Emacs manual.

(defun term-send-kill-line ()
  "Kill line in multi-term mode with the possibility to paste it like in a normal shell."
  (interactive)
  (kill-line)
  (term-send-raw-string "\C-k"))

EstOwnya

Sticky mode: show/hide all (multi-term) terminals on screen

--Shri


CategoryShell