aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Host/Editline.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Host/Editline.h')
-rw-r--r--include/lldb/Host/Editline.h640
1 files changed, 313 insertions, 327 deletions
diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h
index 43c0eccf37dd..f92cbba7f2a0 100644
--- a/include/lldb/Host/Editline.h
+++ b/include/lldb/Host/Editline.h
@@ -7,373 +7,359 @@
//
//===----------------------------------------------------------------------===//
-//TODO: wire up window size changes
+// TODO: wire up window size changes
-// If we ever get a private copy of libedit, there are a number of defects that would be nice to fix;
-// a) Sometimes text just disappears while editing. In an 80-column editor paste the following text, without
+// If we ever get a private copy of libedit, there are a number of defects that
+// would be nice to fix;
+// a) Sometimes text just disappears while editing. In an 80-column editor
+// paste the following text, without
// the quotes:
-// "This is a test of the input system missing Hello, World! Do you disappear when it gets to a particular length?"
-// Now press ^A to move to the start and type 3 characters, and you'll see a good amount of the text will
+// "This is a test of the input system missing Hello, World! Do you
+// disappear when it gets to a particular length?"
+// Now press ^A to move to the start and type 3 characters, and you'll see a
+// good amount of the text will
// disappear. It's still in the buffer, just invisible.
-// b) The prompt printing logic for dealing with ANSI formatting characters is broken, which is why we're
+// b) The prompt printing logic for dealing with ANSI formatting characters is
+// broken, which is why we're
// working around it here.
-// c) When resizing the terminal window, if the cursor moves between rows libedit will get confused.
-// d) The incremental search uses escape to cancel input, so it's confused by ANSI sequences starting with escape.
-// e) Emoji support is fairly terrible, presumably it doesn't understand composed characters?
+// c) When resizing the terminal window, if the cursor moves between rows
+// libedit will get confused.
+// d) The incremental search uses escape to cancel input, so it's confused by
+// ANSI sequences starting with escape.
+// e) Emoji support is fairly terrible, presumably it doesn't understand
+// composed characters?
#ifndef liblldb_Editline_h_
#define liblldb_Editline_h_
#if defined(__cplusplus)
+#include <locale>
#include <sstream>
#include <vector>
-#include <locale>
-// components needed to handle wide characters ( <codecvt>, codecvt_utf8, libedit built with '--enable-widec' )
-// are available on some platforms. The wchar_t versions of libedit functions will only be
-// used in cases where this is true. This is a compile time dependecy, for now selected per target Platform
-#if defined (__APPLE__) || defined(__NetBSD__)
+// components needed to handle wide characters ( <codecvt>, codecvt_utf8,
+// libedit built with '--enable-widec' )
+// are available on some platforms. The wchar_t versions of libedit functions
+// will only be
+// used in cases where this is true. This is a compile time dependecy, for now
+// selected per target Platform
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
#define LLDB_EDITLINE_USE_WCHAR 1
#include <codecvt>
#else
#define LLDB_EDITLINE_USE_WCHAR 0
#endif
-#include "lldb/lldb-private.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/lldb-private.h"
#if defined(_WIN32)
#include "lldb/Host/windows/editlinewin.h"
-#else
-#if !defined(__ANDROID_NDK__)
+#elif !defined(__ANDROID__)
#include <histedit.h>
#endif
-#endif
#include <mutex>
#include <string>
#include <vector>
-#include "lldb/Host/Condition.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Predicate.h"
namespace lldb_private {
- namespace line_editor {
+namespace line_editor {
- // type alias's to help manage 8 bit and wide character versions of libedit
+// type alias's to help manage 8 bit and wide character versions of libedit
#if LLDB_EDITLINE_USE_WCHAR
- using EditLineStringType = std::wstring;
- using EditLineStringStreamType = std::wstringstream;
- using EditLineCharType = wchar_t;
+using EditLineStringType = std::wstring;
+using EditLineStringStreamType = std::wstringstream;
+using EditLineCharType = wchar_t;
#else
- using EditLineStringType=std::string;
- using EditLineStringStreamType = std::stringstream;
- using EditLineCharType = char;
+using EditLineStringType = std::string;
+using EditLineStringStreamType = std::stringstream;
+using EditLineCharType = char;
#endif
- typedef int (* EditlineGetCharCallbackType)(::EditLine * editline, EditLineCharType * c);
- typedef unsigned char (* EditlineCommandCallbackType)(::EditLine * editline, int ch);
- typedef const char * (* EditlinePromptCallbackType)(::EditLine * editline);
-
- class EditlineHistory;
-
- typedef std::shared_ptr<EditlineHistory> EditlineHistorySP;
-
- typedef bool (* IsInputCompleteCallbackType) (
- Editline * editline,
- StringList & lines,
- void * baton);
-
- typedef int (* FixIndentationCallbackType) (
- Editline * editline,
- const StringList & lines,
- int cursor_position,
- void * baton);
-
- typedef int (* CompleteCallbackType) (
- const char * current_line,
- const char * cursor,
- const char * last_char,
- int skip_first_n_matches,
- int max_matches,
- StringList & matches,
- void * baton);
-
- /// Status used to decide when and how to start editing another line in multi-line sessions
- enum class EditorStatus
- {
-
- /// The default state proceeds to edit the current line
- Editing,
-
- /// Editing complete, returns the complete set of edited lines
- Complete,
-
- /// End of input reported
- EndOfInput,
-
- /// Editing interrupted
- Interrupted
- };
-
- /// Established locations that can be easily moved among with MoveCursor
- enum class CursorLocation
- {
- /// The start of the first line in a multi-line edit session
- BlockStart,
-
- /// The start of the current line in a multi-line edit session
- EditingPrompt,
-
- /// The location of the cursor on the current line in a multi-line edit session
- EditingCursor,
-
- /// The location immediately after the last character in a multi-line edit session
- BlockEnd
- };
- }
-
- using namespace line_editor;
-
- /// Instances of Editline provide an abstraction over libedit's EditLine facility. Both
- /// single- and multi-line editing are supported.
- class Editline
- {
- public:
- Editline (const char * editor_name, FILE * input_file, FILE * output_file, FILE * error_file, bool color_prompts);
-
- ~Editline();
-
- /// Uses the user data storage of EditLine to retrieve an associated instance of Editline.
- static Editline *
- InstanceFor (::EditLine * editline);
-
- /// Sets a string to be used as a prompt, or combined with a line number to form a prompt.
- void
- SetPrompt (const char * prompt);
-
- /// Sets an alternate string to be used as a prompt for the second line and beyond in multi-line
- /// editing scenarios.
- void
- SetContinuationPrompt (const char * continuation_prompt);
-
- /// Required to update the width of the terminal registered for I/O. It is critical that this
- /// be correct at all times.
- void
- TerminalSizeChanged();
-
- /// Returns the prompt established by SetPrompt()
- const char *
- GetPrompt();
-
- /// Returns the index of the line currently being edited
- uint32_t
- GetCurrentLine();
-
- /// Interrupt the current edit as if ^C was pressed
- bool
- Interrupt();
-
- /// Cancel this edit and oblitarate all trace of it
- bool
- Cancel();
-
- /// Register a callback for the tab key
- void
- SetAutoCompleteCallback (CompleteCallbackType callback, void * baton);
-
- /// Register a callback for testing whether multi-line input is complete
- void
- SetIsInputCompleteCallback (IsInputCompleteCallbackType callback, void * baton);
-
- /// Register a callback for determining the appropriate indentation for a line
- /// when creating a newline. An optional set of insertable characters can also
- /// trigger the callback.
- bool
- SetFixIndentationCallback (FixIndentationCallbackType callback,
- void * baton,
- const char * indent_chars);
-
- /// Prompts for and reads a single line of user input.
- bool
- GetLine (std::string &line, bool &interrupted);
-
- /// Prompts for and reads a multi-line batch of user input.
- bool
- GetLines (int first_line_number, StringList &lines, bool &interrupted);
-
- void
- PrintAsync (Stream *stream, const char *s, size_t len);
-
- private:
-
- /// Sets the lowest line number for multi-line editing sessions. A value of zero suppresses
- /// line number printing in the prompt.
- void
- SetBaseLineNumber (int line_number);
-
- /// Returns the complete prompt by combining the prompt or continuation prompt with line numbers
- /// as appropriate. The line index is a zero-based index into the current multi-line session.
- std::string
- PromptForIndex (int line_index);
-
- /// Sets the current line index between line edits to allow free movement between lines. Updates
- /// the prompt to match.
- void
- SetCurrentLine (int line_index);
-
- /// Determines the width of the prompt in characters. The width is guaranteed to be the same for
- /// all lines of the current multi-line session.
- int
- GetPromptWidth();
-
- /// Returns true if the underlying EditLine session's keybindings are Emacs-based, or false if
- /// they are VI-based.
- bool
- IsEmacs();
-
- /// Returns true if the current EditLine buffer contains nothing but spaces, or is empty.
- bool
- IsOnlySpaces();
-
- /// Helper method used by MoveCursor to determine relative line position.
- int
- GetLineIndexForLocation (CursorLocation location, int cursor_row);
-
- /// Move the cursor from one well-established location to another using relative line positioning
- /// and absolute column positioning.
- void
- MoveCursor (CursorLocation from, CursorLocation to);
-
- /// Clear from cursor position to bottom of screen and print input lines including prompts, optionally
- /// starting from a specific line. Lines are drawn with an extra space at the end to reserve room for
- /// the rightmost cursor position.
- void
- DisplayInput (int firstIndex = 0);
-
- /// Counts the number of rows a given line of content will end up occupying, taking into account both
- /// the preceding prompt and a single trailing space occupied by a cursor when at the end of the line.
- int
- CountRowsForLine (const EditLineStringType & content);
-
- /// Save the line currently being edited
- void
- SaveEditedLine();
-
- /// Convert the current input lines into a UTF8 StringList
- StringList
- GetInputAsStringList(int line_count = UINT32_MAX);
-
- /// Replaces the current multi-line session with the next entry from history. When the parameter is
- /// true it will take the next earlier entry from history, when it is false it takes the next most
- /// recent.
- unsigned char
- RecallHistory (bool earlier);
-
- /// Character reading implementation for EditLine that supports our multi-line editing trickery.
- int
- GetCharacter (EditLineCharType * c);
-
- /// Prompt implementation for EditLine.
- const char *
- Prompt();
-
- /// Line break command used when meta+return is pressed in multi-line mode.
- unsigned char
- BreakLineCommand (int ch);
-
- /// Command used when return is pressed in multi-line mode.
- unsigned char
- EndOrAddLineCommand(int ch);
-
- /// Delete command used when delete is pressed in multi-line mode.
- unsigned char
- DeleteNextCharCommand (int ch);
-
- /// Delete command used when backspace is pressed in multi-line mode.
- unsigned char
- DeletePreviousCharCommand (int ch);
-
- /// Line navigation command used when ^P or up arrow are pressed in multi-line mode.
- unsigned char
- PreviousLineCommand (int ch);
-
- /// Line navigation command used when ^N or down arrow are pressed in multi-line mode.
- unsigned char
- NextLineCommand (int ch);
-
- /// History navigation command used when Alt + up arrow is pressed in multi-line mode.
- unsigned char
- PreviousHistoryCommand(int ch);
-
- /// History navigation command used when Alt + down arrow is pressed in multi-line mode.
- unsigned char
- NextHistoryCommand(int ch);
-
- /// Buffer start command used when Esc < is typed in multi-line emacs mode.
- unsigned char
- BufferStartCommand (int ch);
-
- /// Buffer end command used when Esc > is typed in multi-line emacs mode.
- unsigned char
- BufferEndCommand (int ch);
-
- /// Context-sensitive tab insertion or code completion command used when the tab key is typed.
- unsigned char
- TabCommand (int ch);
-
- /// Respond to normal character insertion by fixing line indentation
- unsigned char
- FixIndentationCommand (int ch);
-
- /// Revert line command used when moving between lines.
- unsigned char
- RevertLineCommand (int ch);
-
- /// Ensures that the current EditLine instance is properly configured for single or multi-line editing.
- void
- ConfigureEditor (bool multiline);
-
- private:
+typedef int (*EditlineGetCharCallbackType)(::EditLine *editline,
+ EditLineCharType *c);
+typedef unsigned char (*EditlineCommandCallbackType)(::EditLine *editline,
+ int ch);
+typedef const char *(*EditlinePromptCallbackType)(::EditLine *editline);
+
+class EditlineHistory;
+
+typedef std::shared_ptr<EditlineHistory> EditlineHistorySP;
+
+typedef bool (*IsInputCompleteCallbackType)(Editline *editline,
+ StringList &lines, void *baton);
+
+typedef int (*FixIndentationCallbackType)(Editline *editline,
+ const StringList &lines,
+ int cursor_position, void *baton);
+
+typedef int (*CompleteCallbackType)(const char *current_line,
+ const char *cursor, const char *last_char,
+ int skip_first_n_matches, int max_matches,
+ StringList &matches, void *baton);
+
+/// Status used to decide when and how to start editing another line in
+/// multi-line sessions
+enum class EditorStatus {
+
+ /// The default state proceeds to edit the current line
+ Editing,
+
+ /// Editing complete, returns the complete set of edited lines
+ Complete,
+
+ /// End of input reported
+ EndOfInput,
+
+ /// Editing interrupted
+ Interrupted
+};
+
+/// Established locations that can be easily moved among with MoveCursor
+enum class CursorLocation {
+ /// The start of the first line in a multi-line edit session
+ BlockStart,
+
+ /// The start of the current line in a multi-line edit session
+ EditingPrompt,
+
+ /// The location of the cursor on the current line in a multi-line edit
+ /// session
+ EditingCursor,
+
+ /// The location immediately after the last character in a multi-line edit
+ /// session
+ BlockEnd
+};
+}
+
+using namespace line_editor;
+
+/// Instances of Editline provide an abstraction over libedit's EditLine
+/// facility. Both
+/// single- and multi-line editing are supported.
+class Editline {
+public:
+ Editline(const char *editor_name, FILE *input_file, FILE *output_file,
+ FILE *error_file, bool color_prompts);
+
+ ~Editline();
+
+ /// Uses the user data storage of EditLine to retrieve an associated instance
+ /// of Editline.
+ static Editline *InstanceFor(::EditLine *editline);
+
+ /// Sets a string to be used as a prompt, or combined with a line number to
+ /// form a prompt.
+ void SetPrompt(const char *prompt);
+
+ /// Sets an alternate string to be used as a prompt for the second line and
+ /// beyond in multi-line
+ /// editing scenarios.
+ void SetContinuationPrompt(const char *continuation_prompt);
+
+ /// Required to update the width of the terminal registered for I/O. It is
+ /// critical that this
+ /// be correct at all times.
+ void TerminalSizeChanged();
+
+ /// Returns the prompt established by SetPrompt()
+ const char *GetPrompt();
+
+ /// Returns the index of the line currently being edited
+ uint32_t GetCurrentLine();
+
+ /// Interrupt the current edit as if ^C was pressed
+ bool Interrupt();
+
+ /// Cancel this edit and oblitarate all trace of it
+ bool Cancel();
+
+ /// Register a callback for the tab key
+ void SetAutoCompleteCallback(CompleteCallbackType callback, void *baton);
+
+ /// Register a callback for testing whether multi-line input is complete
+ void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback,
+ void *baton);
+
+ /// Register a callback for determining the appropriate indentation for a line
+ /// when creating a newline. An optional set of insertable characters can
+ /// also
+ /// trigger the callback.
+ bool SetFixIndentationCallback(FixIndentationCallbackType callback,
+ void *baton, const char *indent_chars);
+
+ /// Prompts for and reads a single line of user input.
+ bool GetLine(std::string &line, bool &interrupted);
+
+ /// Prompts for and reads a multi-line batch of user input.
+ bool GetLines(int first_line_number, StringList &lines, bool &interrupted);
+
+ void PrintAsync(Stream *stream, const char *s, size_t len);
+
+private:
+ /// Sets the lowest line number for multi-line editing sessions. A value of
+ /// zero suppresses
+ /// line number printing in the prompt.
+ void SetBaseLineNumber(int line_number);
+
+ /// Returns the complete prompt by combining the prompt or continuation prompt
+ /// with line numbers
+ /// as appropriate. The line index is a zero-based index into the current
+ /// multi-line session.
+ std::string PromptForIndex(int line_index);
+
+ /// Sets the current line index between line edits to allow free movement
+ /// between lines. Updates
+ /// the prompt to match.
+ void SetCurrentLine(int line_index);
+
+ /// Determines the width of the prompt in characters. The width is guaranteed
+ /// to be the same for
+ /// all lines of the current multi-line session.
+ int GetPromptWidth();
+
+ /// Returns true if the underlying EditLine session's keybindings are
+ /// Emacs-based, or false if
+ /// they are VI-based.
+ bool IsEmacs();
+
+ /// Returns true if the current EditLine buffer contains nothing but spaces,
+ /// or is empty.
+ bool IsOnlySpaces();
+
+ /// Helper method used by MoveCursor to determine relative line position.
+ int GetLineIndexForLocation(CursorLocation location, int cursor_row);
+
+ /// Move the cursor from one well-established location to another using
+ /// relative line positioning
+ /// and absolute column positioning.
+ void MoveCursor(CursorLocation from, CursorLocation to);
+
+ /// Clear from cursor position to bottom of screen and print input lines
+ /// including prompts, optionally
+ /// starting from a specific line. Lines are drawn with an extra space at the
+ /// end to reserve room for
+ /// the rightmost cursor position.
+ void DisplayInput(int firstIndex = 0);
+
+ /// Counts the number of rows a given line of content will end up occupying,
+ /// taking into account both
+ /// the preceding prompt and a single trailing space occupied by a cursor when
+ /// at the end of the line.
+ int CountRowsForLine(const EditLineStringType &content);
+
+ /// Save the line currently being edited
+ void SaveEditedLine();
+
+ /// Convert the current input lines into a UTF8 StringList
+ StringList GetInputAsStringList(int line_count = UINT32_MAX);
+
+ /// Replaces the current multi-line session with the next entry from history.
+ /// When the parameter is
+ /// true it will take the next earlier entry from history, when it is false it
+ /// takes the next most
+ /// recent.
+ unsigned char RecallHistory(bool earlier);
+
+ /// Character reading implementation for EditLine that supports our multi-line
+ /// editing trickery.
+ int GetCharacter(EditLineCharType *c);
+
+ /// Prompt implementation for EditLine.
+ const char *Prompt();
+
+ /// Line break command used when meta+return is pressed in multi-line mode.
+ unsigned char BreakLineCommand(int ch);
+
+ /// Command used when return is pressed in multi-line mode.
+ unsigned char EndOrAddLineCommand(int ch);
+
+ /// Delete command used when delete is pressed in multi-line mode.
+ unsigned char DeleteNextCharCommand(int ch);
+
+ /// Delete command used when backspace is pressed in multi-line mode.
+ unsigned char DeletePreviousCharCommand(int ch);
+
+ /// Line navigation command used when ^P or up arrow are pressed in multi-line
+ /// mode.
+ unsigned char PreviousLineCommand(int ch);
+
+ /// Line navigation command used when ^N or down arrow are pressed in
+ /// multi-line mode.
+ unsigned char NextLineCommand(int ch);
+
+ /// History navigation command used when Alt + up arrow is pressed in
+ /// multi-line mode.
+ unsigned char PreviousHistoryCommand(int ch);
+
+ /// History navigation command used when Alt + down arrow is pressed in
+ /// multi-line mode.
+ unsigned char NextHistoryCommand(int ch);
+
+ /// Buffer start command used when Esc < is typed in multi-line emacs mode.
+ unsigned char BufferStartCommand(int ch);
+
+ /// Buffer end command used when Esc > is typed in multi-line emacs mode.
+ unsigned char BufferEndCommand(int ch);
+
+ /// Context-sensitive tab insertion or code completion command used when the
+ /// tab key is typed.
+ unsigned char TabCommand(int ch);
+
+ /// Respond to normal character insertion by fixing line indentation
+ unsigned char FixIndentationCommand(int ch);
+
+ /// Revert line command used when moving between lines.
+ unsigned char RevertLineCommand(int ch);
+
+ /// Ensures that the current EditLine instance is properly configured for
+ /// single or multi-line editing.
+ void ConfigureEditor(bool multiline);
+
+private:
#if LLDB_EDITLINE_USE_WCHAR
- std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv;
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv;
#endif
- ::EditLine * m_editline = nullptr;
- EditlineHistorySP m_history_sp;
- bool m_in_history = false;
- std::vector<EditLineStringType> m_live_history_lines;
- bool m_multiline_enabled = false;
- std::vector<EditLineStringType> m_input_lines;
- EditorStatus m_editor_status;
- bool m_color_prompts = true;
- int m_terminal_width = 0;
- int m_base_line_number = 0;
- unsigned m_current_line_index = 0;
- int m_current_line_rows = -1;
- int m_revert_cursor_index = 0;
- int m_line_number_digits = 3;
- std::string m_set_prompt;
- std::string m_set_continuation_prompt;
- std::string m_current_prompt;
- bool m_needs_prompt_repaint = false;
- std::string m_editor_name;
- FILE * m_input_file;
- FILE * m_output_file;
- FILE * m_error_file;
- ConnectionFileDescriptor m_input_connection;
- IsInputCompleteCallbackType m_is_input_complete_callback = nullptr;
- void * m_is_input_complete_callback_baton = nullptr;
- FixIndentationCallbackType m_fix_indentation_callback = nullptr;
- void * m_fix_indentation_callback_baton = nullptr;
- const char * m_fix_indentation_callback_chars = nullptr;
- CompleteCallbackType m_completion_callback = nullptr;
- void * m_completion_callback_baton = nullptr;
-
- std::mutex m_output_mutex;
- };
+ ::EditLine *m_editline = nullptr;
+ EditlineHistorySP m_history_sp;
+ bool m_in_history = false;
+ std::vector<EditLineStringType> m_live_history_lines;
+ bool m_multiline_enabled = false;
+ std::vector<EditLineStringType> m_input_lines;
+ EditorStatus m_editor_status;
+ bool m_color_prompts = true;
+ int m_terminal_width = 0;
+ int m_base_line_number = 0;
+ unsigned m_current_line_index = 0;
+ int m_current_line_rows = -1;
+ int m_revert_cursor_index = 0;
+ int m_line_number_digits = 3;
+ std::string m_set_prompt;
+ std::string m_set_continuation_prompt;
+ std::string m_current_prompt;
+ bool m_needs_prompt_repaint = false;
+ std::string m_editor_name;
+ FILE *m_input_file;
+ FILE *m_output_file;
+ FILE *m_error_file;
+ ConnectionFileDescriptor m_input_connection;
+ IsInputCompleteCallbackType m_is_input_complete_callback = nullptr;
+ void *m_is_input_complete_callback_baton = nullptr;
+ FixIndentationCallbackType m_fix_indentation_callback = nullptr;
+ void *m_fix_indentation_callback_baton = nullptr;
+ const char *m_fix_indentation_callback_chars = nullptr;
+ CompleteCallbackType m_completion_callback = nullptr;
+ void *m_completion_callback_baton = nullptr;
+
+ std::mutex m_output_mutex;
+};
}
-#endif // #if defined(__cplusplus)
-#endif // liblldb_Editline_h_
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Editline_h_