readline trick needed

Discussion in 'Python' started by Steven D'Aprano, Oct 13, 2012.

  1. I'm working with the readline module, and I'm trying to set a key
    combination to process the current command line by calling a known
    function, *and* enter the command line.

    Something along the lines of:

    * execute function spam() in some context where it can access
    the current command line as a string
    * enter the command line

    Function spam() may or may not modify the command line.

    Here is what I have got so far: I can discard the current line and call a
    function:

    readline.parse_and_bind(r'"\C-p": "%cspam()\n"' % 0x15) # ^U

    binds ctrl-P to the key combinations `ctrl-U spam() Enter`, which clears
    the command line before entering spam().

    If I leave out the ctrl-U, I'll get a SyntaxError or other exception,
    e.g. command line `x = 123` gets transformed into `x = 123spam()`.


    This is not suitable:

    readline.parse_and_bind(r'"\C-p": "; spam()\n"')

    because it changes the command line. It's okay for spam() itself to
    modify the command line, but the key binding should not.

    I tried to do this:

    readline.parse_and_bind(r'"\C-p": "\nspam()\n"')

    but it gives me a segmentation fault, which is a little less helpful than
    I had expected.

    This Stackoverflow question suggests that what I want is not possible in
    vanilla Python:

    http://stackoverflow.com/questions/11680356


    but I'm a stubborn guy and I have not given up yet. Any suggestions?


    (P.S. I'm aware of IPython, I want to get this working in the standard
    CPython interpreter.)


    --
    Steven
    Steven D'Aprano, Oct 13, 2012
    #1
    1. Advertising

  2. On 13 Oct 2012 13:30:14 GMT
    Steven D'Aprano <> wrote:

    > I'm working with the readline module, and I'm trying to set a key
    > combination to process the current command line by calling a known
    > function, *and* enter the command line.
    >
    > Something along the lines of:
    >
    > * execute function spam() in some context where it can access
    > the current command line as a string
    > * enter the command line
    >
    > Function spam() may or may not modify the command line.
    >
    > Here is what I have got so far: I can discard the current line and call a
    > function:
    >
    > readline.parse_and_bind(r'"\C-p": "%cspam()\n"' % 0x15) # ^U
    >
    > binds ctrl-P to the key combinations `ctrl-U spam() Enter`, which clears
    > the command line before entering spam().
    >
    > If I leave out the ctrl-U, I'll get a SyntaxError or other exception,
    > e.g. command line `x = 123` gets transformed into `x = 123spam()`.
    >
    >
    > This is not suitable:
    >
    > readline.parse_and_bind(r'"\C-p": "; spam()\n"')
    >
    > because it changes the command line. It's okay for spam() itself to
    > modify the command line, but the key binding should not.
    >
    > I tried to do this:
    >
    > readline.parse_and_bind(r'"\C-p": "\nspam()\n"')
    >
    > but it gives me a segmentation fault, which is a little less helpful than
    > I had expected.
    >
    > This Stackoverflow question suggests that what I want is not possible in
    > vanilla Python:
    >
    > http://stackoverflow.com/questions/11680356
    >
    >
    > but I'm a stubborn guy and I have not given up yet. Any suggestions?
    >
    >
    > (P.S. I'm aware of IPython, I want to get this working in the standard
    > CPython interpreter.)
    >
    >
    > --
    > Steven
    > --
    > http://mail.python.org/mailman/listinfo/python-list



    Why dont you grow yourself some usable neurons instead ? Don't you realize now stackoverflow.com is starting
    to hurt your capacity to cogitate on your own or have you not realized this yet?

    Cheers,

    Etienne


    --
    Etienne Robillard
    Green Tea Hackers Club
    Fine Software Carpentry For The Rest Of Us!
    http://gthc.org/
    Etienne Robillard, Oct 13, 2012
    #2
    1. Advertising

  3. On Sun, Oct 14, 2012 at 12:44 AM, Etienne Robillard
    <> wrote:
    > Why dont you grow yourself some usable neurons instead ? Don't you realize now stackoverflow.com is starting
    > to hurt your capacity to cogitate on your own or have you not realized this yet?


    Excuse me?

    I'm not overly familiar with readline, so perhaps there is a really
    obvious way to do what Steven's trying to do, but this post does not
    appear to be the result of a lack of thinking.

    If it really IS that obvious to you, post a link to appropriate
    documentation without the rudeness... that way it'll be useful to
    everyone, not just cathartic to you.

    ChrisA
    Chris Angelico, Oct 13, 2012
    #3
  4. On Sun, 14 Oct 2012 00:47:52 +1100
    Chris Angelico <> wrote:

    > Excuse me?
    >
    > I'm not overly familiar with readline, so perhaps there is a really
    > obvious way to do what Steven's trying to do, but this post does not
    > appear to be the result of a lack of thinking.
    >
    > If it really IS that obvious to you, post a link to appropriate
    > documentation without the rudeness... that way it'll be useful to
    > everyone, not just cathartic to you.
    >
    > ChrisA
    > --
    > http://mail.python.org/mailman/listinfo/python-list


    whatever. i don't feel much like replying to idiots today so your apologies
    and useless if not irrelevant.



    --
    Etienne Robillard
    Green Tea Hackers Club
    Fine Software Carpentry For The Rest Of Us!
    http://gthc.org/
    Etienne Robillard, Oct 13, 2012
    #4
  5. Etienne Robillard schreef:
    > On Sun, 14 Oct 2012 00:47:52 +1100
    > Chris Angelico <> wrote:
    >
    >> Excuse me?
    >>
    >> I'm not overly familiar with readline, so perhaps there is a really
    >> obvious way to do what Steven's trying to do, but this post does not
    >> appear to be the result of a lack of thinking.
    >>
    >> If it really IS that obvious to you, post a link to appropriate
    >> documentation without the rudeness... that way it'll be useful to
    >> everyone, not just cathartic to you.
    >>
    >> ChrisA
    >> --
    >> http://mail.python.org/mailman/listinfo/python-list

    >
    > whatever. i don't feel much like replying to idiots today


    Then simply don't. Much better then replying in such a rude way.

    I leave the question of who is being an idiot here as an exercise to the
    reader.

    --
    "Too often we hold fast to the cliches of our forebears. We subject all
    facts to a prefabricated set of interpretations. Too often we enjoy the
    comfort of opinion without the discomfort of thought."
    -- John F Kennedy

    Roel Schroeven, Oct 13, 2012
    #5
  6. On Sun, Oct 14, 2012 at 8:31 AM, Joshua Landau
    <> wrote:
    > With two irritants (including 88888), is it not advisable that python-list
    > gets an admin to block these accounts? Even if it does nothing more than
    > slow them, that's something.


    That's what killfiles are for. You have two options:

    http://en.wikipedia.org/wiki/Kill_file
    http://bofh.ch/bofh/bsmh2.html

    The first option is not perfect, as you'll still see replies that
    quote such people's posts. The second has a few issues with local law
    enforcement, but other than that, is a very effective means of
    avoiding seeing their posts.

    ChrisA
    Chris Angelico, Oct 13, 2012
    #6
  7. On 13/10/2012 22:31, Joshua Landau wrote:
    >
    > With two irritants (including 88888), is it not advisable that python-list
    > gets an admin to block these accounts? Even if it does nothing more than
    > slow them, that's something.
    >


    Most irritants are mere amateurs compared to Ilias Lazaridis. I wonder
    if he's *STILL* researching?

    --
    Cheers.

    Mark Lawrence.
    Mark Lawrence, Oct 13, 2012
    #7
  8. On Sun, Oct 14, 2012 at 9:25 AM, Joshua Landau
    <> wrote:
    > On 13 October 2012 22:44, Chris Angelico <> wrote:
    >>
    >> On Sun, Oct 14, 2012 at 8:31 AM, Joshua Landau
    >> <> wrote:
    >> > With two irritants (including 88888), is it not advisable that
    >> > python-list
    >> > gets an admin to block these accounts? Even if it does nothing more than
    >> > slow them, that's something.

    >>
    >> That's what killfiles are for. You have two options:
    >>
    >> http://en.wikipedia.org/wiki/Kill_file
    >> http://bofh.ch/bofh/bsmh2.html
    >>
    >> The first option is not perfect, as you'll still see replies that
    >> quote such people's posts. The second has a few issues with local law
    >> enforcement, but other than that, is a very effective means of
    >> avoiding seeing their posts.

    >
    >
    > The first's no good for protecting the newbies though. If troll flames
    > newbie, then I want to be able to assure newbie that he's not done anything
    > wrong or stupid.
    >
    > The second is a bit better, definitely, but what I'm wanting is to delegate
    > these tasks to python-list's admins. I'm lazy, see.


    Agreed, defending newbies is important. But not everyone gets
    frustrated at trolls. Those who don't, don't bother to killfile them,
    and can respond in defense of the newbies. Also, if two or three
    non-trolls respond to the original post, the angry troll is only one
    of several, which helps dilute the problem a bit. Still not a
    solution, but it helps.

    ChrisA
    Chris Angelico, Oct 13, 2012
    #8
  9. On 13/10/2012 23:26, Joshua Landau wrote:
    > On 13 October 2012 23:13, Mark Lawrence <> wrote:
    >
    >> On 13/10/2012 22:31, Joshua Landau wrote:
    >>
    >>>
    >>> With two irritants (including 88888), is it not advisable that python-list
    >>> gets an admin to block these accounts? Even if it does nothing more than
    >>> slow them, that's something.
    >>>
    >>>

    >> Most irritants are mere amateurs compared to Ilias Lazaridis. I wonder if
    >> he's *STILL* researching?

    >
    >
    > My god, he even has an encyclopaedia
    > entry<http://www.nationmaster.com/encyclopedia/Ilias-Lazaridis>.
    > Is he some kind of deity?
    >


    Oh no he's far higher up the food chain than that. Here's a starter
    https://groups.google.com/forum/?fromgroups=#!search/lazaridis$20banned/comp.lang.ruby/plR34TbM3vc/Ev-Hj5F8oKcJ

    --
    Cheers.

    Mark Lawrence.
    Mark Lawrence, Oct 13, 2012
    #9
  10. On 13/10/2012 23:52, Mark Lawrence wrote:
    > On 13/10/2012 23:26, Joshua Landau wrote:
    >> On 13 October 2012 23:13, Mark Lawrence <> wrote:
    >>
    >>> On 13/10/2012 22:31, Joshua Landau wrote:
    >>>
    >>>>
    >>>> With two irritants (including 88888), is it not advisable that
    >>>> python-list
    >>>> gets an admin to block these accounts? Even if it does nothing more
    >>>> than
    >>>> slow them, that's something.
    >>>>
    >>>>
    >>> Most irritants are mere amateurs compared to Ilias Lazaridis. I
    >>> wonder if
    >>> he's *STILL* researching?

    >>
    >>
    >> My god, he even has an encyclopaedia
    >> entry<http://www.nationmaster.com/encyclopedia/Ilias-Lazaridis>.
    >> Is he some kind of deity?
    >>

    >
    > Oh no he's far higher up the food chain than that. Here's a starter
    > https://groups.google.com/forum/?fromgroups=#!search/lazaridis$20banned/comp.lang.ruby/plR34TbM3vc/Ev-Hj5F8oKcJ
    >
    >


    Yes a real pro. Trolling will never become an Olympic sport as the
    guy's so good nobody can compete with him. (If he was American they'd
    still have a World Series though :) Throw his name plus Eclipse,
    Netbeans and banned into your search engine of choice and enjoy, but
    beware that to really endulge yourself please stock up on vast
    quantities of caffeine and sandwiches first cos you'll need them. For
    example this http://web.archiveorange.com/archive/v/7IfPlywrYZb0gAgMsPa1
    points to this http://www.tfeb.org/lisp/mad-people.html

    --
    Cheers.

    Mark Lawrence.
    Mark Lawrence, Oct 14, 2012
    #10
  11. Steven D'Aprano

    Peter Otten Guest

    [on topic] Re: readline trick needed

    Steven D'Aprano wrote:

    > I'm working with the readline module, and I'm trying to set a key
    > combination to process the current command line by calling a known
    > function, *and* enter the command line.
    >
    > Something along the lines of:
    >
    > * execute function spam() in some context where it can access
    > the current command line as a string
    > * enter the command line
    >
    > Function spam() may or may not modify the command line.


    > (P.S. I'm aware of IPython, I want to get this working in the standard
    > CPython interpreter.)


    If IPython does what you want why don't you have a look at the source?

    Anyway, here's what I came up with (no warranties as it was all trial-and-
    error):

    $ cat readline_callback.py
    import ctypes
    import ctypes.util
    from ctypes import c_int, c_char_p
    import readline
    import sys

    rlname = ctypes.util.find_library("readline")

    # int rl_add_defun (const char *name, rl_command_func_t *function, int key)
    # typedef int rl_command_func_t (int, int);
    # int rl_done
    # char * rl_line_buffer

    rl = ctypes.CDLL(rlname)

    RL_COMMAND_FUNC = ctypes.CFUNCTYPE(c_int, c_int, c_int)

    intercepted_line = None
    def lovely_spam(a, b):
    global intercepted_line
    print
    intercepted_line = c_char_p.in_dll(rl, "rl_line_buffer").value
    rl.rl_insert_text("*" + intercepted_line)
    c_int.in_dll(rl, "rl_done").value = 1
    return 0

    def control(c):
    return ord(c.upper())-64

    rl.rl_add_defun("lovely-spam", RL_COMMAND_FUNC(lovely_spam), control("P"))

    #rl.rl_add_defun("lovely-spam", RL_COMMAND_FUNC(lovely_spam), -1)
    #readline.parse_and_bind("Control-P: lovely-spam")

    $ python -i readline_callback.py
    >>> alpha = 42
    >>> alpha

    1764

    The relevant documentation:
    http://cnswww.cns.cwru.edu/php/chet/readline/readline.html
    http://docs.python.org/library/ctypes.html
    Peter Otten, Oct 16, 2012
    #11
  12. Steven D'Aprano

    Ned Deily Guest

    Re: [on topic] Re: readline trick needed

    In article <k5j5sk$msb$>, Peter Otten <>
    wrote:
    > Steven D'Aprano wrote:
    > > I'm working with the readline module, and I'm trying to set a key
    > > combination to process the current command line by calling a known
    > > function, *and* enter the command line.

    [...]
    > Anyway, here's what I came up with (no warranties as it was all trial-and-
    > error):

    [...]

    Keep in mind that the Python readline module may be linked to either the
    GPL-licensed GNU readline or the BSD-licensed editline (libedit) library
    (the default on newer OS X systems and probably on *BSD systems) and
    they have different command strings. Note the warning here:

    http://docs.python.org/py3k/library/readline.html

    Or it may not be linked with either.

    --
    Ned Deily,
    Ned Deily, Oct 16, 2012
    #12
  13. Steven D'Aprano

    Peter Otten Guest

    Re: [on topic] Re: readline trick needed

    Ned Deily wrote:

    > In article <k5j5sk$msb$>, Peter Otten <>
    > wrote:
    >> Steven D'Aprano wrote:
    >> > I'm working with the readline module, and I'm trying to set a key
    >> > combination to process the current command line by calling a known
    >> > function, *and* enter the command line.

    > [...]
    >> Anyway, here's what I came up with (no warranties as it was all
    >> trial-and- error):

    > [...]
    >
    > Keep in mind that the Python readline module may be linked to either the
    > GPL-licensed GNU readline or the BSD-licensed editline (libedit) library
    > (the default on newer OS X systems and probably on *BSD systems) and
    > they have different command strings. Note the warning here:
    >
    > http://docs.python.org/py3k/library/readline.html


    I think you are a Mac user. If so, can the snippet I posted be generalised
    to work with libedit?

    > Or it may not be linked with either.


    OK, change "no warranties" to "absolutely no warranties" ;)
    Peter Otten, Oct 16, 2012
    #13
  14. Re: [on topic] Re: readline trick needed

    On Tue, 16 Oct 2012 10:30:01 +0200, Peter Otten wrote:

    > Steven D'Aprano wrote:
    >
    >> I'm working with the readline module, and I'm trying to set a key
    >> combination to process the current command line by calling a known
    >> function, *and* enter the command line.
    >>
    >> Something along the lines of:
    >>
    >> * execute function spam() in some context where it can access
    >> the current command line as a string
    >> * enter the command line
    >>
    >> Function spam() may or may not modify the command line.

    >
    >> (P.S. I'm aware of IPython, I want to get this working in the standard
    >> CPython interpreter.)

    >
    > If IPython does what you want why don't you have a look at the source?


    Well, I was hoping for a pure Python solution, rather than having to
    troll through who knows how many thousands of lines of code in a language
    I can barely read.


    > Anyway, here's what I came up with (no warranties as it was all
    > trial-and- error):
    >
    > $ cat readline_callback.py
    > import ctypes


    Ah, ctypes.

    Well, I guess I have some interesting study ahead of me, to make head or
    tail of your solution. Thank you!



    --
    Steven
    Steven D'Aprano, Oct 16, 2012
    #14
  15. Steven D'Aprano

    Robert Kern Guest

    Re: [on topic] Re: readline trick needed

    On 10/16/12 12:27 PM, Steven D'Aprano wrote:
    > On Tue, 16 Oct 2012 10:30:01 +0200, Peter Otten wrote:
    >
    >> Steven D'Aprano wrote:
    >>
    >>> I'm working with the readline module, and I'm trying to set a key
    >>> combination to process the current command line by calling a known
    >>> function, *and* enter the command line.
    >>>
    >>> Something along the lines of:
    >>>
    >>> * execute function spam() in some context where it can access
    >>> the current command line as a string
    >>> * enter the command line
    >>>
    >>> Function spam() may or may not modify the command line.

    >>
    >>> (P.S. I'm aware of IPython, I want to get this working in the standard
    >>> CPython interpreter.)

    >>
    >> If IPython does what you want why don't you have a look at the source?

    >
    > Well, I was hoping for a pure Python solution, rather than having to
    > troll through who knows how many thousands of lines of code in a language
    > I can barely read.


    Are you confusing IPython, the pure Python REPL for CPython, for IronPython, the
    C# implementation of Python?

    https://github.com/ipython/ipython

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
    Robert Kern, Oct 16, 2012
    #15
  16. Re: [on topic] Re: readline trick needed

    On Tue, 16 Oct 2012 13:20:24 +0100, Robert Kern wrote:

    > On 10/16/12 12:27 PM, Steven D'Aprano wrote:


    >> Well, I was hoping for a pure Python solution, rather than having to
    >> troll through who knows how many thousands of lines of code in a
    >> language I can barely read.

    >
    > Are you confusing IPython, the pure Python REPL for CPython,


    IPython is pure Python?

    Well, you learn something new everyday. Or at least I do.

    I guess that means that I can look forward to trolling through 250 or so
    Python modules instead of C code :)


    Thanks to everyone who replied.


    --
    Steven
    Steven D'Aprano, Oct 16, 2012
    #16
  17. Steven D'Aprano

    Dwight Hutto Guest

    Re: [on topic] Re: readline trick needed

    On Tue, Oct 16, 2012 at 7:27 AM, Steven D'Aprano
    <> wrote:
    > On Tue, 16 Oct 2012 10:30:01 +0200, Peter Otten wrote:
    >
    >> Steven D'Aprano wrote:
    >>
    >>> I'm working with the readline module, and I'm trying to set a key
    >>> combination to process the current command line by calling a known
    >>> function, *and* enter the command line.
    >>>
    >>> Something along the lines of:
    >>>
    >>> * execute function spam() in some context where it can access
    >>> the current command line as a string
    >>> * enter the command line
    >>>


    I'm working on the dictionary now,but I came up with this, which uses
    a list as the key, and accepts the params to perform the function:

    import subprocess as sub
    key_list = ['print_something','espeak']

    def print_something(params):
    print "%s" % (params)

    def espeak(params):
    sub.call(['espeak','%s' % (params)])

    key = raw_input("Please enter key: ")

    for line in key_list:
    if str(line) == key:
    params = raw_input("Enter Params: ")
    eval("%s('%s')" % (key,params))


    I keep getting the function performed in the dict. I'll figure it out
    eventually, I know I've done it before, and it might be a lambda
    solution...not sure.

    But the above could be refined more, it just uses a list, and key/params.


    --
    Best Regards,
    David Hutto
    CEO: http://www.hitwebdevelopment.com
    Dwight Hutto, Oct 16, 2012
    #17
  18. Steven D'Aprano

    Peter Otten Guest

    [off topic], was Re: [on topic] Re: readline trick needed

    Dwight Hutto wrote:

    I knew I'd eventually regret putting "on topic" into the subject...

    Well done, Dwight.
    Peter Otten, Oct 16, 2012
    #18
  19. Steven D'Aprano

    Dwight Hutto Guest

    Re: [off topic], was Re: [on topic] Re: readline trick needed

    On Tue, Oct 16, 2012 at 10:36 AM, Peter Otten <> wrote:
    > Dwight Hutto wrote:
    >
    > I knew I'd eventually regret putting "on topic" into the subject...


    I didn't write that. If you're referring to OT, it means Off Topic,
    and a response would be appreciated. And you can call me David, I go
    by my middle name.
    >
    > Well done, Dwight.
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list




    --
    Best Regards,
    David Hutto
    CEO: http://www.hitwebdevelopment.com
    Dwight Hutto, Oct 16, 2012
    #19
  20. Steven D'Aprano

    Ned Deily Guest

    Re: [on topic] Re: readline trick needed

    In article <k5jcbs$eub$>, Peter Otten <>
    wrote:
    > Ned Deily wrote:
    > > Keep in mind that the Python readline module may be linked to either the
    > > GPL-licensed GNU readline or the BSD-licensed editline (libedit) library
    > > (the default on newer OS X systems and probably on *BSD systems) and
    > > they have different command strings. Note the warning here:
    > >
    > > http://docs.python.org/py3k/library/readline.html

    >
    > I think you are a Mac user. If so, can the snippet I posted be generalised
    > to work with libedit?


    Isn't it hairy enough??

    Here's how to make tab complete work with both; it gives an idea of the
    libedit commands:

    import rlcompleter
    if 'libedit' in readline.__doc__:
    readline.parse_and_bind("bind ^I rl_complete")
    else: # GNU readline format
    readline.parse_and_bind("tab: complete")

    The documentation of the command syntax is in the .editrc man pages, for
    example:

    https://developer.apple.com/library/mac/#documentation/Darwin/Reference/M
    anPages/man5/editrc.5.html

    > > Or it may not be linked with either.

    > OK, change "no warranties" to "absolutely no warranties" ;)


    Good idea.

    --
    Ned Deily,
    Ned Deily, Oct 16, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. eran
    Replies:
    7
    Views:
    396
  2. gavino
    Replies:
    4
    Views:
    536
    gavino
    Sep 20, 2010
  3. Jean-Michel
    Replies:
    0
    Views:
    359
    Jean-Michel
    Dec 22, 2007
  4. Patrick Drouin

    regex trick needed

    Patrick Drouin, Oct 26, 2004, in forum: Perl Misc
    Replies:
    9
    Views:
    121
    Tad McClellan
    Oct 27, 2004
  5. Andrew DeFaria
    Replies:
    1
    Views:
    208
    Ben Morrow
    Jan 30, 2008
Loading...

Share This Page