Cómo ejecutar múltiples shells en Emacs

147

Estoy usando Emacs 23.3.1 en Windows 7. Sé que puedo ejecutar shell desde emacs usando Mx shell. Me gustaría tener varias ventanas de shell al mismo tiempo, pero escribir Mx shell por segunda vez me abre la misma ventana de shell.

¿Hay alguna manera de tener diferentes ventanas de shell?

S4M
fuente

Respuestas:

210

C-u M-x shell lo haré.

Solicitará un nombre para el nuevo shell, solo presione la tecla de retorno para el valor predeterminado (que será algo así como) *shell*<2>.

También funciona con eshell.

Otro truco, si usa eshell: al igual que lo M-x eshelllleva de regreso a *eshell*(en lugar de comenzar un nuevo eshell), si usa un argumento de prefijo numérico, lo llevará a ese búfer de eshell. Por ejemplo, C-3M-xeshellte llevará a *eshell*<3>. Lamentablemente, si usa shell (en lugar de eshell), este truco no parece funcionar (en mi Emacs 24.0.50.1 al menos).

Matt Curtis
fuente
1
OK, este funciona. Cu Mx shell me pregunta el nombre del nuevo shell. ¡Gracias!
S4M
1
No hay problemas S4M. Agregué un consejo para eshell; como preguntaste sobre shell, no sé si lo encontrarás útil, pero los usuarios de eshell con la misma pregunta podrían encontrarlo útil.
Matt Curtis
Gracias Matt. ¿Qué significa Cu / hacer aquí?
Tim
44
C-uejecuta el comando universal-argument. Es una forma de inyectar un argumento en el siguiente comando. Puede leer más sobre esto con C-h k C-uC-h kcorre describe-key, muy útil!)
Matt Curtis
Luego C-h f eshell( C-h fejecuta describe-function) muestra que la función eshelltoma un argumento opcional. Cita: Un prefijo numérico arg (como en C-u 42 M-x eshell RET) cambia a la sesión con ese número, creándolo si es necesario. Un prefijo no numérico arg significa crear una nueva sesión.
Matt Curtis
34

Puede cambiar el nombre del búfer de su shell con M-x rename-buffer. Entonces podrás lanzar un segundo shell.

Giann
fuente
2
Prefiero ir con la solución de Matt Curtis. Ejecutar un shell con un nuevo nombre me parece más fácil que renombrar el actual y luego ejecutar uno nuevo.
S4M
8

Mire MultiTerm , hace que la administración de múltiples terminales en Emacs sea mucho más fácil.

Victor Deryagin
fuente
1
Tenga en cuenta que el modo shell y el modo término son dos cosas completamente diferentes.
darkfeline
5

También podría ser útil usar una interfaz similar a una pantalla para sus shells. He escrito el mío, pero hay otros por ahí, como EmacsScreen .

Trey Jackson
fuente
5

Después de más de cuatro años, veo que algunas personas todavía están viendo este problema a veces, por lo que publicaré una función rápida que escribí para cargar un shell y pedir su nombre. De esa manera, puede nombrar un shell "ordenar-archivos" si está dedicado a ordenar archivos y otro "colmena" si está dedicado a ejecutar consultas de colmena. Lo uso todos los días ahora (en 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
fuente
4

Esto generará automáticamente una nueva instancia de shell en cualquier búfer que esté utilizando; vincúlelo a MS o algo así y alegría 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)
  )
)

Muchas gracias a phils por recomendar una reescritura usando let, a pesar de que el resultado es un paréntesis aún más horrible ...: \

bjsdaiyu
fuente
1
Necesita letvincular variables si están destinadas para uso local. Tal como está ahora tiene valores globales para currentbufy newbuf.
phils
¿Cómo se compara la función new-shell con mi función create-shell?
S4M
1
@ S4M es principalmente una cuestión de preferencia, soy vago y quiero mi shell de inmediato, en la ventana actualmente activa y sin tener que escribir un nombre de búfer por adelantado.
bjsdaiyu
@phils gracias por el consejo, no estoy familiarizado con lisp, por lo que volveré a trabajarlo con la asignación local. :-)
bjsdaiyu
hmm, creo que puedes tomar mi función y agregar un nombre predeterminado que sería algo así como shell_n , donde n sería el enésimo shell abierto, mientras que Cu create-shell solicitaría un nombre para el shell.
S4M
0

Esto abrirá un nuevo shell cada vez que invoque la función y cambie el nombre automáticamente si es necesario. La ventaja adicional es que si está editando archivos de forma remota (dired / tramp ...), esto abrirá un shell en el host remoto y le cambiará el nombre automáticamente con el nombre de 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
fuente