2010-10-22 244 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個終端分屏的屏幕。