2010-10-22 187 views
24

在Emacs中,我经常发现自己处于需要在各种源文件之间来回跳转到各种终端的情况。然而,我觉得我没有一个好的方法来有效地做到这一点,并且很笨拙,您只能在Emacs(shelleshellterm)中打开一个shell如何打开多个终端?

此外,我需要一个有效的方法来处理多个终端和源文件。

我该如何做到这一点?

回答

14

尝试使用MultiTerm来打开多个shell。

+1

是的,有多个多*包。我使用2个键绑定的多重eshell。一个用于循环shell缓冲区,另一个用于创建新的shell缓冲区。 – kjfletch 2010-10-22 07:57:56

2

而不是在emacs中有几个终端窗口,每当我需要一个新的终端时,我产生了一个不同的xterm。这当然是可以忍受的,因为我使用了一个非常轻便的终端模拟器(urxvt),它在0.2s以下开始。
然后,我使用我的窗口管理器在它们和emacs帧之间切换。一个可配置的窗口管理器将有足够的选项来调整窗口(非常有效)之间的切换。在emacs里面,我使用了windmove和ido-mode,并且绑定了C-tab一个切换到最后一个缓冲区的函数(因为我很多时候使用C-x b)。

所以呃,不知道它对你有多大用处,因为它与你的使用模式有很大的不同,但这对我来说很有用。

12

您当然可以打开多个交互式shell。试着输入C-ùM-XshellRETRET

3

我通常做的一个中号 - Xserver-start然后用emacsclient --no-wait打开文件。我已经用e这个别名来修饰它,所以它更方便一些。

我在一个终端上完成所有工作,并使用e将我想要编辑的文件“扔”到Emacs中。在Emacs里面,我使用iswitchb,并且工作得很好。因人而异。

8

您可以使用Emacs Lisp Screen,它模拟GNU Screen,并提供简单的键绑定以跳转到多个不同的shell之间以及之间。

12

您可以根据需要一次打开多个终端和壳。只需使用M-x rename-buffer来更改现有的*term**shell*缓冲区的名称,并且下次您执行M-x termM-x shell时,将创建一个全新的缓冲区。在M-x shell的情况下,前缀参数会导致系统提示您输入新shell缓冲区的名称,如offby1所示。

几年前我有一份工作,我不得不定期登录到名为“host01.foo.com”,“host02.foo.com”等各种生产服务器。我写了这样一个小功能,使其更易于管理他们所有:

(defun ssh-to-host (num) 
    (interactive "P") 
    (let* ((buffer-name (format "*host%02d*" num)) 
     (buffer (get-buffer buffer-name))) 
    (if buffer 
     (switch-to-buffer buffer) 
     (term "/bin/bash") 
     (term-send-string 
     (get-buffer-process (rename-buffer buffer-name)) 
     (format "ssh host%02d.foo.com\r" num))))) 

然后我束缚,这命令(比方说)SH(超级2H),使我只需键入M-5 sh。如果我没有名为*host05*的缓冲区,它将启动一个新的终端仿真缓冲区,将其重命名为*host05*,然后将我ssh登录到host05.foo.com。如果缓冲区*host05*已经存在,它只会将我切换到它。非常方便!

4

我用结合我的极限寿命到Emacs许多方法:

  • elscreen.el是一个生命的救星,如果你有一个复杂的窗口布局像gdb或者干脆成为不堪重负的混乱,你只需打开一个新的屏幕。在你的情况下,你可以将一个屏幕专用于终端。
  • multi-term.el使管理终端更容易一点。
  • shell-pop.el,快速终端访问的好工具。 shell-pop让您指定一键开启和关闭特定的壳缓冲窗口,如果你已经使用下拉终端,如tilda知道是多么的方便这可以是:

这里是和例子我shell-pop的配置,我用钥匙C-t弹出一个eshell

