Como executar vários shells no Emacs

147

Estou usando o Emacs 23.3.1 no Windows 7. Eu sei que posso executar o shell do emacs usando o Mx shell. Gostaria de ter várias janelas de shell ao mesmo tempo, mas digitar Mx shell uma segunda vez apenas me abre a mesma janela de shell.

Existe uma maneira de ter diferentes janelas de shell?

S4M
fonte

Respostas:

210

C-u M-x shell vai fazer isso.

Ele solicitará um nome para o novo shell, basta pressionar return para o padrão (que será algo como *shell*<2>.

Também funciona com eshell.

Outro truque, se você usar o eshell: assim como o M-x eshellleva de volta a *eshell*(em vez de iniciar um novo eshell), se você usar um argumento de prefixo numérico, ele o levará ao buffer do eshell. Por exemplo, C-3M-xeshelllevará você a *eshell*<3>. Infelizmente, se você usa shell (em vez de eshell), esse truque parece não funcionar (no meu Emacs 24.0.50.1, pelo menos.)

Matt Curtis
fonte
1
OK, este funciona. O shell Cu Mx me pergunta o nome do novo shell. Obrigado!
S4M
1
Sem problemas S4M. Eu adicionei uma dica para eshell; como você perguntou sobre o shell, não sei se você o achará útil, mas convide os usuários com a mesma pergunta a acharem útil.
Matt Curtis
Obrigado Matt. O que Cu significa / faz aqui?
Tim
4
C-uexecuta o comando universal-argument. É uma maneira de injetar um argumento no próximo comando. Você pode ler mais sobre isso com C-h k C-u( C-h kcorridas describe-key, muito útil!)
Matt Curtis
Então C-h f eshell( C-h fexecuta describe-function) mostra que a função eshellaceita um argumento opcional. Citação: Um prefixo numérico arg (como em C-u 42 M-x eshell RET) muda para a sessão com esse número, criando-o, se necessário. Um prefixo não numérico arg significa criar uma nova sessão.
Matt Curtis
34

Você pode renomear o buffer do seu shell com M-x rename-buffer. Então você poderá iniciar um segundo shell.

Giann
fonte
2
Eu prefiro ir com a solução de Matt Curtis. Executar um shell com um novo nome me parece mais fácil do que renomear o atual e depois executar um novo.
S4M
8

Veja o MultiTerm , que facilita muito o gerenciamento de vários terminais no Emacs.

Victor Deryagin
fonte
1
Observe que o modo shell e o termo mode são duas coisas completamente diferentes.
darkfeline
5

Também pode ser útil usar uma interface semelhante a uma tela para seus shells. Eu escrevi o meu próprio, mas existem outros por aí, como o EmacsScreen .

Trey Jackson
fonte
5

Depois de mais de quatro anos, vejo que algumas pessoas ainda estão analisando esse problema algumas vezes, então publicarei uma função rápida que escrevi para carregar um shell e pedir seu nome. Dessa forma, você pode nomear um shell "classificar arquivos" se for dedicado à classificação de arquivos e outro "hive" se for dedicado a executar consultas de seção. Eu uso isso todos os dias agora (no 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
fonte
4

Isso gerará automaticamente uma nova instância do shell em qualquer buffer que você estiver usando; ligá-lo ao MS ou algo assim e alegria instantânea:

(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)
  )
)

Muito obrigado ao phils por recomendar uma reescrita usando let, mesmo que o resultado seja parênteses ainda mais terríveis ...: \

bjsdaiyu
fonte
1
Você precisa letvincular variáveis ​​se elas forem destinadas ao uso local. Agora você tem valores globais para currentbufe newbuf.
Phils
como a função new-shell se compara à minha função create-shell?
S4M
1
@ S4M é principalmente uma questão de preferência, sou preguiçoso e quero meu shell imediatamente, na janela ativa no momento e sem precisar digitar um nome de buffer na frente.
Bjsdaiyu
@phils obrigado pela dica, eu não estou em todos familiarizados com lisp assim vai refazê-la usando atribuição locais :-).
bjsdaiyu
hmm, acho que você pode pegar minha função e adicionar um nome padrão que seria algo como shell_n , onde n seria o n-ésimo shell aberto, enquanto o Cu create-shell solicitaria um nome para o shell.
S4M
0

Isso abrirá um novo shell sempre que você chamar a função e renomeá-la automaticamente, se necessário. A vantagem adicionada é que, se você estiver editando arquivos remotamente (dired / tramp ...), isso abrirá um shell no host remoto e renomeá-lo-á automaticamente com o nome do host remoto:

(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
fonte