Comment exécuter plusieurs shells sur Emacs

147

J'utilise Emacs 23.3.1 sur Windows 7. Je sais que je peux exécuter shell à partir d'emacs en utilisant Mx shell. Je voudrais avoir plusieurs fenêtres shell en même temps, mais taper Mx shell une deuxième fois m'ouvre juste la même fenêtre shell.

Existe-t-il un moyen d'avoir différentes fenêtres shell?

S4M
la source

Réponses:

210

C-u M-x shell le fera.

Il vous demandera un nom pour le nouveau shell, appuyez simplement sur retour pour la valeur par défaut (qui sera quelque chose comme *shell*<2> .

Fonctionne également avec eshell.

Une autre astuce, si vous utilisez eshell: tout comme M-x eshellvous ramène à *eshell*(plutôt que de démarrer un nouveau eshell), si vous utilisez un argument de préfixe numérique, cela vous mènera à ce tampon eshell. Par exemple, vous C-3M-xeshellamènera à *eshell*<3>. Malheureusement, si vous utilisez shell (plutôt que eshell), cette astuce ne semble pas fonctionner (au moins dans mon Emacs 24.0.50.1).

Matt Curtis
la source
1
OK, celui-ci fonctionne. La coque Cu Mx me demande le nom de la nouvelle coque. Merci!
S4M
1
Aucun problème S4M. J'ai ajouté une astuce pour eshell; comme vous l'avez demandé à propos du shell, je ne sais pas si vous le trouverez utile, mais les utilisateurs d'eshell avec la même question pourraient le trouver utile.
Matt Curtis
Merci, Matt. Que signifie / fait Cu ici?
Tim
4
C-uexécute la commande universal-argument. C'est une manière d'injecter un argument dans la commande suivante. Vous pouvez en savoir plus à ce sujet avec C-h k C-u( C-h kcourses describe-key, très pratique!)
Matt Curtis
Puis C-h f eshell( C-h fs'exécute describe-function) montre que la fonction eshellprend un argument optionnel. Quote: Un préfixe numérique arg (comme dans C-u 42 M-x eshell RET) bascule vers la session avec ce numéro, le créant si nécessaire. Un préfixe non numérique arg signifie créer une nouvelle session.
Matt Curtis
34

Vous pouvez renommer le tampon de votre shell avec M-x rename-buffer. Ensuite, vous pourrez lancer un deuxième shell.

Giann
la source
2
Je préfère aller avec la solution de Matt Curtis. Exécuter un shell sous un nouveau nom me semble plus facile que de renommer le shell actuel et d'en exécuter un nouveau.
S4M
8

Regardez MultiTerm , il facilite la gestion de plusieurs terminaux dans Emacs.

Victor Deryagin
la source
1
Notez que le mode shell et le mode term sont deux choses complètement différentes.
darkfeline
5

Il peut également être utile d'utiliser une interface de type écran avec vos shells. J'ai écrit le mien, mais il y en a d'autres, comme EmacsScreen .

Trey Jackson
la source
5

Après plus de quatre ans, je vois que certaines personnes se penchent encore sur ce problème parfois, donc je publierai une fonction rapide que j'ai écrite pour charger un shell et demander son nom. De cette façon, vous pouvez nommer un shell "sort-files" s'il est dédié au tri des fichiers et un autre "ruche" s'il est dédié à l'exécution de requêtes Hive. Je l'utilise tous les jours maintenant (sur 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
la source
4

Cela générera automatiquement une nouvelle instance de shell dans le tampon que vous utilisez; liez-le à MS ou à quelque chose comme ça et à la joie instantanée:

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

Un grand merci à phils pour avoir recommandé une réécriture en utilisant let, même si le résultat est encore plus horrible entre parenthèses ...: \

bjsdaiyu
la source
1
Vous devez letlier des variables si elles sont destinées à un usage local. Dans l'état actuel des choses, vous avez maintenant des valeurs globales pour currentbufet newbuf.
phils
comment la fonction new-shell se compare-t-elle à ma fonction create-shell?
S4M
1
@ S4M c'est principalement une question de préférence, je suis paresseux et je veux mon shell immédiatement, dans la fenêtre actuellement active et sans avoir à taper un nom de tampon à l'avant.
bjsdaiyu
@phils merci pour le tuyau, je ne suis pas du tout familier avec lisp, je vais donc le retravailler en utilisant une affectation locale. :-)
bjsdaiyu
hmm, je pense que vous pouvez prendre ma fonction et ajouter un nom par défaut qui serait quelque chose comme shell_n , où n serait le n-ième shell ouvert, tandis que Cu create-shell demanderait un nom pour le shell.
S4M
0

Cela ouvrira un nouveau shell chaque fois que vous invoquerez la fonction et la renommez automatiquement si nécessaire. L'avantage supplémentaire est que si vous éditez des fichiers à distance (dired / tramp ...), cela ouvrira un shell sur l'hôte distant et le renommera automatiquement avec le nom d'hôte distant:

(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
la source