Python Forum

Full Version: Cmd Module + raw_input tab [complete
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello Everyone!

I am new here, and fairly new to python, and I must say I've been missing out for so long.

System: Python 2.7, Cmd Module, OSX.

Issue:

I am using the Cmd module to create a little helper script @ work.  It is a CLI Application that works with a REST API.

I have a simple interactive shell component of it, and I am using the CMD module to achieve this, I am able to setup tab completion for specific actions by using the complete_command method, for example:

_AVAILABLE_KEYS = ('python','php','ruby') 

def complete_add(self, text, line, begidx, endidx):
     return [i for i in self._AVAILABLE_KEYS if i.startswith(text)]

def do_example(self,args):
     if args == 'python':
          print 'yay!'
     else:
          print 'booooooo!'
This works great in the case above, when using things like 'example py<tab>'.

But, I want to use something similar to:

_AVAILABLE_KEYS = ('python','php','ruby') 

def complete_add(self, text, line, begidx, endidx):
     return [i for i in self._AVAILABLE_KEYS if i.startswith(text)]

def do_example(self,args):
     if len(args) > 1:
          language = args
     else:
          language = raw_input('What is the language of choice?: ') 

     if language == 'python':
          print 'yay!'
     else:
          print 'booooooo!'
And of course.. have the user able to use tab complete on the answer.

From what I've searched out there answers to what I could find expect some form of comprehension of readline, etc.. to which I have none.

I am more than happy to do research, but a basic code example would be most helpful, but if possible some form of description as to how it works so I can learn from this.

Any help would be great
I figured out how to answer my own question.

completer.py:
import readline

class askCompleter:
def __init__(self, words):
self.words = words
self.prefix = None

def setWords(self,words):
self.words = words

def ask(self,question,**kwargs):
completer = Completer(self.words)
readline.parse_and_bind("tab: complete")
readline.set_completer(completer.complete) 

if not 'null' in kwargs:
null = False
if null == True:
#return raw_input(question)
return raw_input(question)
else:
ans = ''
while not ans:
ans = raw_input(question)
return ans 


class Completer:
def __init__(self, words):
self.words = words
self.prefix = None

def complete(self, prefix, index):
if prefix != self.prefix:
# we have a new prefix!
# find all words that start with this prefix
self.matching_words = [
 w for w in self.words if w.startswith(prefix)
 ]
self.prefix = prefix
try:
return self.matching_words[index]
except IndexError:
return None
Then where my original code is:

_AVAILABLE_KEYS = ('python','php','ruby')
ac = completer.askCompleter(self._AVAILABLE_KEYS)
ac.ask('Language: ')
In short:

Rather than trying to play around with the Cmd module (which I know very little of), I setup a second class/module which uses a readline example I found somewhere on the internet (sorry I can't recall, I had it in a file called 'test.py' that I was playing with earlier).

It seems python is smart enough to understand that the tab completion is isolated to the class itself.  Pretty cool!