Python Forum
Cmd Module + raw_input tab [complete
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Cmd Module + raw_input tab [complete
#1
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
Reply
#2
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!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Going thru tutorials..."NameError: name 'raw_input' is not defined" hmonnier 4 4,213 Jul-14-2020, 02:19 PM
Last Post: BitPythoner
  raw_input vs input EmilySenechal 1 2,358 Nov-20-2018, 02:13 AM
Last Post: ichabod801
  raw_input rtbr17 3 3,672 Sep-26-2018, 09:36 PM
Last Post: nilamo
  URL via raw_input, passed to HTTP requests and output? johnnyaustin 1 4,889 Dec-08-2017, 11:22 PM
Last Post: johnnyaustin
  Help with raw_input Marshall_99 2 3,425 Mar-21-2017, 01:44 AM
Last Post: Marshall_99
  Any way to get raw_input to work in my function? Pythonerous 4 5,233 Oct-27-2016, 05:03 PM
Last Post: Pythonerous

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020