围绕readline构建的python批处理的触发器选项卡完成 [英] trigger tab completion for python batch process built around readline

查看:73
本文介绍了围绕readline构建的python批处理的触发器选项卡完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:我有一个python程序,该程序可以导入并使用readline模块来构建自制的命令行界面。我有第二个python程序(围绕bottle和Web微框架构建),充当该CLI的前端。第二个python程序打开到第一个的类似管道的界面,实质上是在两者之间来回传递用户输入和CLI输出。

Background: I have a python program that imports and uses the readline module to build a homemade command line interface. I have a second python program (built around bottle, a web micro-framework) that acts as a front-end for that CLI. The second python program opens a pipe-like interface to the first, essentially passing user input and CLI output back and forth between the two.

问题:在外部包装程序(Web界面)中,无论最终用户何时按下TAB键(或我绑定readline completer函数的任何其他键),该键都将插入CLI的stdin 中,而无需启用readline完成函数。我需要它来触发readline的命令完成功能,这通常是在交互式CLI会话期间发生的。

Problem: In the outer wrapper program (the web interface), whenever the end-user presses the TAB key (or any other key that I bind the readline completer function), that key is inserted into the CLI's stdin without firing the readline completer function. I need this to trigger readline's command completion function instead, as normally occurs during an interactive CLI session.

可能的解决方案1:将TAB密钥发送到子进程的stdin的方法,以便批处理用法与交互式用法相同?

Possible Solution #1: Is there some way to send the TAB key to a subprocess' stdin, so that a batch usage works the same as an interactive usage?

可能的解决方案2:或者,如果有某种方法可以手动触发整个完成过程(包括匹配生成显示),我可以插入并扫描特殊的文本序列,例如< TAB_KEY_HERE> ,手动触发可能的完成匹配 display 功能。 (我编写了completer函数,该函数生成可能的匹配项,因此我真正需要的就是访问readline的函数以显示可能的匹配项。)

Possible Solution #2: Or, if there was some way to trigger the entire completion process manually (including matches generation and display), I could insert and scan for a special text sequence, like "<TAB_KEY_HERE>", firing the possible completion matches display function manually. (I wrote the completer function, which generates the possible matches, so all I really need is access to readline's function to display the possible matches.)

可能的解决方案#3:我想,如果我无法访问readline的matchs-display函数,最后一个选择是重写readline的内置显示完成功能,因此我可以直接调用它。 :(

Possible Solution #3: I guess, if I cannot access readline's matches-display function, the last option is to rewrite readline's built-in display-completion function, so I can call it directly. :(

有更好的解决方案吗?关于遵循上述任何一种解决方案提出的建议吗?我被困在#1和#2上,我m尝试避免#3。

Is there a better solution? Any suggestions on following the paths presented by any of the above solutions? I am stuck on #1 and #2, and I'm trying to avoid #3.

谢谢!

推荐答案

解决方案#1 被证明是可行的方法,关键是直接将Web套接字连接到CLI应用程序,显然,readline退回到了一些更简单的模式,过滤掉了所有TAB,因为它没有连接到真正的PTY / TTY(我可能记不太清了。已经形成了许多蜘蛛网。)相反,需要打开一个PTY / TTY对,并将其插入CLI之间。 app和web-sockets应用程序,欺骗了CLI应用程序,使其认为它已连接到基于键盘的真实终端,例如:

Solution #1 proved to be a workable approach. The key was to not connect the web socket directly to the CLI app. Apparently, readline was falling back into some simpler mode, which filtered out all TAB's, since it was not connected to a real PTY/TTY. (I may not be remembering this exactly right. Many cobwebs have formed.) Instead, a PTY/TTY pair needed to be opened and inserted in between the CLI app and web-sockets app, which tricked the CLI app into thinking it was connected to a real keyboard-based terminal, like so:

import pty
masterPTY, slaveTTY = pty.openpty()
appHandle = subprocess.Popen(
    ['/bin/python', 'myapp.py'],
    shell=False,
    stdin=slaveTTY,
    stdout=slaveTTY,
    stderr=slaveTTY,
    )
...
while True
    # read output from CLI app
    output = os.read(masterPTY, 1024)
    ...
    # write output to CLI app
    while input_data:
        chars_written = os.write(masterPTY, input_data)
        input_data = input_data[chars_written:]
    ...
appHandle.terminate()
os.close(masterPTY)
os.close(slaveTTY)

还有其他人。 :)

有关更多背景的信息,请参见以下答案:

See this answer to a related question for more background:

https://stackoverflow.com/a/14565848/538418

这篇关于围绕readline构建的python批处理的触发器选项卡完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