正在学习 Python,在 Org mode 实验代码块,发现不能处理 input
#+begin_src python :session
input("> ")
#+end_src
这本身可以理解,但是有没有人试过另一个执行思路:
- 切换到
*Python*
Buffer
- 执行代码,并且等待执行完成
- 返回 Org mode 的 Buffer,插入结果
感觉值得一试,不过我目前没时间尝试。不知道大家有考虑过没?
Emacs SE 上有同样的问题,但它们都拘泥于现有的 Babel 框架,没有我想要的方法。
1 个赞
interactive test 应當是用 REPL 做的工作。
嗯,我之所以有这个想法,就是因为 *Python*
(Inferior Python mode)已经支持了 input
,Org 执行代码的时候直接利用它就好了。
觉得你可以尝试给 ob-python.el
添加这个功能。
以前讨论过类似的问题:怎样让 output buffer 接受输入?
这样间接实现用户输入是有点繁琐。不过从另一个角度看,用户输入也是相当重要的信息,明确写在文档里,对于过一段时间再来回顾/重现当时的情形还是有用的。
对,ob-shell更需要交互。也许可以写一个
#+begin_src shell :var name=(read-minibuffer "Name: ")
echo $name
#+end_src
#+RESULTS[<2018-04-06 10:08:10> 27a280ff89c19cf5c6685796570366c04a13cbd5]:
: ni
我的意思大概是这样:
(defun foo ()
(interactive)
(let ((code (plist-get (cadr (org-element-at-point)) :value)))
(switch-to-buffer-other-window "*shell*")
(goto-char (point-max))
(insert code)
(recursive-edit)
(message "Update Org Mode Buffer")))
要是有可能的话,还可以用外部终端(如 Terminal.app)运行代码。
这种方式通常获取结果很困难,除非终端eval函数支持返回结果。继承自comint-mode的REPL也不知道是否支持这种操作。
用 Org Mode 代码块练习书上的代码,Tangle 繁琐且不必要,暂且就这么解决,很简单的代码就已经实现了我的大部分需求。
(defun chunyang-org-babel-execute-python-in-iTerm ()
(interactive)
(seq-let (type plist) (org-element-at-point)
(cond ((not (eq 'src-block type))
(user-error "Not a src block"))
((not (string= "python" (plist-get plist :language)))
(user-error "Not a Python src block"))
(t
(let ((filename (make-temp-file "" nil ".py")))
(org-babel-tangle '(4) filename)
(chunyang-mac-iTerm-send-string (concat "python " filename)))))))
看个人习惯。
我更偏向静默的方式使用代码块,把输入参数尽量落到文档上。
如果需要处理 stdin,我希望是这样的:
#+BEGIN_SRC python :results value :preamble "# -*- coding: utf-8 -*-"
foo = input("> ") # <<< 1
bar = input("> ") # <<< 1
assert foo == bar
foo = input("> ") # <<< 1
bar = input("> ") # <<< 2
assert foo != bar
#+END_SRC
代码发送到解释器之前替换成:
foo = 1
bar = 1
assert foo == bar
foo = 1
bar = 2
assert foo != bar
而原始代码放到 .py 文件中执行仍然可以跟用户交互。
fontux
12
请教这步具体该怎么做呢?这个应该和 Org-mode 没有很大的关系,假设进程一直处于运行状态,process-send-string
多个语句时(不一定要有输入,也可以是比较耗时的语句),怎么判断语句都执行完毕并获得结果?
我初步想到了两种方法:Process Filter Functions 和 REPL buffer 中的 after-change-functions
,但是感觉都不太好?前者有点理解不透,有没有更具体一点的例子可以参考一下?后者有时会返回不全。还有无其它可用的方法?