我正在尝试实现 raw_input() 的替换,它将使用像 vim 这样的可配置文本编辑器作为用户界面。
理想的工作流程是这样的:
- 您的 python 脚本正在运行,并调用 my_raw_input()。
- Vim(或 emacs、gedit 或任何其他文本编辑器)打开时显示空白文档
- 您在文档中键入一些文本,然后保存并退出
- python 脚本继续运行,文件的内容作为 my_raw_input() 的返回值。
如果你熟悉 git,这就是使用时的体验git commit
,编辑器是通过core.editor配置的。其他实用程序crontab -e
也这样做。
最终,我希望这个 my_raw_input() 函数也采用带有默认输入内容的可选字符串,然后用户可以对其进行编辑。
研究至今
- os.exec用编辑器命令替换当前进程,但不返回。即,当 vim 启动时,您的 python 脚本会退出。
- popen不以交互方式启动子进程,没有显示用户界面。
- vim 有一个
-
命令行参数可以从标准输入读取,但没有任何东西可以用:w
. - 我查看了git 的代码,我根本无法理解。
这可能吗?
编辑
到目前为止很好的答案。我还发现了做同样事情的mecurial 代码。我还提出了一个通过查看crontab 代码的示例,但与某些响应相比,它看起来不必要地复杂。
#!/usr/bin/python
import os
import tempfile
def raw_input_editor(default=None, editor=None):
''' like the built-in raw_input(), except that it uses a visual
text editor for ease of editing. Unline raw_input() it can also
take a default value. '''
editor = editor or get_editor()
with tempfile.NamedTemporaryFile(mode='r+') as tmpfile:
if default:
tmpfile.write(default)
tmpfile.flush()
child_pid = os.fork()
is_child = child_pid == 0
if is_child:
os.execvp(editor, [editor, tmpfile.name])
else:
os.waitpid(child_pid, 0)
tmpfile.seek(0)
return tmpfile.read().strip()
def get_editor():
return (os.environ.get('VISUAL')
or os.environ.get('EDITOR')
or 'vi')
if __name__ == "__main__":
print raw_input_editor('this is a test')