简体   繁体   English

Python 2.7 cmd自动完成读取行缓冲区似乎过时

[英]Python 2.7 cmd autocomplete readline buffers seem stale

I'm using readline based cmd module on Mac OS (and Red Hat Linux) with tab completion enabled. 我在启用了制表符补全的Mac OS(和Red Hat Linux)上使用基于readline的cmd模块。 It seems to be working great except for when I introduced my own logic to handle "sub command" completions based on regex matching. 除了我引入了自己的逻辑来处理基于正则表达式匹配的“子命令”完成时,它似乎工作得很好。 here is a simple address book example where I have a tree based structure: 这是一个简单的通讯录示例,其中有一个基于树的结构:

Code: 码:

import cmd
import readline
import re

readline.parse_and_bind("bind ^I rl_complete")

class Test(cmd.Cmd):
    def do_assign(self, line):
        print line
    def complete_assign(self, text, line, begidx, endidx):
        if re.match('assign\s+employee\s+name', line):
            return [i for i in ['first', 'middle', 'last']
                if i.startswith(text)]
        elif re.match('assign\s+employee', line):
            return [i for i in ['name', 'address', 'phone']
                if i.startswith(text)]
        elif line.startswith("assign"):
            return [i for i in ['employee', 'manager']
                if i.startswith(text)]

Test().cmdloop()

Output: 输出:

(Cmd) assign <TAB>
employee  manager   

(Cmd) assign employee <TAB>
address  phone    name 

(Cmd) assign employee name <TAB>
last    middle  first   

(Cmd) assign employee name first <RETURN>
employee name first

(Cmd) assign <TAB> <-- This is incorrect. Expecting ['employee', 'manager'] instead
last    middle  first  

(Cmd) assign

As you see the difference between first and last "assign " operations, I'm getting different results because the line variable in function complete_assign seems to get assigned assign employee name first instead of just assign because of the previous RETURN operation, due to which the completor logic is now matching the wrong regex code block and providing the incorrect completions. 正如你看到的第一个和最后的区别“分配”操作,我得到不同的结果,因为该line的函数变量complete_assign似乎得到分配的assign employee name first ,而不仅仅是assign ,因为以前返回操作的,由于其补全逻辑现在匹配错误的正则表达式代码块并提供不正确的补全。 Is there a way to "flush" the readline stdin buffer after every operation so that it doesn't remember the buffer from previous complete_assign or do_assign trials? 有没有一种方法可以在每次操作后“刷新” readline stdin缓冲区,以使它不记得以前的complete_assigndo_assign试验中的缓冲区?

Thanks! 谢谢!

I think I solved it, thanks to this article: http://pymotw.com/2/readline/#accessing-the-completion-buffer 多亏了这篇文章,我想我解决了它: http : //pymotw.com/2/readline/#accessing-the-completion-buffer

While going through the BufferAwareCompleter code, I stumbled across this line: 在浏览BufferAwareCompleter代码时,我偶然发现了这一行:

being_completed = origline[begin:end]

Which made me think that I should be able to use the line indices provided in the completer API to my advantage, and this is exactly what helped. 这使我认为我应该能够利用completer API中提供的行索引来发挥自己的优势,而这正是有帮助的。

Since I did not care about the 'stale' part of the buffer, I just used end index to demarcate my line boundary. 由于我不在乎缓冲区的“过时”部分,因此我只使用了结束索引来划分行边界。 This did the trick: 这达到了目的:

line = line[:endidx]

Updated working code: 更新的工作代码:

import cmd
import readline
import re

readline.parse_and_bind("bind ^I rl_complete")

class Test(cmd.Cmd):
    def do_assign(self, line):
        print line
    def complete_assign(self, text, line, begidx, endidx):
        line = line[:endidx] # <-- ADDED THIS
        if re.match('assign\s+employee\s+name', line):
            return [i for i in ['first', 'middle', 'last']
                if i.startswith(text)]
        elif re.match('assign\s+employee', line):
            return [i for i in ['name', 'address', 'phone']
                if i.startswith(text)]
        elif line.startswith("assign"):
            return [i for i in ['employee', 'manager']
                if i.startswith(text)]

Test().cmdloop()

Update working output: 更新工作输出:

(Cmd) assign 
employee  manager   
(Cmd) assign employee 
name     phone    address  
(Cmd) assign employee name 
last    middle  first   
(Cmd) assign employee name first
employee name first
(Cmd) assign 
manager   employee  
(Cmd) assign 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM