diff -r e5f78085499e Modules/readline.c --- a/Modules/readline.c Mon Aug 18 17:48:15 2014 +0300 +++ b/Modules/readline.c Tue Aug 19 11:40:21 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; @@ -126,6 +133,60 @@ #define readlinestate_global ((readlinestate *)PyModule_GetState(PyState_FindModule(&readlinemodule))) +#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; + +#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); + + 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 + + /* Exported function to send one line to readline's init file parser */ static PyObject * @@ -1032,6 +1093,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)