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 <rafael.laboissi...@inserm.fr> [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

Reply via email to