I have a Cmd console set up to auto-complete card names for a Magic: the Gathering collection management system.
It uses the text parameter to query the database for cards, and uses the results to auto-complete/suggest cards.
However, these cards names have multiple words, and Cmd runs auto-completion from the last space to the end of the line.
For example:
mtgdb> add Mage<tab><tab>
Mage Slayer (Alara Reborn) Magefire Wings (Alara Reborn)
mtgdb> add Mage S<tab><tab>
Sages of the Anima (Alara Reborn)
Sanctum Plowbeast (Alara Reborn)
Sangrite Backlash (Alara Reborn)
Sanity Gnawers (Alara Reborn)
Sen Triplets (Alara Reborn)
[...]
mtgdb> add Mage Sl<tab>
mtgdb> add Mage Slave of Bolas (Alara Reborn)
I tried manually grabbing what I wanted from the line
parameter, which gets the results I want from the database, but this fails to overwrite the first word:
mtgdb> add Mage Sl<tab>
mtgdb> add Mage Mage Slayer (Alara Reborn)
In the end, I need the auto-completer to work like this:
mtgdb> add Mage Sl<tab>
mtgdb> add Mage Slayer (Alara Reborn)
Aside from the manual parsing attempt above, I also tried replacing spaces with plus signs, and discovered that Cmd is perfectly happy splitting on those as well. Replacing spaces with underscores works, but there is one card in Unhinged which is named _____
, so I have to go through acrobatics to demunge the strings since I can't just line.replace("_", " ")
.
Here's some runnable test code:
import cmd
commands = [
"foo",
"foo bar blah",
"bar",
"bar baz blah",
"baz",
"baz foo blah"]
class Console(cmd.Cmd):
intro = "Test console for" + \
"http://stackoverflow.com/questions/4001708/\n" + \
"Type \"cmd<space><tab><tab>\" to test " + \
"auto-completion with spaces in commands\nwith " + \
"similar beginings."
def do_cmd(self, line):
print(line)
def complete_cmd(self, text, line, start_index, end_index):
if text:
return [command for command in commands
if command.startswith(text)]
else:
return commands
if __name__ == "__main__":
command = Console()
command.cmdloop()
It shouldn't need to be overly complicated. Something like the following:
import cmd
completions = [
'Mage Slayer (Alara Reborn)',
'Magefire Wings (Alara Reborn)',
'Sages of the Anima (Alara Reborn)',
'Sanctum Plowbeast (Alara Reborn)',
'Sangrite Backlash (Alara Reborn)',
'Sanity Gnawers (Alara Reborn)',
'Sen Triplets (Alara Reborn)'
]
class mycmd(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
def do_quit(self, s):
return True
def do_add(self, s):
pass
def complete_add(self, text, line, begidx, endidx):
mline = line.partition(' ')[2]
offs = len(mline) - len(text)
return [s[offs:] for s in completions if s.startswith(mline)]
if __name__ == '__main__':
mycmd().cmdloop()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With