从Python缓冲区发送代码到从M-x ansi-term运行的IPython会话

3

假设我在Emacs中用M-x ansi-term打开一个终端模拟器。这会在Emacs中打开一个带有我选择的shell的缓冲区。假设我从这个shell运行ipython。我是否可以从另一个包含Python代码的Emacs缓冲区发送代码到这个ipython会话?如果可以,如何操作?

3个回答

5
我有一个用于此目的的小模式(除了它不是特定于IPython的,我主要用它来运行shell脚本):isend-mode
以下是使用方法:
1. 打开一个ansi-term缓冲区:

M-xansi-termRET/usr/bin/ipythonRET

2. 打开包含要执行代码的缓冲区,并将其关联到解释器缓冲区:

M-xisend-associateRET*ansi-term*RET

3. 在python缓冲区中按下C-RET,将当前行发送到ansi-term缓冲区中的解释器。

这太棒了,Francesco。它只支持发送当前行吗?(即与发送区域或完整缓冲区相反)。 - Amelio Vazquez-Reina
1
如果区域处于活动状态,则发送该区域而不是发送当前行(实际上,它将发送由该区域跨越的所有行,即没有任何一行仅部分发送)。要发送整个缓冲区,我使用 C-x h C-RET(但我很少使用此功能,因为我的主要用途是逐行或逐部分解释脚本)。 - François Févotte
感谢@Francesco,我注意到的唯一问题是isend不能很好地处理其中有缩进的代码块的代码片段。例如,如果我选择具有if块或带有其他未缩进代码的for循环的代码,则isend将不会按照IPython期望的方式发送缩进。在IPython中调用%paste,将所选代码发送到shell是否更好?(即,您将使isend将代码复制到Emacs剪贴板,然后在IPython缓冲区中调用%paste)。这将允许isend处理任意复杂的代码片段。 - Amelio Vazquez-Reina
1
我认为你的问题与交互式IPython解释器期望在循环或其他缩进结构的末尾有空行有关。默认情况下,isend会忽略这样的行,但我已经上传了一个新版本,可以使用(setq isend-skip-empty-lines nil)告诉它发送空行。 - François Févotte
1
谢谢,Francesco。我尝试了新版本,但问题仍然存在。原因是在Python(和IPython)中缩进具有意义,所以如果我选择来自循环内部的代码,IPython会抱怨unexpected indent,因为代码已经缩进了。解决isend问题的唯一方法是在将代码块发送到缓冲区之前从代码块中删除任何额外的缩进(但保持行之间的相对缩进)。我认为这将是一个优雅的解决方案,并且它应该也适用于其他shell(其他shell对缩进不挑剔)。 - Amelio Vazquez-Reina
显示剩余3条评论

3
(defun send-buffer-to-ipython ()
  "Send current buffer to the running ipython process."
  (interactive)
  (let* ((ipython-buffer "*ansi-term*") ; the buffer name of your running terminal
         (proc (get-buffer-process ipython-buffer)))
    (unless proc
      (error "no process found"))
    (save-buffer)
    (process-send-string proc
                         (format "execfile(\"%s\")\n" (buffer-file-name)))
    (pop-to-buffer ipython-buffer)      ; show ipython and select it
    ;; (display-buffer ipython-buffer)  ; show ipython but don't select it
    ))

然后将命令send-buffer-to-ipython绑定到您喜欢的任何键。我将其绑定到C-c C-c

(define-key python-mode-map [?\C-c ?\C-c] 'send-buffer-to-ipython)

当文本较大时,我认为发送一个命令来加载和执行当前文件是更好的选择。这也是python.el实现的方式,除了在python.el中,python-send-region会将当前缓冲区的内容保存到临时文件中,并发送命令以加载临时文件。 - Tao Peng

2

谢谢Andreas。你说的“Caveat: a shebang precedes default py-shell-name”是什么意思?你的意思是,如果我在要发送代码的脚本中有一个shebang,则shebang会优先于我的“py-shell-name”的值吗? - Amelio Vazquez-Reina
AFAIS在ansi-term中执行只有在没有设置shebang时才有效 - 这是一个错误。 - Andreas Röhler
Andreas,如果我有多个 ansi_term 缓冲区,我该如何设置?我可以将运行 IPython 的 Emacs 缓冲区重命名为其他名称,并将其作为参数传递给 py-shell-name 吗?或者我们应该如何处理多个 ansi-term? - Amelio Vazquez-Reina

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接