1 //===-- Editline.cpp --------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "lldb/Host/Editline.h"
13 #include "lldb/Core/Error.h"
14 #include "lldb/Core/StreamString.h"
15 #include "lldb/Core/StringList.h"
16 #include "lldb/Host/Host.h"
21 using namespace lldb_private;
23 static const char k_prompt_escape_char = '\1';
25 Editline::Editline (const char *prog, // prog can't be NULL
26 const char *prompt, // can be NULL for no prompt
37 m_getc_mutex (Mutex::eMutexTypeNormal),
39 // m_gets_mutex (Mutex::eMutexTypeNormal),
40 m_completion_callback (NULL),
41 m_completion_callback_baton (NULL),
42 m_line_complete_callback (NULL),
43 m_line_complete_callback_baton (NULL),
44 m_lines_command (Command::None),
45 m_lines_curr_line (0),
47 m_prompt_with_line_numbers (false),
48 m_getting_line (false),
55 m_editline = ::el_init(prog, fin, fout, ferr);
56 m_history = ::history_init();
60 m_editline = ::el_init("lldb-tmp", fin, fout, ferr);
62 if (prompt && prompt[0])
65 //::el_set (m_editline, EL_BIND, "^[[A", NULL); // Print binding for up arrow key
66 //::el_set (m_editline, EL_BIND, "^[[B", NULL); // Print binding for up down key
69 ::el_set (m_editline, EL_CLIENTDATA, this);
71 // only defined for newer versions of editline
73 ::el_set (m_editline, EL_PROMPT_ESC, GetPromptCallback, k_prompt_escape_char);
75 // fall back on old prompt setting code
76 ::el_set (m_editline, EL_PROMPT, GetPromptCallback);
78 ::el_set (m_editline, EL_EDITOR, "emacs");
81 ::el_set (m_editline, EL_HIST, history, m_history);
83 ::el_set (m_editline, EL_ADDFN, "lldb-complete", "Editline completion function", Editline::CallbackComplete);
84 ::el_set (m_editline, EL_ADDFN, "lldb-edit-prev-line", "Editline edit prev line", Editline::CallbackEditPrevLine);
85 ::el_set (m_editline, EL_ADDFN, "lldb-edit-next-line", "Editline edit next line", Editline::CallbackEditNextLine);
87 ::el_set (m_editline, EL_BIND, "^r", "em-inc-search-prev", NULL); // Cycle through backwards search, entering string
88 ::el_set (m_editline, EL_BIND, "^w", "ed-delete-prev-word", NULL); // Delete previous word, behave like bash does.
89 ::el_set (m_editline, EL_BIND, "\033[3~", "ed-delete-next-char", NULL); // Fix the delete key.
90 ::el_set (m_editline, EL_BIND, "\t", "lldb-complete", NULL); // Bind TAB to be autocompelte
92 // Source $PWD/.editrc then $HOME/.editrc
93 ::el_source (m_editline, NULL);
97 ::history (m_history, &m_history_event, H_SETSIZE, 800);
98 ::history (m_history, &m_history_event, H_SETUNIQUE, 1);
101 // Always read through our callback function so we don't read
102 // stuff we aren't supposed to. This also stops the extra echoing
103 // that can happen when you have more input than editline can handle
105 SetGetCharCallback(GetCharFromInputFileCallback);
110 Editline::~Editline()
116 ::history_end (m_history);
120 // Disable edit mode to stop the terminal from flushing all input
121 // during the call to el_end() since we expect to have multiple editline
122 // instances in this program.
123 ::el_set (m_editline, EL_EDITMODE, 0);
125 ::el_end(m_editline);
130 Editline::SetGetCharCallback (GetCharCallbackType callback)
132 ::el_set (m_editline, EL_GETCFN, callback);
136 Editline::GetHistoryFile()
138 char history_path[PATH_MAX];
139 ::snprintf (history_path, sizeof(history_path), "~/.%s-history", m_program.c_str());
140 return FileSpec(history_path, true);
144 Editline::LoadHistory ()
148 FileSpec history_file(GetHistoryFile());
149 if (history_file.Exists())
150 ::history (m_history, &m_history_event, H_LOAD, history_file.GetPath().c_str());
157 Editline::SaveHistory ()
161 std::string history_path = GetHistoryFile().GetPath();
162 ::history (m_history, &m_history_event, H_SAVE, history_path.c_str());
170 Editline::PrivateGetLine(std::string &line)
175 error.SetErrorString("interrupted");
180 if (m_editline != NULL)
183 const char *line_cstr = NULL;
184 // Call el_gets to prompt the user and read the user's input.
186 // // Make sure we know when we are in el_gets() by using a mutex
187 // Mutex::Locker locker (m_gets_mutex);
188 line_cstr = ::el_gets (m_editline, &line_len);
191 static int save_errno = (line_len < 0) ? errno : 0;
195 error.SetError(save_errno, eErrorTypePOSIX);
199 // Decrement the length so we don't have newline characters in "line" for when
200 // we assign the cstr into the std::string
201 while (line_len > 0 &&
202 (line_cstr[line_len - 1] == '\n' ||
203 line_cstr[line_len - 1] == '\r'))
208 // We didn't strip the newlines, we just adjusted the length, and
209 // we want to add the history item with the newlines
211 ::history (m_history, &m_history_event, H_ENTER, line_cstr);
213 // Copy the part of the c string that we want (removing the newline chars)
214 line.assign(line_cstr, line_len);
220 error.SetErrorString("the EditLine instance has been deleted");
227 Editline::GetLine(std::string &line)
232 // Set arrow key bindings for up and down arrows for single line
233 // mode where up and down arrows do prev/next history
234 ::el_set (m_editline, EL_BIND, "^[[A", "ed-prev-history", NULL); // Map up arrow
235 ::el_set (m_editline, EL_BIND, "^[[B", "ed-next-history", NULL); // Map down arrow
236 m_interrupted = false;
242 error.SetErrorString("already getting a line");
245 if (m_lines_curr_line > 0)
247 error.SetErrorString("already getting lines");
250 m_getting_line = true;
251 error = PrivateGetLine(line);
252 m_getting_line = false;
255 if (m_got_eof && line.empty())
257 // Only set the error if we didn't get an error back from PrivateGetLine()
259 error.SetErrorString("end of file");
266 Editline::Push (const char *bytes, size_t len)
270 // Must NULL terminate the string for el_push() so we stick it
271 // into a std::string first
272 ::el_push(m_editline,
273 const_cast<char*>(std::string (bytes, len).c_str()));
281 Editline::GetLines(const std::string &end_line, StringList &lines)
286 error.SetErrorString("already getting a line");
289 if (m_lines_curr_line > 0)
291 error.SetErrorString("already getting lines");
295 // Set arrow key bindings for up and down arrows for multiple line
296 // mode where up and down arrows do edit prev/next line
297 ::el_set (m_editline, EL_BIND, "^[[A", "lldb-edit-prev-line", NULL); // Map up arrow
298 ::el_set (m_editline, EL_BIND, "^[[B", "lldb-edit-next-line", NULL); // Map down arrow
299 ::el_set (m_editline, EL_BIND, "^b", "ed-prev-history", NULL);
300 ::el_set (m_editline, EL_BIND, "^n", "ed-next-history", NULL);
301 m_interrupted = false;
303 LineStatus line_status = LineStatus::Success;
307 FILE *out_file = GetOutputFile();
308 FILE *err_file = GetErrorFile();
309 m_lines_curr_line = 1;
310 while (line_status != LineStatus::Done)
312 const uint32_t line_idx = m_lines_curr_line-1;
313 if (line_idx >= lines.GetSize())
314 lines.SetSize(m_lines_curr_line);
315 m_lines_max_line = lines.GetSize();
316 m_lines_command = Command::None;
317 assert(line_idx < m_lines_max_line);
318 std::string &line = lines[line_idx];
319 error = PrivateGetLine(line);
322 line_status = LineStatus::Error;
326 switch (m_lines_command)
329 if (m_line_complete_callback)
331 line_status = m_line_complete_callback (this,
335 m_line_complete_callback_baton);
337 else if (line == end_line)
339 line_status = LineStatus::Done;
342 if (line_status == LineStatus::Success)
345 // If we already have content for the next line because
346 // we were editing previous lines, then populate the line
347 // with the appropriate contents
348 if (line_idx+1 < lines.GetSize() && !lines[line_idx+1].empty())
349 ::el_push (m_editline,
350 const_cast<char*>(lines[line_idx+1].c_str()));
352 else if (line_status == LineStatus::Error)
354 // Clear to end of line ("ESC[K"), then print the error,
355 // then go to the next line ("\n") and then move cursor up
356 // two lines ("ESC[2A").
357 fprintf (err_file, "\033[Kerror: %s\n\033[2A", error.AsCString());
360 case Command::EditPrevLine:
361 if (m_lines_curr_line > 1)
363 //::fprintf (out_file, "\033[1A\033[%uD\033[2K", (uint32_t)(m_lines_prompt.size() + lines[line_idx].size())); // Make cursor go up a line and clear that line
364 ::fprintf (out_file, "\033[1A\033[1000D\033[2K");
365 if (!lines[line_idx-1].empty())
366 ::el_push (m_editline,
367 const_cast<char*>(lines[line_idx-1].c_str()));
371 case Command::EditNextLine:
372 // Allow the down arrow to create a new line
374 //::fprintf (out_file, "\033[1B\033[%uD\033[2K", (uint32_t)(m_lines_prompt.size() + lines[line_idx].size()));
375 ::fprintf (out_file, "\033[1B\033[1000D\033[2K");
376 if (line_idx+1 < lines.GetSize() && !lines[line_idx+1].empty())
377 ::el_push (m_editline,
378 const_cast<char*>(lines[line_idx+1].c_str()));
383 m_lines_curr_line = 0;
384 m_lines_command = Command::None;
386 // If we have a callback, call it one more time to let the
387 // user know the lines are complete
388 if (m_line_complete_callback)
389 m_line_complete_callback (this,
393 m_line_complete_callback_baton);
399 Editline::HandleCompletion (int ch)
401 if (m_completion_callback == NULL)
404 const LineInfo *line_info = ::el_line(m_editline);
405 StringList completions;
408 const int num_completions = m_completion_callback (line_info->buffer,
411 0, // Don't skip any matches (start at match zero)
412 -1, // Get all the matches
414 m_completion_callback_baton);
416 FILE *out_file = GetOutputFile();
418 // if (num_completions == -1)
420 // ::el_insertstr (m_editline, m_completion_key);
421 // return CC_REDISPLAY;
424 if (num_completions == -2)
426 // Replace the entire line with the first string...
427 ::el_deletestr (m_editline, line_info->cursor - line_info->buffer);
428 ::el_insertstr (m_editline, completions.GetStringAtIndex(0));
432 // If we get a longer match display that first.
433 const char *completion_str = completions.GetStringAtIndex(0);
434 if (completion_str != NULL && *completion_str != '\0')
436 el_insertstr (m_editline, completion_str);
440 if (num_completions > 1)
442 int num_elements = num_completions + 1;
443 ::fprintf (out_file, "\nAvailable completions:");
444 if (num_completions < page_size)
446 for (int i = 1; i < num_elements; i++)
448 completion_str = completions.GetStringAtIndex(i);
449 ::fprintf (out_file, "\n\t%s", completion_str);
451 ::fprintf (out_file, "\n");
458 while (cur_pos < num_elements)
460 int endpoint = cur_pos + page_size;
461 if (endpoint > num_elements)
462 endpoint = num_elements;
463 for (; cur_pos < endpoint; cur_pos++)
465 completion_str = completions.GetStringAtIndex(cur_pos);
466 ::fprintf (out_file, "\n\t%s", completion_str);
469 if (cur_pos >= num_elements)
471 ::fprintf (out_file, "\n");
475 ::fprintf (out_file, "\nMore (Y/n/a): ");
477 got_char = el_getc(m_editline, &reply);
478 if (got_char == -1 || reply == 'n')
481 page_size = num_elements - cur_pos;
487 if (num_completions == 0)
488 return CC_REFRESH_BEEP;
494 Editline::GetClientData (::EditLine *e)
496 Editline *editline = NULL;
497 if (e && ::el_get(e, EL_CLIENTDATA, &editline) == 0)
503 Editline::GetInputFile ()
505 return GetFilePointer (m_editline, 0);
509 Editline::GetOutputFile ()
511 return GetFilePointer (m_editline, 1);
515 Editline::GetErrorFile ()
517 return GetFilePointer (m_editline, 2);
521 Editline::GetPrompt()
523 if (m_prompt_with_line_numbers && m_lines_curr_line > 0)
526 strm.Printf("%3u: ", m_lines_curr_line);
527 m_lines_prompt = std::move(strm.GetString());
528 return m_lines_prompt.c_str();
532 return m_prompt.c_str();
537 Editline::SetPrompt (const char *p)
543 size_t start_pos = 0;
545 while ((escape_pos = m_prompt.find('\033', start_pos)) != std::string::npos)
547 m_prompt.insert(escape_pos, 1, k_prompt_escape_char);
553 Editline::GetFilePointer (::EditLine *e, int fd)
555 FILE *file_ptr = NULL;
556 if (e && ::el_get(e, EL_GETFP, fd, &file_ptr) == 0)
562 Editline::CallbackEditPrevLine (::EditLine *e, int ch)
564 Editline *editline = GetClientData (e);
565 if (editline->m_lines_curr_line > 1)
567 editline->m_lines_command = Command::EditPrevLine;
573 Editline::CallbackEditNextLine (::EditLine *e, int ch)
575 Editline *editline = GetClientData (e);
576 if (editline->m_lines_curr_line < editline->m_lines_max_line)
578 editline->m_lines_command = Command::EditNextLine;
585 Editline::CallbackComplete (::EditLine *e, int ch)
587 Editline *editline = GetClientData (e);
589 return editline->HandleCompletion (ch);
594 Editline::GetPromptCallback (::EditLine *e)
596 Editline *editline = GetClientData (e);
598 return editline->GetPrompt();
603 Editline::SetInputBuffer (const char *c, size_t len)
607 Mutex::Locker locker(m_getc_mutex);
608 SetGetCharCallback(GetCharInputBufferCallback);
609 m_getc_buffer.append(c, len);
610 m_getc_cond.Broadcast();
616 Editline::GetChar (char *c)
618 Mutex::Locker locker(m_getc_mutex);
619 if (m_getc_buffer.empty())
620 m_getc_cond.Wait(m_getc_mutex);
621 if (m_getc_buffer.empty())
623 *c = m_getc_buffer[0];
624 m_getc_buffer.erase(0,1);
629 Editline::GetCharInputBufferCallback (EditLine *e, char *c)
631 Editline *editline = GetClientData (e);
633 return editline->GetChar(c);
638 Editline::GetCharFromInputFileCallback (EditLine *e, char *c)
640 Editline *editline = GetClientData (e);
641 if (editline && editline->m_got_eof == false)
643 char ch = ::fgetc(editline->GetInputFile());
646 // Only turn a CTRL+D into a EOF if we receive the
647 // CTRL+D an empty line, otherwise it will forward
648 // delete the character at the cursor
649 const LineInfo *line_info = ::el_line(e);
650 if (line_info != NULL &&
651 line_info->buffer == line_info->cursor &&
652 line_info->cursor == line_info->lastchar)
660 editline->m_got_eof = true;
674 FILE *out_file = GetOutputFile();
677 const LineInfo *line_info = ::el_line(m_editline);
679 ::fprintf (out_file, "\033[%uD\033[K", (uint32_t)(strlen(GetPrompt()) + line_info->cursor - line_info->buffer));
687 ::el_set (m_editline, EL_REFRESH);
691 Editline::Interrupt ()
693 m_interrupted = true;
694 if (m_getting_line || m_lines_curr_line > 0)
695 el_insertstr(m_editline, "\n"); // True to force the line to complete itself so we get exit from el_gets()