2 #include <readline/readline.h> 3 #include <readline/history.h> 5 #include <boost/thread/mutex.hpp> 6 #include <boost/thread/lock_guard.hpp> 7 #include <boost/algorithm/string.hpp> 9 static void install_line_handler();
10 static void remove_line_handler();
12 static boost::mutex sync_mutex;
14 static char *the_line;
22 : m_buffer(NULL), m_restart(
false)
40 std::vector<std::string>& rdln::readline_buffer::completion_commands()
42 static std::vector<std::string> commands = {
"exit"};
47 :
std::stringbuf(), m_cout_buf(NULL), m_prompt_length(0)
54 if(m_cout_buf != NULL)
56 m_cout_buf = std::cout.rdbuf();
57 std::cout.rdbuf(
this);
58 install_line_handler();
63 if(m_cout_buf == NULL)
65 std::cout.rdbuf(m_cout_buf);
67 remove_line_handler();
72 boost::lock_guard<boost::mutex> lock(sync_mutex);
74 rl_callback_read_char();
86 if(m_cout_buf == NULL)
88 boost::lock_guard<boost::mutex> lock(sync_mutex);
89 rl_set_prompt(
std::string(m_prompt_length,
' ').c_str());
91 rl_set_prompt(prompt.c_str());
93 m_prompt_length = prompt.size();
98 if(std::find(completion_commands().begin(), completion_commands().end(), command) != completion_commands().end())
100 completion_commands().push_back(command);
105 return completion_commands();
110 boost::lock_guard<boost::mutex> lock(sync_mutex);
111 #if RL_READLINE_VERSION < 0x0700 112 char lbuf[2] = {0,0};
114 int end = 0, point = 0;
117 if (rl_end || (rl_prompt && *rl_prompt))
119 #if RL_READLINE_VERSION >= 0x0700 120 rl_clear_visible_line();
122 line = rl_line_buffer;
125 rl_line_buffer = lbuf;
135 m_cout_buf->sputc( this->sgetc() );
137 while ( this->snextc() != EOF );
139 #if RL_READLINE_VERSION < 0x0700 140 if (end || (rl_prompt && *rl_prompt))
143 rl_line_buffer = line;
154 static void handle_line(
char* line)
163 if(!test_line.empty())
165 add_history(test_line.c_str());
166 history_set_pos(history_length);
167 if (test_line ==
"exit" || test_line ==
"q")
182 static char* completion_matches(
const char* text,
int state)
184 static size_t list_index;
194 for(; list_index<completions.size(); )
196 const std::string& cmd = completions[list_index++];
197 if(cmd.compare(0, len, text) == 0)
199 return strdup(cmd.c_str());
206 static char** attempted_completion(
const char* text,
int start,
int end)
208 rl_attempted_completion_over = 1;
209 return rl_completion_matches(text, completion_matches);
212 static void install_line_handler()
214 rl_attempted_completion_function = attempted_completion;
215 rl_callback_handler_install(
"", handle_line);
219 static void remove_line_handler()
221 rl_replace_line(
"", 0);
224 rl_callback_handler_remove();
static void add_completion(const std::string &command)
void set_prompt(const std::string &prompt)
static const std::vector< std::string > & get_completions()
linestatus get_line(std::string &line) const