diff liboctave/oct-rl-hist.c @ 11486:a1deab9a6e71

bash-like history control
author Pascal Dupuis <Pascal.Dupuis@worldonline.be> and John W. Eaton <jwe@octave.org>
date Wed, 12 Jan 2011 03:40:19 -0500
parents 42d098307c30
children 0a4dfc867e60
line wrap: on
line diff
--- a/liboctave/oct-rl-hist.c	Wed Jan 12 01:15:23 2011 -0500
+++ b/liboctave/oct-rl-hist.c	Wed Jan 12 03:40:19 2011 -0500
@@ -24,6 +24,8 @@
 #include <config.h>
 #endif
 
+#include "oct-rl-hist.h"
+
 #if defined (USE_READLINE)
 
 #include <stdio.h>
@@ -32,10 +34,82 @@
 
 #include <readline/history.h>
 
-void
-octave_add_history (const char *line)
+/* check_history_control, hc_erasedup, and the core of
+   octave_add_history were borrowed from Bash.  */
+
+/* Check LINE against what HISTCONTROL says to do.  Returns 1 if the line
+   should be saved; 0 if it should be discarded.  */
+static int
+check_history_control (const char *line, int history_control)
 {
-  add_history (line);
+  HIST_ENTRY *temp;
+  int r;
+
+  if (history_control == 0)
+    return 1;
+
+  /* ignorespace or ignoreboth */
+  if ((history_control & HC_IGNSPACE) && *line == ' ')
+    return 0;
+
+  /* ignoredups or ignoreboth */
+  if (history_control & HC_IGNDUPS)
+    {
+      using_history ();
+      temp = previous_history ();
+
+      r = (temp == 0 || strcmp (temp->line, line));
+
+      using_history ();
+
+      if (r == 0)
+        return r;
+    }
+
+  return 1;
+}
+
+/* Remove all entries matching LINE from the history list.  Triggered when
+   HISTCONTROL includes `erasedups'.  */
+
+static void
+hc_erasedups (const char *line)
+{
+  HIST_ENTRY *temp;
+  int r;
+
+  using_history ();
+  while (temp = previous_history ())
+    {
+      if (! strcmp (temp->line, line))
+        {
+          r = where_history ();
+          remove_history (r);
+        }
+    }
+  using_history ();
+}
+
+/* Check LINE against HISTCONTROL and add it to the history if it's OK.
+   Returns 1 if the line was saved in the history, 0 otherwise.  */
+
+int
+octave_add_history (const char *line, int history_control)
+{
+  if (check_history_control (line, history_control))
+    {
+      /* We're committed to saving the line.  If the user has requested it,
+         remove other matching lines from the history.  */
+
+      if (history_control & HC_ERASEDUPS)
+        hc_erasedups (line);
+        
+      add_history (line);
+
+      return 1;
+    }
+
+  return 0;
 }
 
 int