From b499436ad8428a011e6f6073d08ff5fc4ff51ae2 Mon Sep 17 00:00:00 2001
From: Libor Morkovsky <liborek@gmail.com>
Date: Mon, 22 Jun 2015 17:53:43 +0200
Subject: [PATCH] directory commands can autocomplete across slash

---
 liboctave/cmd-edit.cc   |   49 ++++++++++++++++++++++++++++++++++++++++++++++-
 liboctave/cmd-edit.h    |   10 +++++++++
 liboctave/oct-rl-edit.c |    6 +++++
 liboctave/oct-rl-edit.h |    5 ++++
 src/input.cc            |   14 +++++++++++++
 5 files changed, 83 insertions(+), 1 deletions(-)

diff --git a/liboctave/cmd-edit.cc b/liboctave/cmd-edit.cc
index daa2948..9240523 100644
--- a/liboctave/cmd-edit.cc
+++ b/liboctave/cmd-edit.cc
@@ -70,6 +70,8 @@ public:
 
   typedef command_editor::completion_fcn completion_fcn;
 
+  typedef command_editor::word_break_fcn word_break_fcn;
+
   gnu_readline (void);
 
   ~gnu_readline (void) { }
@@ -114,6 +116,8 @@ public:
 
   void do_set_completion_function (completion_fcn f);
 
+  void do_set_word_break_function (word_break_fcn f);
+
   void do_set_quoting_function (quoting_fcn f);
 
   void do_set_dequoting_function (dequoting_fcn f);
@@ -124,6 +128,8 @@ public:
 
   completion_fcn do_get_completion_function (void) const;
 
+  word_break_fcn do_get_word_break_function (void) const;
+
   quoting_fcn do_get_quoting_function (void) const;
 
   dequoting_fcn do_get_dequoting_function (void) const;
@@ -177,6 +183,8 @@ private:
 
   completion_fcn completion_function;
 
+  word_break_fcn word_break_function;
+
   quoting_fcn quoting_function;
 
   dequoting_fcn dequoting_function;
@@ -195,11 +203,12 @@ private:
   static int command_accept_line (int count, int key);
 
   static char **command_completer (const char *text, int start, int end);
+  static const char *word_breaker();
 };
 
 gnu_readline::gnu_readline ()
   : command_editor (), previous_startup_hook (0),
-    previous_event_hook (0), completion_function (0),
+    previous_event_hook (0), completion_function (0), word_break_function(0),
     quoting_function (0), dequoting_function (0),
     char_is_quoted_function (0), user_accept_line_function (0)
 {
@@ -390,6 +399,17 @@ gnu_readline::do_set_completion_function (completion_fcn f)
 }
 
 void
+gnu_readline::do_set_word_break_function (word_break_fcn f)
+{
+  word_break_function = f;
+
+  rl_word_break_fcn_ptr fp
+    = f ? gnu_readline::word_breaker : 0;
+
+  ::octave_rl_set_word_break_function (fp);
+}
+
+void
 gnu_readline::do_set_quoting_function (quoting_fcn f)
 {
   quoting_function = f;
@@ -441,6 +461,12 @@ gnu_readline::do_get_completion_function (void) const
   return completion_function;
 }
 
+gnu_readline::word_break_fcn
+gnu_readline::do_get_word_break_function (void) const
+{
+  return word_break_function;
+}
+
 gnu_readline::quoting_fcn
 gnu_readline::do_get_quoting_function (void) const
 {
@@ -717,6 +743,13 @@ gnu_readline::command_completer (const char *text, int, int)
   return matches;
 }
 
+const char *
+gnu_readline::word_breaker ()
+{
+  word_break_fcn f = command_editor::get_word_break_function();
+  return f();
+}
+
 #endif
 
 class
@@ -1073,6 +1106,13 @@ command_editor::set_completion_function (completion_fcn f)
 }
 
 void
+command_editor::set_word_break_function (word_break_fcn f)
+{
+  if (instance_ok ())
+    instance->do_set_word_break_function (f);
+}
+
+void
 command_editor::set_quoting_function (quoting_fcn f)
 {
   if (instance_ok ())
@@ -1107,6 +1147,13 @@ command_editor::get_completion_function (void)
     ? instance->do_get_completion_function () : 0;
 }
 
