Как запустить несколько оболочек на Emacs

147

Я использую Emacs 23.3.1 в Windows 7. Я знаю, что могу запустить оболочку из Emacs, используя Mx. Я хотел бы иметь несколько окон оболочки одновременно, но ввод Mx shell во второй раз просто открывает мне то же самое окно оболочки.

Есть ли способ иметь разные окна оболочки?

S4M
источник

Ответы:

210

C-u M-x shell сделаю это.

Он запросит имя для новой оболочки, просто нажмите return для значения по умолчанию (что-то вроде *shell*<2>.

Также работает с eshell.

Еще один прием, если вы используете eshell: точно так же, как M-x eshellвы возвращаетесь к *eshell*(а не запускаете новый eshell), если вы используете аргумент числового префикса, он приведет вас к этому буферу eshell. Например, C-3M-xeshellприведет вас к *eshell*<3>. К сожалению, если вы используете shell (а не eshell), этот трюк не работает (по крайней мере, в моем Emacs 24.0.50.1).

Мэтт Кертис
источник
1
ОК, этот работает Cu Mx shell спрашивает у меня название новой оболочки. Спасибо!
S4M
1
Без проблем S4M. Я добавил совет для eshell; как вы спросили об оболочке, я не знаю, найдете ли вы ее полезной, но пользователи eshell с таким же вопросом могут найти ее полезной.
Мэтт Кертис
Спасибо, Мэтт. Что Cu означает / делает здесь?
Тим
4
C-uзапускает команду universal-argument. Это способ ввода аргумента в следующую команду. Вы можете прочитать больше об этом с C-h k C-u( C-h kработает describe-key, очень удобно!)
Мэтт Кертис
Затем C-h f eshell( C-h fвыполняется describe-function) показывает, что функция eshellпринимает необязательный аргумент. Цитата: числовой префикс arg (как в C-u 42 M-x eshell RET) переключается на сеанс с этим номером, создавая его при необходимости. Нечисловой префикс arg означает создание нового сеанса.
Мэтт Кертис
34

Вы можете переименовать буфер вашей оболочки с помощью M-x rename-buffer. Тогда вы сможете запустить вторую оболочку.

Giann
источник
2
Я предпочитаю пойти с решением Мэтта Кертиса. Запуск оболочки под новым именем кажется мне проще, чем переименование текущего, а затем запуск нового.
S4M
8

Посмотрите на MultiTerm , он делает управление несколькими терминалами в Emacs намного проще.

Виктор Дерягин
источник
1
Обратите внимание, что режим оболочки и режим термина - это две совершенно разные вещи.
darkfeline
5

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

Трей Джексон
источник
5

По прошествии более четырех лет я вижу, что некоторые люди по-прежнему рассматривают эту проблему иногда, поэтому я опубликую быструю написанную мной функцию для загрузки оболочки и запроса ее имени. Таким образом, вы можете назвать оболочку «sort-files», если она предназначена для сортировки файлов, и другую «hive», если она предназначена для выполнения запросов к кустам. Я использую это каждый день (на emacs 24):

(defun create-shell ()
    "creates a shell with a given name"
    (interactive);; "Prompt\n shell name:")
    (let ((shell-name (read-string "shell name: " nil)))
    (shell (concat "*" shell-name "*"))))
S4M
источник
4

Это автоматически сгенерирует новый экземпляр оболочки в любом буфере, который вы используете; свяжите это с MS или чем-то подобным и мгновенной радостью:

(defun new-shell ()
  (interactive)

  (let (
        (currentbuf (get-buffer-window (current-buffer)))
        (newbuf     (generate-new-buffer-name "*shell*"))
       )

   (generate-new-buffer newbuf)
   (set-window-dedicated-p currentbuf nil)
   (set-window-buffer currentbuf newbuf)
   (shell newbuf)
  )
)

Большое спасибо phils за рекомендацию переписать с использованием let, хотя в результате получаются еще более ужасные скобки ...: \

bjsdaiyu
источник
1
Вам необходимо letсвязать переменные, если они предназначены для локального использования. Как сейчас, у вас есть глобальные значения для currentbufи newbuf.
Филс
как функция new-shell сравнивается с моей функцией create-shell?
S4M
1
@ S4M это в основном вопрос предпочтений, я ленивый и хочу немедленно мою оболочку, в текущем активном окне и без необходимости предварительно вводить имя буфера.
bjsdaiyu
@phils спасибо за совет, я совсем не знаком с lisp, поэтому буду переделывать его, используя локальное назначение. :-)
bjsdaiyu
хм, я думаю, что вы можете взять мою функцию и добавить имя по умолчанию, которое будет выглядеть примерно как shell_n , где n будет открывать n-ю оболочку, а Cu create-shell запросит имя для оболочки.
S4M
0

Это будет открывать новую оболочку каждый раз, когда вы вызываете функцию и автоматически переименовываете ее, если это необходимо. Плюс в том, что если вы редактируете файлы удаленно (dired / tramp ...), это откроет оболочку на удаленном хосте и автоматически переименует ее с удаленным именем хоста:

(defun ggshell (&optional buffer)
(interactive)
(let* (
       (tramp-path (when (tramp-tramp-file-p default-directory)
             (tramp-dissect-file-name default-directory)))
       (host (tramp-file-name-real-host tramp-path))
       (user (if (tramp-file-name-user tramp-path)
         (format "%s@" (tramp-file-name-user tramp-path)) ""))
       (new-buffer-nameA (format "*shell:%s*" host))
       (new-buffer-nameB (generate-new-buffer-name new-buffer-nameA))
       (currentbuf (get-buffer-window (current-buffer)))
       )
  (generate-new-buffer new-buffer-nameB)
  (set-window-dedicated-p currentbuf nil)
  (set-window-buffer currentbuf new-buffer-nameB)
  (shell new-buffer-nameB)
  ))
DenverCoder9
источник