Question

In Emacs, I don't like shell-mode/eshell-mode since they cannot take full use of zsh and they suck much.

So I hope to use xterm as the external subprocess.

(global-set-key (kbd "M-<f2>")
                (lambda () (interactive)
                  (start-process "XTerm" nil "xterm")))

And now the PWD of xterm is synced with Emacs default-directory and the term is now a full-feathered one. But there is ONE problem: I the startup time of the sub-rountine is always disappointing.

So I hope starting xterm only once and when in Emacs, if it finds there is a subprocess called XTerm running, 1) switch to it 2)set the PWD of shell running in xterm to default-directory of Emacs.

Is it possible to do so?

If neither is possible, then with tmux, can we achieve this goal?

Was it helpful?

Solution

Here's my setup:

(defvar terminal-process)
(defun terminal ()
  "Switch to terminal. Launch if nonexistant."
  (interactive)
  (if (get-buffer "*terminal*")
      (switch-to-buffer "*terminal*")
    (term "/bin/bash"))
  (setq terminal-process (get-buffer-process "*terminal*")))

(global-set-key "\C-t" 'terminal)

Could you elaborate more on the start-up time? Mine is around 0.3s.

UPD A small snippet from my dired customization

I've got this in my dired setup:

(add-hook
 'dired-mode-hook
 (lambda()
   (define-key dired-mode-map (kbd "`")
     (lambda()(interactive)
       (let ((current-dir (dired-current-directory)))
         (term-send-string
          (terminal)
          (format "cd %s\n" current-dir)))))))

where terminal is:

(defun terminal ()
  "Switch to terminal. Launch if nonexistant."
  (interactive)
  (if (get-buffer "*terminal*")
      (switch-to-buffer "*terminal*")
    (term "/bin/bash"))
  (setq terminal-process (get-buffer-process "*terminal*")))

What this does is it opens a terminal for the same directory as dired buffer, reusing the existing *terminal*, or creating a new one if it's absent.

To summarize the answer to your question:

Yes, it's possible. It's done with:

(term-send-string
 (terminal)
 (format "cd %s\n" default-directory))

OTHER TIPS

If xterm is not a hard requirement, only that you somehow launch zsh from emacs, then take a look at AnsiTerm, or my preference, MultiTerm. They implement a terminal emulator (like xterm) in emacs, so you can run whatever terminal application (e.g. zsh) in a buffer. I like MultiTerm because it has better defaults IMO.

Then you can change directories with

(defun term-send-cd (&optional dir)
  (interactive "DDirectory: ")
  (let ((dir (if dir (expand-file-name dir) "")))
    (term-send-raw-string (format "cd '%s'\n" dir))))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top