+command_editor::word_break_fcn
+command_editor::get_word_break_function (void)
+{
+  return (instance_ok ())
+    ? instance->do_get_word_break_function () : 0;
+}
+
 command_editor::quoting_fcn
 command_editor::get_quoting_function (void)
 {
diff --git a/liboctave/cmd-edit.h b/liboctave/cmd-edit.h
index 46c0eb3..b4ed971 100644
--- a/liboctave/cmd-edit.h
+++ b/liboctave/cmd-edit.h
@@ -47,6 +47,8 @@ public:
 
   typedef std::string (*completion_fcn) (const std::string&, int);
 
+  typedef const char * (*word_break_fcn) (void);
+
   typedef std::string (*quoting_fcn) (const std::string&, int, char);
 
   typedef std::string (*dequoting_fcn) (const std::string&, int);
@@ -99,6 +101,8 @@ public:
 
   static void set_completion_function (completion_fcn f);
 
+  static void set_word_break_function (word_break_fcn f);
+
   static void set_quoting_function (quoting_fcn f);
 
   static void set_dequoting_function (dequoting_fcn f);
@@ -109,6 +113,8 @@ public:
 
   static completion_fcn get_completion_function (void);
 
+  static word_break_fcn get_word_break_function (void);
+
   static quoting_fcn get_quoting_function (void);
 
   static dequoting_fcn get_dequoting_function (void);
@@ -241,6 +247,8 @@ protected:
 
   virtual void do_set_completion_function (completion_fcn) { }
 
+  virtual void do_set_word_break_function (word_break_fcn) { }
+
   virtual void do_set_quoting_function (quoting_fcn) { }
 
   virtual void do_set_dequoting_function (dequoting_fcn) { }
@@ -251,6 +259,8 @@ protected:
 
   virtual completion_fcn do_get_completion_function (void) const { return 0; }
 
+  virtual word_break_fcn do_get_word_break_function (void) const { return 0; }
+
   virtual quoting_fcn do_get_quoting_function (void) const { return 0; }
 
   virtual dequoting_fcn do_get_dequoting_function (void) const { return 0; }
diff --git a/liboctave/oct-rl-edit.c b/liboctave/oct-rl-edit.c
index d4750fc..a640e5e 100644
--- a/liboctave/oct-rl-edit.c
+++ b/liboctave/oct-rl-edit.c
@@ -277,6 +277,12 @@ octave_rl_set_completion_function (rl_attempted_completion_fcn_ptr f)
 }
 
 void
+octave_rl_set_word_break_function (rl_word_break_fcn_ptr f)
+{
+  rl_completion_word_break_hook = f;
+}
+
+void
 octave_rl_set_quoting_function (rl_quoting_fcn_ptr f)
 {
   rl_filename_quoting_function = f;
diff --git a/liboctave/oct-rl-edit.h b/liboctave/oct-rl-edit.h
index 630d7c7..08a716d 100644
--- a/liboctave/oct-rl-edit.h
+++ b/liboctave/oct-rl-edit.h
@@ -37,6 +37,8 @@ typedef char * (*rl_quoting_fcn_ptr) (char *, int, char *);
 
 typedef char * (*rl_dequoting_fcn_ptr) (char *, int);
 
+typedef const char * (*rl_word_break_fcn_ptr) (void);
+
 typedef int (*rl_char_is_quoted_fcn_ptr) (char *, int);
 
 typedef int (*rl_command_fcn_ptr) (int, int);
@@ -108,6 +110,9 @@ extern void
 octave_rl_set_completion_function (rl_attempted_completion_fcn_ptr);
 
 extern void
+octave_rl_set_word_break_function (rl_word_break_fcn_ptr);
+
+extern void
 octave_rl_set_quoting_function (rl_quoting_fcn_ptr);
 
 extern void
diff --git a/src/input.cc b/src/input.cc
index 82e0691..152e72e 100644
--- a/src/input.cc
+++ b/src/input.cc
@@ -501,6 +501,19 @@ is_completing_dirfns (void)
   return retval;
 }
 
+const char *
+dir_word_breaker()
+{
+  // if completing a path, do not break into 
+  // words on that many chars
+  if(is_completing_dirfns()) {
+    return " \t\n";
+  }
+
+  // otherwise use the default
+  return 0;
+}
+
 static std::string
 generate_completion (const std::string& text, int state)
 {
@@ -620,6 +633,7 @@ initialize_command_input (void)
   command_editor::set_filename_quote_characters (" \t\n\\\"'@<>=;|&()#$`?*[!:{");
   command_editor::set_completer_quote_characters ("'\"");
 
+  command_editor::set_word_break_function (dir_word_breaker);
   command_editor::set_completion_function (generate_completion);
 
   command_editor::set_quoting_function (quoting_filename);
-- 
1.7.2.3

