Подтвердить что ты не робот

Как открыть несколько терминалов?

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

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

Как я могу это достичь?

4b9b3361

Ответ 1

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

Ответ 2

Вы можете открыть несколько интерактивных оболочек. Попробуйте ввести C-u M-x shell RET RET.

Ответ 3

У вас может быть как можно больше терминалов и оболочек одновременно. Просто используйте 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* и ssh me в host05.foo.com. Если буфер *host05* уже существует, он просто переключит меня на него. Очень удобно!

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

У меня была точно такая же проблема несколько лет назад, и я не нашел ничего, что меня удовлетворило; поэтому я написал свою собственную функцию "переключить оболочку". Он переключается между текущей конфигурацией кадра или окна и буфером системной оболочки. Он также может поместить оболочку в выделенный фрейм и ввести pushd в текущий каталог буфера.

Это выдержка из моих .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 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-!

Это значительный кусок кода, который будет опубликован здесь. Но он будет работать хорошо.

Ответ 10

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

M-shift-!

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

Ответ 12

Ecb + eshell будет тем, что вы хотите точно!

Ответ 13

Я использую vi, но надеюсь, что это поможет. Я могу открыть столько терминалов, сколько хочу (например, в Ubuntu 16.04):

  ctrl + alt + t

Я обычно открываю 2 терминала и перемещаю (позицию) один терминал вправо:

  ctrl + super + right-arrow

и переместите другой терминал влево:

  ctrl + super + left-arrow

так что у меня есть разделенный экран на 2 терминала.