(require 'shell-pop) 
(shell-pop-set-internal-mode "eshell")  ; Or "ansi-term" if you prefer 
(shell-pop-set-window-height 60)   ; Give shell buffer 60% of window 
;; If you use "ansi-term" and want to use C-t 
;; (defvar ansi-term-after-hook nil) 
;; (add-hook 'ansi-term-after-hook 
;;   '(lambda() 
;;    (define-key term-raw-map (kbd "C-t") 'shell-pop))) 
;; (defadvice ansi-term (after ansi-term-after-advice (org)) 
;; (run-hooks 'ansi-term-after-hook)) 
;; (ad-activate 'ansi-term) 
(global-set-key (kbd "C-t") 'shell-pop) 
2

几年前我有完全相同的问题,并没有发现任何满足我。所以我写了我自己的“切换外壳”功能。它在当前帧或窗口配置和系统shell缓冲区之间切换。它也可以将外壳放入专用的框架中,并将pushd注入到当前缓冲区目录。

这是my .emacs摘录:

(defvar --toggle-shell-last-window-conf nil "The last window configuration.") 
(defvar --toggle-shell-last-buf nil "The last buffer object in case there's no last window configuration.") 
(defvar --toggle-shell-last-frame nil "The frame that was selected when opening a shell buffer.") 

(defun --toggle-shell-have-conf() 
    (window-configuration-p --toggle-shell-last-window-conf)) 

(defun --toggle-shell-store-last-conf() 
    (setq --toggle-shell-last-buf (current-buffer) 
    --toggle-shell-last-frame (selected-frame) 
    --toggle-shell-last-window-conf (current-window-configuration))) 

(defun --toggle-shell-restore-last-conf() 
    (if (--toggle-shell-have-conf) 
     (progn (raise-frame --toggle-shell-last-frame) 
     (set-window-configuration --toggle-shell-last-window-conf)) 
    (let ((bufnam (if (bufferp --toggle-shell-last-buf) 
       (buffer-name --toggle-shell-last-buf) --toggle-shell-last-buf))) 
     (if bufnam 
     (if (get-buffer bufnam) (switch-to-buffer bufnam t) 
     (message "%s: buffer not available" bufnam)))))) 

(defun --toggle-shell (&optional display inject-cd) 
    "Toggles between current buffers and a system shell buffer. With prefix-arg 
close the shell. 

When DISPLAY is 'vertical splits the shell as vertical window; when 'frame uses 
a dedicated frame (default: single window). When INJECT-CD executes a `pushd' 
to the working directory of the buffer from which you toggled the shell." 
    (interactive) 
    (let* ((shell-buf (get-buffer "*shell*")) 
    (shell-window   ; non-nil when currently displayed 
     (if shell-buf (get-buffer-window shell-buf t))) 
    (shell-frame 
     (if shell-window (window-frame shell-window))) 
    (in-shell (eq (current-buffer) shell-buf)) 
    (vertical (string= display 'vertical)) 
    (popup-frame (or (string= display 'frame) 
       (and inject-cd (not (bufferp shell-buf))) 
       (and (framep shell-frame) 
        (not (eq shell-frame (selected-frame))))))) 
    ;; With prefix-arg close shell, restore windows. Otherwise (no prefix-arg) 
    ;; toggle shell window; restore windows when called twice in a row, or the 
    ;; current buffer is the shell buffer (`in-shell'). 
    (if current-prefix-arg 
    (if (bufferp shell-buf) 
     (progn (message "Exiting shell '%s'" (buffer-name shell-buf)) 
      (kill-buffer shell-buf) 
      (if in-shell (--toggle-shell-restore-last-conf))) 
     (error "No shell buffer to kill.")) 
     ;; If already in shell-buffer toggle back to stored frame-configuration. 
     (if (and in-shell (not inject-cd)) 
     (progn 
     (--toggle-shell-restore-last-conf) 
     ;; Recurse to reopen the shell-buffer in a dedicated frame, or 
     ;; close the dedicated frame and reopen the buffer in a window. 
     (if (and popup-frame (eq shell-frame (selected-frame))) 
     (--toggle-shell 'frame inject-cd) 
      (when (and popup-frame shell-frame) 
     (delete-frame shell-frame) 
     (--toggle-shell nil inject-cd)))) 
    ;; Not in shell buffer. Warp to it or create new one. 
    (unless in-shell 
     (--toggle-shell-store-last-conf)) 
    (if popup-frame 
     (progn (switch-to-buffer-other-frame (or shell-buf "*shell*")) 
      (raise-frame 
      (or shell-frame (window-frame (get-buffer-window "*shell*" t))))) 
     (if (> (count-windows) 1) 
      (delete-other-windows))) 
    ;; Finally `cd' into the working directory the current buffer. 
    (let ((new-shell (not (bufferp shell-buf))) 
      (new-dir  ; `default-directory' of `--toggle-shell-last-buf' 
      (if --toggle-shell-last-buf 
      (buffer-local-value 'default-directory --toggle-shell-last-buf)))) 
     ;; Open shell, move point to end-of-buffer. The new shell-buffer's 
     ;; `default-directory' will be that of the buffer the shell was 
     ;; launched from. 
     (when vertical 
     (if (> (count-windows) 1) 
     (delete-other-windows)) 
     (split-window-vertically) (other-window 1)) 
     (funcall 'shell) 
     (when new-shell 
     (message "New shell %s (%s)" (buffer-name (current-buffer)) new-dir) 
     (if inject-cd (sit-for 2))) ; wait for prompt 
     (goto-char (point-max)) 
     ;; If on a command-prompt insert and launch a "cd" command (assume no 
     ;; job is running). 
     (when (and inject-cd new-dir) 
     (save-excursion 
      (backward-line-nomark) (end-of-line) 
      (unless (setq inject-cd (re-search-forward comint-prompt-regexp (point-max) t)) 
     (error "Cannot `pushd', shell is busy"))) 
     (when (and inject-cd) 
      (let* ((cmd (format 
       "pushd '%s' %s" (comint-quote-filename new-dir) 
       (if (buffer-file-name --toggle-shell-last-buf) 
        (format "# '%s'" (file-name-directory (buffer-file-name --toggle-shell-last-buf))) 
       "")))) 
     ;; `shell-process-cd' set new `default-directory' and set 
     ;; `shell-last-dir' to old. (If the pushd command is 
     ;; successful, a dirs is performed as well; >nul discards this 
     ;; output.) 
     (shell-process-cd new-dir) 
     (insert cmd) 
     (comint-send-input) 
     (message "%s: cd '%s'" (buffer-name --toggle-shell-last-buf) new-dir)) 
     ) 
     ) 
    ) 
    ) 
    ) 
    ) 
) 

--toggle-shell是做的伎俩功能。我将它绑定到F12:

;; F12   toggle between shell buffer and current window configuration 
;; SHIFT-F12 like before, but let shell buffer appear in a dedicated frame 
;; ALT-F12  inject a pushd to change to directory of current buffer 
;; CTRL-F12 `shell-command' 

(global-set-key [(f12)] '--toggle-shell) 
(global-set-key [(shift f12)] '(lambda()(interactive)(--toggle-shell 'frame))) 
(global-set-key [(meta f12)] '(lambda()(interactive)(--toggle-shell nil t))) 
(global-set-key [(meta f10)] '(lambda()(interactive)(--toggle-shell nil t))) 
(global-set-key [(control f12)] 'shell-command) ; alias M-! 

这是一个重要的代码发布在这里。但它应该工作得很好。

3

我经常在旧工作场所使用10个左右的贝壳。秘密是你必须重新命名额外的shell缓冲区。我在.emacs中自动执行了这个操作,从逻辑上创建并命名了这些shell(我为每个项目都使用了projnameRun和projnameBuild)。与任何事情一起工作得很好,使得重新获得正确的shell非常容易(您可以使用项目名称的结尾与r或b结合运行/构建)。

+0

真的,这是正确的答案。 – 2016-04-17 03:23:47

2

半相关的 - 你可以快速地在选定的文件运行shell命令

M-shift-! 

它节省了较小的命令搭配chmod等

0

Ecb + eshell将是你想要的!

0

我使用vi,但希望这有助于。如我想通过(例如在Ubuntu 16.04)。我可以打开为许多终端:

ctrl + alt + t 

我通常是开放的2个端子,并且通过移动(位置)一个端子连接到右:

ctrl + super + right-arrow 

并通过以下方式将另一个终端移动到左边:

ctrl + super + left-arrow 

这样我就有了一个由2个终端分屏的屏幕。