customizing the readline module

holger krekel pyth at devel.trillke.net
Tue Aug 20 12:26:15 CEST 2002


Huaiyu Zhu wrote:
> Let me see if I can make this example more concrete.  For this example,
> let's assume that a='a', b='b', etc.  The acceptable answers from the
> interaction (the "legal command lines") would be one of the following
> 
> a b 
> a c
> a d
> e f
> e g h
> e g i
> 
> The intended behavior would be this: When user types 'e' and hit tab, the
> given choices should be (f, g).  If the user typed 'e g', the given choices
> should be (h, i).  That is, the set of choices would depend on what the user
> has typed so far on that line.
> 
> I can do this with the current readline module, as long as the last word 'g'
> uniquely identify the history 'e g', with the assumption that backspace is
> not used to change a partial answer.
> 
> This breaks down when e and g are the same word.  There is not sufficient
> information in deciding between the choices (f, g), which follows 'e', and
> (h, i), which follows 'e e'.

What you need is to issue

    readline.set_completer_delims('')

to prevent readline from giving you just a part of the line. This way you get
the complete line and can anaylize yourself (splitting into words etc.).
Of course your completer function then has to pass back completion
strings which represent a whole line.  But that's not hard.

> I hope the above explanation is clear enough by now.  By 'history', I'm
> refering to the partial command line from the beginning of the line up to
> the current cursor point.  (I realize there is another unintended collision
> of terminology with shell history.)  
> 
> An example (which is my typical usage) is this.  I'm doing several numerical
> experiments with a few parameters.  Sometime, such as during debugging, I'd
> like to set the parameters by hand, but other times I want them to be
> obtained from config files, in which case I'd like to set the config file
> names.  So a command line might be any of the following
> 
> run -p <a> <b> <c> <d>
> run -c <config-file-name>
> run -c <config-file-name> -r <result-dir-name>
> 
> or some other combinations.  Obviously, the choices given after 'run -c'
> should be different from 'run -r'.  The choices for each of <a>, <b>,
> ... should also be different.  Some of them would be numbers, in that case
> it would be useful if the prompted choice could be the variable name or its
> allowed range.  I'd like to know if this is doable without using curses
> module.

Yes, but you won't get any menus where you could select by moving the
cursor keys. The above method (clearing completer_delims) gives you
full power to parse yourself and give back anything you want.

But be careful. readline has two noteworthy (annoying) behaviours:

1) a common prefix for the completion matches is used to complete
   the line.  Sometimes you don't want that.  You can fix this
   by appending another string to the completion list which is
   not a prefix of the others.

2) readlines sorts the completion strings.  you have to use
   some trickery if you want your order preserved. 

look at the functions 'rl_fixorder' and 'rl_fixprefix' in

    http://home.trillke.net/~hpk/rlcompleter2.py
   
> Just to preempt another possible confusion, let me emphasize that I'm not
> dealing with the Unix shell command lines.  It is about using the readline
> module in an interactive shell written in Python.  So why don't I just use a
> dialog style interaction?  The answer is that in most cases the ability to
> use shell history is very handy.

i agree. thats why i am enhancing the interactive python shell
with the above module. 

greetings,

    holger




More information about the Python-list mailing list