【问题标题】:How to run multiple shells on Emacs如何在 Emacs 上运行多个 shell
【发布时间】:2023-03-31 18:25:02
【问题描述】:

我在 Windows 7 上使用 Emacs 23.3.1。我知道我可以使用 M-x shell 从 emacs 运行 shell。我想同时拥有多个 shell 窗口,但第二次键入 M-x shell 只会打开同一个 shell 窗口。

有没有办法拥有不同的 shell 窗口?

【问题讨论】:

    标签: emacs


    【解决方案1】:

    C-u M-x shell 会做到的。

    它将提示输入新 shell 的名称,只需按回车键即可(类似于 *shell*<2>

    也适用于 eshell。

    另一个技巧,如果你使用 eshell:就像 Mx eshell 带你回到*eshell*(而不是开始一个新的 eshell),如果你使用一个数字前缀参数,它会带你到那个eshell缓冲区。例如,C-3M-xeshell 会将您带到*eshell*<3>。遗憾的是,如果您使用 shell(而不是 eshell),这个技巧似乎不起作用(至少在我的 Emacs 24.0.50.1 中。)

    【讨论】:

    • 好的,这个有效。 C-u M-x shell 询问我新 shell 的名称。谢谢!
    • 没有问题 S4M。我添加了一个关于 eshell 的提示;当您询问 shell 时,我不知道您是否会发现它有用,但有相同问题的 eshell 用户可能会发现它很有用。
    • 谢谢,马特。 C-u 在这里是什么意思/做什么?
    • C-u 运行命令universal-argument。这是一种将参数注入下一个命令的方法。您可以通过 C-h k C-u 了解更多信息(C-h k 运行 describe-key,非常方便!)
    • 我一直用这个。我有一个烦恼,尽管我最终在 Ibuffer 中有一行写着 *shell*<2> 3038 Shell (shell<1> run) ~/ 并且当您尝试退出时,emacs 将 shell 称为 shell,即使名称是 shell。当然,我可以编辑建议的默认名称参数,但我不这样做。
    【解决方案2】:

    您可以使用 M-x rename-buffer 重命名 shell 的缓冲区。然后您将能够启动第二个 shell。

    【讨论】:

    • 我更喜欢使用 Matt Curtis 的解决方案。在我看来,以新名称运行 shell 比重命名当前 shell 然后运行新名称更容易。
    【解决方案3】:

    看看MultiTerm,它让在 Emacs 中管理多个终端变得更加容易。

    【讨论】:

    • 请注意,shell 模式和 term 模式是两个完全不同的东西。
    【解决方案4】:

    四年多后,我看到有些人有时还在关注这个问题,所以我将发布一个我写的快速函数来加载一个shell并询问它的名称。这样,如果一个 shell 专门用于对文件进行排序,您可以将其命名为“sort-files”,如果它专门用于运行 hive 查询,则可以将其命名为“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 "*"))))
    

    【讨论】:

      【解决方案5】:

      在您的 shell 中使用类似屏幕的界面也可能很有用。我自己写了,但也有其他的,比如EmacsScreen

      【讨论】:

        【解决方案6】:

        这将在您碰巧使用的任何缓冲区中自动生成一个新的 shell 实例;将它绑定到 M-S 或类似的东西上并立即获得快乐:

        (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 重写,即使结果是更糟糕的括号...:\

        【讨论】:

        • 如果变量是供本地使用的,您需要 let-bind 变量。现在,您现在拥有currentbufnewbuf 的全局值。
        • new-shell 函数与我的 create-shell 函数相比如何?
        • @S4M 这主要是一个偏好问题,我很懒,想立即在当前活动窗口中使用我的 shell,而无需预先输入缓冲区名。
        • @phils 感谢您的提示,我对 lisp 一点也不熟悉,因此将使用本地分配对其进行重做。:-)
        • hmm,我想你可以使用我的函数并添加一个类似于 shell_n 的默认名称,其中 n 是打开的第 n 个 shell,而 Cu 创建-shell 将提示 shell 的名称。
        【解决方案7】:

        这将在您每次调用该函数时打开一个新的 shell,并在需要时自动重命名它。 额外的好处是,如果您正在远程编辑文件(dired/tramp...),这将在远程主机上打开一个 shell 并使用远程主机名自动重命名:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多