3

最近我一直在研究 vim 插件开发,我发现我错过了使用 Python REPL(例如 ipython/bpython)来检查 vim 模块和环境(当前打开的文档、行号、选择等)的能力.

原则上,这不是很先进,而且我从其他嵌入 Python 的应用程序中完成了一些事情......

通常你可以这样做:

import code
code.interact(local=locals())

或者使用 IPython:

import IPython
IPython.embed()

然而,当 vim 嵌入 Python 时,它替换了sys.stdin/stdout/stderr,我设法临时恢复了这些,它几乎可以工作,但仍然存在一些问题,包括乱码行尾和 stdin 无法正确读取。

例如,

std_back = sys.stderr, sys.stdin, sys.stdout
sys.stderr = sys.__stderr__
sys.stdout = sys.__stdout__
sys.stdin = sys.__stdin__

import IPython
IPython.embed()

sys.stderr, sys.stdin, sys.stdout = std_back

我在 linux 上尝试了 vim 和 gvim,但 stdin/stdout 无法正常工作。(很难解释,但只接受每秒一次的键输入,并且不打印换行符,文本换行)。

所以我最后的尝试是使用idle,它绕过终端并用命令行打开一个tk界面。

import idlelib
import idlelib.PyShell
idlelib.PyShell.main()

这会加载控制台,但在一个子进程中,因此无法访问vim模块,我检查了 idlelib 源代码,发现您可以通过伪造一个命令行参数来禁用子进程的使用,该命令行参数通常从命令行启动时会访问空闲直接地。

import sys
sys.argv.append("-n")

import idlelib
import idlelib.PyShell
idlelib.PyShell.main()

好的,所以这可行,但是,Python 开发人员将删除 idlelib 的选项以在进程内运行(目前已弃用)。是否有其他开发人员知道在 vim 中使用 Python REPL 的方法,从pyfile/调用py3file

4

1 回答 1

2

这是一个侦听网络套接字的简单解释器外壳:

import socket
import sys
import code
from threading import Thread


def remote_shell(local, host='localhost', port=5555):
    serv = socket.socket()
    serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    serv.bind((host, port))
    serv.listen(1)
    streams = sys.stdout, sys.stderr
    print('listening on %s:%d' % (host, port))
    try:
        sock, addr = serv.accept()
        f = sock.makefile('rw')
        sys.stdout = sys.stderr = f

        def read(prompt):
                f.write(prompt)
                f.flush()
                return f.readline().rstrip('\n')

        code.interact(readfunc=read, local=local)
    finally:
        sys.stdout, sys.stderr = streams
        serv.close()
        sock.close()


if __name__ == '__main__':
    remote_shell(local=locals())
    # or if it should run in background:
    # Thread(target=remote_shell, kwargs={'local': locals()}).start()

要连接,只需使用:nc localhost 5555- 但对于高级使用它可能过于受限。使用至少像这样的工具rlwrap可以拥有历史记录,但更高级的 readline 功能(如制表符完成)将不起作用。但至少它是一些东西......

于 2013-07-13T03:01:24.550 回答