customizing the readline module

holger krekel pyth at devel.trillke.net
Wed Aug 21 12:28:12 CEST 2002


Huaiyu Zhu wrote:
> holger krekel <pyth at devel.trillke.net> wrote:
> >
> >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.
> 
> Thanks.  This partially solved the problem.  However, passing back the whole
> line clutters up the completion choices offered by readline.  For example,
> suppose I want to choose from
> 
> aaa bbb1
> aaa bbb2
> 
> After 'aaa', if the completer returns ('bbb1', 'bbb2'), then when the first
> letter 'b' is pressed the partial line 'aaa' disappears.  If instead the
> completer returns ('aaa bbb1', 'aaa bbb2'), then the choices given are 'aaa
> bbb1 aaa bbb2', which is hard to read for long lines.

Oh, i am sorry.  last time i did this stuff it was a lot of trial and error. 

You can pass back *any* strings to readline (they needn't match the line
at all) but you have to be careful that they have no common prefix which
readline would simply take at face value and print. 

IOW for readline it's all completions (and it's all derived from
bash-requirements, btw).  

Example:

>> aaa <tab>

your completer function returns to readline 'aaa bbb'
so 

>> aaa bbb

appears on the screen. you hit 

>> aaa bbb<tab>

your completer function returns to readline 

    ['bbb1cc','bbb2cc','*'] 

which readline shows as completions. 

the user eventually types

>> aaa bbb1<tab>

you return 'aaa bbb1cc' (the complete line for unique completions!)

IOW you do all the work and control readline by passing
either one string (unique completion) or a list of strings
(which needn't be related to the actual line *at all*) but make sure 
that readline doesn't get in the way.

> Is there a way to tweak the protocol for readline to allow the semantics of
> passing back [aaa] as the accepted words and [bbb1, bbb2] as possible
> completions?  That would allow the command line to remain 'aaa ' while the
> completions be 'bbb1 bbb2'.

newer readline libs might help but python will not integrate that soon
enough, i guess.  The above approach works for me and is fairly backward
compatible.  

> BTW, why readline is so designed that it needs to make a sequence of calls
> terminated by an exception to obtain a list of completions, instead of just
> accepting a list of completions with a single call?

because it's about a 100 hundred years old or so :-)

More Seriously, i guess it's because readline wants to be able to
stop asking the completer if it gets has more than, say, 5000 completions
to prevent memory bloat or so...

But wait, you just return None when you are finished, no exception!

But it's ugly, yes. Easy enough to write a small wrapper which 
handles this for you so you only have to construct a list.

> I do not quite understand the other two problems you warned.  Maybe I
> haven't got to that stage yet.

It boils down to prevent readline from prematurely completing and
(in my case) to somehow fix the sort order.  

Another note. In python-cvs a patch of mine went in which fixes
an uglyness:

   with unique completions readlines appends a space character (' ').

in the above example you will note that when you return 'aaa bbb' that
readline actually prints 'aaa bbb '. the python2.2-commandline suffers
from the same problem.

nobody-said-readline-is-very-elegant'ly yours,

    holger




More information about the Python-list mailing list