Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.albasani.net!news.stack.nl!newsfeed.xs4all.nl!newsfeed2a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; '+++': 0.03; 'static': 0.04; 'diff': 0.07; 'granted,': 0.07; 'initialize': 0.07; '#endif': 0.09; '+/*': 0.09; 'assuming': 0.09; 'bash': 0.09; 'content-type:text/x-diff': 0.09; 'function,': 0.09; 'received:151': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'python': 0.11; 'mostly': 0.14; '(int': 0.16; '+#define': 0.16; '+#endif': 0.16; '+#if': 0.16; '+#ifndef': 0.16; '-1;': 0.16; 'command.': 0.16; 'count,': 0.16; 'emanuele': 0.16; 'fluent': 0.16; 'mercurial,': 0.16; 'module?': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'xxx:': 0.16; 'attach': 0.16; ':-)': 0.16; 'do,': 0.16; 'wrote:': 0.18; 'library': 0.18; 'ticket': 0.19; '(where': 0.19; 'code,': 0.22; 'memory': 0.22; 'aug': 0.22; 'shell': 0.22; 'skip:+ 20': 0.22; 'header:User-Agent:1': 0.23; 'char': 0.24; 'mon,': 0.24; '---': 0.24; "i've": 0.25; '(see': 0.26; '+0200': 0.26; 'equivalent': 0.26; 'possibly': 0.26; 'skip:" 20': 0.27; 'header:X -Complaints-To:1': 0.27; 'tried': 0.27; 'appreciated.': 0.29; '0);': 0.29; 'patch': 0.29; 'related': 0.29; 'skip:( 20': 0.30; "i'm": 0.30; 'work.': 0.31; 'code': 0.31; 'complete,': 0.31; "d'aprano": 0.31; 'default,': 0.31; 'enabled': 0.31; 'skip:! 10': 0.31; 'steven': 0.31; 'subject:next': 0.31; 'writes:': 0.31; 'open': 0.33; 'not.': 0.33; 'there,': 0.34; "i'd": 0.34; '+0200,': 0.36; 'next': 0.36; 'should': 0.36; 'positive': 0.37; 'skip:o 20': 0.38; 'apple': 0.38; 'filled': 0.38; 'to:addr:python-list': 0.38; 'issue': 0.38; 'does': 0.39; 'use.': 0.39; 'to:addr:python.org': 0.39; 'system.': 0.39; 'received:org': 0.40; 'even': 0.60; 'che': 0.60; 'eventually': 0.60; 'forum': 0.61; 'skip:o 30': 0.61; 'full': 0.61; 'first': 0.61; 'hear': 0.63; 'determine': 0.67; 'hints': 0.68; 'line,': 0.68; 'skip:r 40': 0.68; 'default': 0.69; 'skip:r 30': 0.69; 'opinions': 0.70; 'jul': 0.74; 'touch': 0.74; 'goal': 0.75; 'subject:get': 0.81; 'quando': 0.84 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Lele Gaifax Subject: Adapt bash readline operate-and-get-next Date: Mon, 18 Aug 2014 20:49:13 +0200 Organization: Nautilus Entertainments References: <232acf45-096d-466a-aa75-06d8c378b128@googlegroups.com> <53cc376e$0$2898$e4fe514c@news.xs4all.nl> <53926733-5e65-482f-96bc-0171c6a93d59@googlegroups.com> <4882fd4d-b772-4ebb-8aaa-0c20be6051b6@googlegroups.com> <53cd47fc$0$6574$c3e8da3$5496439d@news.astraweb.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Gmane-NNTP-Posting-Host: 151.62.28.218 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.93 (gnu/linux) Cancel-Lock: sha1:zsON0z132Ldro4k/gFdBvreMcPI= X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 136 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1408387774 news.xs4all.nl 2952 [2001:888:2000:d::a6]:50186 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:76502 --=-=-= Content-Type: text/plain Steven D'Aprano writes: > On Mon, 21 Jul 2014 17:57:22 +0200, Lele Gaifax wrote: >> Granted, the readline library exposes a "operate-and-get-next" function, >> by default bound to \C-o... > > Have you actually got that working in Python with the readline module? > I've tried and tried and cannot get it to work. Any hints gratefully > appreciated. This is just a first attempt to adapt the Bash code to the Python readline.c module: I'm very surprised that the half-an-hour I spent on it, mostly to locate related code, actually full filled the goal :-) The patch isn't complete, in particular, it does not work on Apple's libedit, because I have no way to try it on that system. Also, I'm not fluent with Mercurial, so this is just a "hg diff". Even if I know this is not the right forum and I should (and I eventually do, assuming a positive feedback) instead open a ticket and attach the patch there, I'd like to hear opinions on whether this should be enabled by default, and possibly get in touch with some Apple owner... ciao, lele. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=readline.patch diff -r e5f78085499e Modules/readline.c --- a/Modules/readline.c Mon Aug 18 17:48:15 2014 +0300 +++ b/Modules/readline.c Mon Aug 18 20:46:43 2014 +0200 @@ -73,6 +73,13 @@ int num_matches, int max_length); #endif +#if !defined(__APPLE__) +static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL; +static int hist_last_line_added; +static int set_saved_history(void); +static int operate_and_get_next(int count, int c); +#endif + /* Memory allocated for rl_completer_word_break_characters (see issue #17289 for the motivation). */ static char *completer_word_break_characters; @@ -1032,6 +1039,10 @@ With libedit, this call makes readline() crash. */ rl_variable_bind ("enable-meta-key", "off"); } + + /* XXX: determine whether the following works on libedit */ + rl_add_defun("operate-and-get-next", operate_and_get_next, -1); + rl_bind_key_if_unbound_in_map(CTRL('O'), operate_and_get_next, emacs_standard_keymap); #endif /* Initialize (allows .inputrc to override) @@ -1287,3 +1298,61 @@ setup_readline(mod_state); return m; } + +#ifndef __APPLE__ + +/* XXX: determine whether the following works on libedit */ + +/* Following code taken from bash' bashline.c */ + +/* The equivalent of the Korn shell C-o operate-and-get-next-history-line + editing command. */ +static int saved_history_line_to_use = -1; +static int last_saved_history_line = -1; + +#define HISTORY_FULL() (history_is_stifled() && history_length >= history_max_entries) + +static int +set_saved_history() +{ + /* XXX - compensate for assumption that history was `shuffled' if it was + actually not. */ + if (HISTORY_FULL() && + hist_last_line_added == 0 && + saved_history_line_to_use < history_length - 1) + saved_history_line_to_use++; + + if (saved_history_line_to_use >= 0) { + rl_get_previous_history(history_length - saved_history_line_to_use, 0); + last_saved_history_line = saved_history_line_to_use; + } + + saved_history_line_to_use = -1; + rl_startup_hook = old_rl_startup_hook; + + return 0; +} + +static int +operate_and_get_next (int count, int c) +{ + int where; + + /* Accept the current line. */ + rl_newline(1, c); + + /* Find the current line, and find the next line to use. */ + where = where_history(); + + if (HISTORY_FULL() || (where >= history_length - 1)) + saved_history_line_to_use = where; + else + saved_history_line_to_use = where + 1; + + old_rl_startup_hook = rl_startup_hook; + rl_startup_hook = set_saved_history; + + return 0; +} + +#endif --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit -- nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia. lele@metapensiero.it | -- Fortunato Depero, 1929. --=-=-=--