Okay, I could not refrain myself and implemented the change in
src/unix/sys-std.c. The patch is attached below. I tested it in the
2.11.1 source and it worked fine. At any rate, the patch applies cleanly
to the SVN source.
Three notes about this patch:
1. The code is taken from the bash source (bashline.c) with minimal
changes.
2. The changes are put inside #ifdef HAVE_READLINE_HISTORY_H, because
it uses history related functions.
3. In the call to rl_add_defun, the operate-and-get-next function is
bound to C-o. This is not the behavior of Bash and Octave, which
depends on the user to define the key binding in ~/.inputrc. To
mimic this behavior, the code should be rather:
rl_add_defun ("operate-and-get-next", operate_and_get_next, -1);
Best regards,
Rafael Laboissiere
* Rafael Laboissiere [2010-08-07 13:07]:
> Both Bash and Octave have a nifty addition to the readline library called
> "operate-and-get-next", bound to "C-o". This function accepts the
> current line for execution and fetch the next line relative to the
> current line from the history for editing (see
> http://www.faqs.org/docs/bashman/bashref_101.html).
>
> This feature has a huge impact in my productivity using Bash and Octave
> interactively, since it avoids those numerous arrow key strokes in order
> to rerun a previous block of commands.
>
> I looked at the Bash sources and it does not seem too complicate to
> implement. Octave has borrowed practically the same code from Bash.
> Before I start looking at the R code, I would like to know whether the R
> developers had already planned to include the operate-and-get-next
> feature into R.
>
> Best regards,
>
> Rafael Laboissiere
--- a/src/unix/sys-std.c
+++ b/src/unix/sys-std.c
@@ -596,6 +596,54 @@
onintr();
}
+
+#ifdef HAVE_READLINE_HISTORY_H
+/*
+ Add a function that accepts the current line for execution and
+ fetch the next line relative to the current line from the history for
+ editing.
+
+ The code below is taken almost as is from the Bash source (bashline.c).
+*/
+
+static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
+
+static int saved_history_line_to_use = -1;
+
+static int
+set_saved_history ()
+{
+ 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_is_stifled () && (history_length >= history_max_entries)) ||
+ (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
+
#ifdef HAVE_RL_COMPLETION_MATCHES
/*
function-completion interface formerly in package rcompletion by
@@ -893,6 +941,10 @@
#ifdef HAVE_RL_COMPLETION_MATCHES
initialize_rlcompletion();
#endif
+#ifdef HAVE_READLINE_HISTORY_H
+rl_add_defun ("operate-and-get-next", operate_and_get_next,
+ CTRL ('O'));
+#endif
}
else
#endif /* HAVE_LIBREADLINE */
__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel