Как открыть несколько терминалов? - PullRequest
27 голосов
/ 22 октября 2010

В Emacs я часто нахожусь в ситуации, когда мне нужно переключаться между различными исходными файлами на различные терминалы.Однако я чувствую, что у меня нет хорошего способа сделать это эффективно, и неудобно, что вы можете открыть только одну оболочку в Emacs (shell, eshell или term).

Более того, мне нужен эффективный способ переключения между несколькими терминалами и исходными файлами.

Как мне этого добиться?

Ответы [ 13 ]

17 голосов
/ 22 октября 2010

Вы можете открыть столько терминалов и оболочек одновременно, сколько захотите. Просто используйте M-x rename-buffer, чтобы изменить имя существующего буфера *term* или *shell*, и в следующий раз, когда вы сделаете M-x term или M-x shell, будет создан совершенно новый буфер. В случае M-x 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)))))

Затем я связал эту команду с (скажем) s-h (супер H), что позволило мне просто набрать M-5 s-h . Если у меня еще не было буфера с именем *host05*, он запустил бы новый буфер эмулятора терминала, переименовал бы его в *host05* и отправил меня в host05.foo.com. Если буфер *host05* уже существует, он просто переключит меня на него. Очень удобно!

17 голосов
/ 22 октября 2010

Вы можете открыть несколько интерактивных оболочек.Попробуйте набрать Cu Mx shell RET RET .

15 голосов
/ 22 октября 2010

Попробуйте использовать MultiTerm, чтобы открыть несколько оболочек.

8 голосов
/ 22 октября 2010

Вы можете использовать Экран Emacs Lisp , который эмулирует Экран GNU и обеспечивает легкую привязку клавиш для перехода между различными оболочками.

4 голосов
/ 06 апреля 2011

Я использую много методов для включения моей терминальной жизни в 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)
3 голосов
/ 06 декабря 2011

Я регулярно использовал около 10 снарядов на своем старом рабочем месте.Секрет в том, что вы должны переименовать дополнительные буферы оболочки.Я сделал это автоматически, хотя в моем .emacs, создавая и называя оболочки логически (у меня были projnameRun и projnameBuild для каждого проекта).Работал очень хорошо вместе с чем-либо, что облегчало перефразирование нужной оболочки (вы используете конец имени проекта в сочетании с r или b для запуска / сборки).

3 голосов
/ 22 октября 2010

Я обычно делаю M - x server-start и затем использую emacsclient --no-wait для открытия файлов. Я связал это с e с некоторыми украшениями, чтобы было немного удобнее.

Я делаю всю свою работу на одном терминале и просто «выбрасываю» файлы, которые хочу редактировать, в Emacs, используя e. Внутри Emacs я манипулирую, используя iswitchb, и он работает просто отлично. YMMV.

2 голосов
/ 24 июня 2012

Полу-связанный - вы можете быстро запустить команду оболочки для выбранного файла с помощью

M-shift-!

Это экономит много времени для небольших команд chmod и т. Д.

2 голосов
/ 24 августа 2011

Несколько лет назад у меня была точно такая же проблема, и я не нашел ничего, что меня устраивало;поэтому я написал свою собственную функцию «переключить оболочку».Он переключается между текущей конфигурацией фрейма или окна и буфером системной оболочки.Он также может поместить оболочку в выделенный кадр и вставить 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-!

Это значительная часть кода, которая будет размещена здесь.Но это должно работать хорошо.

2 голосов
/ 22 октября 2010

Вместо нескольких окон терминала в emacs, я создаю другой xterm всякий раз, когда мне нужен новый терминал.Это, конечно, терпимо, потому что я использую очень легкий эмулятор терминала (urxvt), который запускается менее чем за 0,2 с.
Затем я использую мой оконный менеджер для переключения между ними и фреймами emacs.Настраиваемый оконный менеджер будет иметь множество опций для эффективного переключения между окнами.В emacs я использую windmove и ido-mode и привязал к C-tab функцию, которая переключается на последний буфер (потому что я часто использую Cx b).

Так что, не увереннасколько это полезно для вас, поскольку оно сильно отличается от вашего шаблона использования, но это то, что работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...