Scheduler: Implement new file descriptor event API
[senf.git] / Console / Readline.cc
index 8d796e6..a02e2a8 100644 (file)
@@ -79,9 +79,13 @@ namespace {
 
     void readline_callback(char * input)
     {
-        if (senf::console::detail::ReadlineClientReader::active() && input)
-            return senf::console::detail::ReadlineClientReader::instance().callback(
-                std::string(input) );
+        if (senf::console::detail::ReadlineClientReader::active()) {
+            if (input)
+                return senf::console::detail::ReadlineClientReader::instance().callback(
+                    std::string(input) );
+            else // input == 0 -> EOF (or Ctrl-D)
+                senf::console::detail::ReadlineClientReader::instance().eof();
+        }
     }
 
     ssize_t readline_cookie_write_function(void * cookie, char const * buffer, size_t size)
@@ -100,14 +104,20 @@ namespace {
     void readline_deprep_term()
     {}
 
+    int restart_line(int count, int key)
+    {
+        rl_kill_full_line(count, key);
+        rl_crlf();
+        rl_forced_update_display();
+        return 0;
+    }
+
 }
 
 prefix_ senf::console::detail::ReadlineClientReader::ReadlineClientReader(Client & client)
     : ClientReader(client), ch_ (-1), skipChars_ (0), 
-      schedBinding_ ( client.handle(), 
-                      senf::membind(&ReadlineClientReader::charEvent, this),
-                      Scheduler::EV_READ, 
-                      false ),
+      readevent_ ( "ReadlineClientReader", senf::membind(&ReadlineClientReader::charEvent, this),
+                   client.handle(), Scheduler::EV_READ, false ),
       terminate_ (false)
 {
     if (instance_ != 0)
@@ -129,6 +139,7 @@ prefix_ senf::console::detail::ReadlineClientReader::ReadlineClientReader(Client
     rl_deprep_term_function = &readline_deprep_term;
     rl_getc_function = &readline_getc_function;
     rl_bind_key('\t', &rl_insert);
+    rl_bind_key('\x03', &restart_line);
     using_history();
     
     // Don't ask me, where I found this ...
@@ -137,6 +148,7 @@ prefix_ senf::console::detail::ReadlineClientReader::ReadlineClientReader(Client
                               0xFF, 0xFB, 0x03, // IAC WILL SGA
                               0x00 };
     handle().write(options, options+sizeof(options));
+    handle().write(std::string("(readline support enabled)\r\n"));
 
     strncpy(promptBuffer_, promptString().c_str(), 1024);
     promptBuffer_[1023] = 0;
@@ -144,7 +156,7 @@ prefix_ senf::console::detail::ReadlineClientReader::ReadlineClientReader(Client
 
     _rl_bell_preference = 0; // Set this *after* the config file has been read
 
-    schedBinding_.enable();
+    readevent_.enable();
 }
 
 prefix_ senf::console::detail::ReadlineClientReader::~ReadlineClientReader()
@@ -184,18 +196,18 @@ prefix_ void senf::console::detail::ReadlineClientReader::v_translate(std::strin
     boost::replace_all(data, "\xff", "\xff\xff");
 }
 
-prefix_ void senf::console::detail::ReadlineClientReader::charEvent(Scheduler::EventId event)
+prefix_ void senf::console::detail::ReadlineClientReader::charEvent(int event)
 {
     char ch;
     if (event != Scheduler::EV_READ || handle().read(&ch, &ch+1) <= &ch) {
         stopClient();
         return;
     }
-    ch_ = ch;
+    ch_ = static_cast<unsigned char>(ch);
 
     if (skipChars_ > 0)
         --skipChars_;
-    else if (ch_ == static_cast<char>(0xff))
+    else if (ch_ == 0xff)
         skipChars_ = 2;
     else if (ch_ != 0)
         rl_callback_read_char();