从python脚本中调用EDITOR(vim)

sam*_*sam 42 python vim editor command-line-interface

我想在python脚本中调用一个编辑器来征求用户的意见,就像crontab e或者git commit一样.

这是我到目前为止运行的片段.(将来,我可能会使用$ EDITOR而不是vim,以便人们可以根据自己的喜好进行自定义.)

tmp_file = '/tmp/up.'+''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(6))
edit_call = [ "vim",tmp_file]
edit = subprocess.Popen(edit_call,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True )   
Run Code Online (Sandbox Code Playgroud)

我的问题是,通过使用Popen,它似乎让我的i/o与python脚本进入vim的运行副本,我找不到一种方法来将i/o传递给vim.我收到以下错误.

Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
Run Code Online (Sandbox Code Playgroud)

什么是从python调用CLI程序,手动控制到它的最佳方法,然后在完成后将其传回去?

unp*_*680 70

打电话给$ EDITOR很容易.我已经编写了这种代码来调用编辑器:

import sys, tempfile, os
from subprocess import call

EDITOR = os.environ.get('EDITOR','vim') #that easy!

initial_message = "" # if you want to set up the file somehow

with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
  tf.write(initial_message)
  tf.flush()
  call([EDITOR, tf.name])

  # do the parsing with `tf` using regular File operations.
  # for instance:
  tf.seek(0)
  edited_message = tf.read()
Run Code Online (Sandbox Code Playgroud)

这里的好处是,库处理创建和删除临时文件.

  • 我不得不用`with open(tf.name)`重新打开文件来获取更新的文件内容.否则,我只是获得与`initial_message`相同的内容 (9认同)
  • 我遇到了同样的问题,即回读文件的旧内容,并且确实在很多情况下,vim将旧文件移到一边并写入新文件,使我们的tf文件描述符仍然在现在备份文件上打开.在文件名之前添加命令行选项"+ set backupcopy = yes"可以防止出现此问题,现在我很高兴能够读取该文件的新内容.call([EDITOR,'+ set backupcopy = yes',tf.name]) (5认同)

mod*_*e13 6

在python3中: 'str' does not support the buffer interface

$ python3 editor.py
Traceback (most recent call last):
  File "editor.py", line 9, in <module>
    tf.write(initial_message)
  File "/usr/lib/python3.4/tempfile.py", line 399, in func_wrapper
    return func(*args, **kwargs)
TypeError: 'str' does not support the buffer interface
Run Code Online (Sandbox Code Playgroud)

对于python3,用于initial_message = b""声明缓冲的字符串.

然后使用edited_message.decode("utf-8")将缓冲区解码为字符串.

import sys, tempfile, os
from subprocess import call

EDITOR = os.environ.get('EDITOR','vim') #that easy!

initial_message = b"" # if you want to set up the file somehow

with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
    tf.write(initial_message)
    tf.flush()
    call([EDITOR, tf.name])

    # do the parsing with `tf` using regular File operations.
    # for instance:
    tf.seek(0)
    edited_message = tf.read()
    print (edited_message.decode("utf-8"))
Run Code Online (Sandbox Code Playgroud)

结果:

$ python3 editor.py
look a string
Run Code Online (Sandbox Code Playgroud)


Mat*_*tin 5

python-editor:

$ pip install python-editor
$ python
>>> import editor
>>> result = editor.edit(contents="text to put in editor\n")
Run Code Online (Sandbox Code Playgroud)

更多细节在这里:https : //github.com/fmoo/python-editor