File indexing completed on 2026-05-10 08:42:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef LLDB_HOST_EDITLINE_H
0029 #define LLDB_HOST_EDITLINE_H
0030
0031 #include "lldb/Host/Config.h"
0032
0033 #include <locale>
0034 #include <sstream>
0035 #include <vector>
0036
0037 #include "lldb/lldb-private.h"
0038
0039 #if !defined(_WIN32) && !defined(__ANDROID__)
0040 #include <histedit.h>
0041 #endif
0042
0043 #include <csignal>
0044 #include <mutex>
0045 #include <optional>
0046 #include <string>
0047 #include <vector>
0048
0049 #include "lldb/Host/ConnectionFileDescriptor.h"
0050 #include "lldb/Utility/CompletionRequest.h"
0051 #include "lldb/Utility/FileSpec.h"
0052 #include "lldb/Utility/Predicate.h"
0053 #include "lldb/Utility/StringList.h"
0054
0055 #include "llvm/ADT/FunctionExtras.h"
0056
0057 namespace lldb_private {
0058 namespace line_editor {
0059
0060
0061 #if LLDB_EDITLINE_USE_WCHAR
0062 using EditLineStringType = std::wstring;
0063 using EditLineStringStreamType = std::wstringstream;
0064 using EditLineCharType = wchar_t;
0065 #else
0066 using EditLineStringType = std::string;
0067 using EditLineStringStreamType = std::stringstream;
0068 using EditLineCharType = char;
0069 #endif
0070
0071
0072
0073
0074
0075
0076
0077 #if LLDB_EDITLINE_USE_WCHAR || defined(EL_CLIENTDATA) || LLDB_HAVE_EL_RFUNC_T
0078 using EditLineGetCharType = wchar_t;
0079 #else
0080 using EditLineGetCharType = char;
0081 #endif
0082
0083 using EditlineGetCharCallbackType = int (*)(::EditLine *editline,
0084 EditLineGetCharType *c);
0085 using EditlineCommandCallbackType = unsigned char (*)(::EditLine *editline,
0086 int ch);
0087 using EditlinePromptCallbackType = const char *(*)(::EditLine *editline);
0088
0089 class EditlineHistory;
0090
0091 using EditlineHistorySP = std::shared_ptr<EditlineHistory>;
0092
0093 using IsInputCompleteCallbackType =
0094 llvm::unique_function<bool(Editline *, StringList &)>;
0095
0096 using FixIndentationCallbackType =
0097 llvm::unique_function<int(Editline *, StringList &, int)>;
0098
0099 using SuggestionCallbackType =
0100 llvm::unique_function<std::optional<std::string>(llvm::StringRef)>;
0101
0102 using CompleteCallbackType = llvm::unique_function<void(CompletionRequest &)>;
0103
0104
0105
0106 enum class EditorStatus {
0107
0108
0109 Editing,
0110
0111
0112 Complete,
0113
0114
0115 EndOfInput,
0116
0117
0118 Interrupted
0119 };
0120
0121
0122 enum class CursorLocation {
0123
0124 BlockStart,
0125
0126
0127 EditingPrompt,
0128
0129
0130
0131 EditingCursor,
0132
0133
0134
0135 BlockEnd
0136 };
0137
0138
0139 enum class HistoryOperation {
0140 Oldest,
0141 Older,
0142 Current,
0143 Newer,
0144 Newest
0145 };
0146 }
0147
0148 using namespace line_editor;
0149
0150
0151
0152 class Editline {
0153 public:
0154 Editline(const char *editor_name, FILE *input_file, FILE *output_file,
0155 FILE *error_file, bool color, std::recursive_mutex &output_mutex);
0156
0157 ~Editline();
0158
0159
0160
0161 static Editline *InstanceFor(::EditLine *editline);
0162
0163 static void
0164 DisplayCompletions(Editline &editline,
0165 llvm::ArrayRef<CompletionResult::Completion> results);
0166
0167
0168
0169 void SetPrompt(const char *prompt);
0170
0171
0172
0173 void SetContinuationPrompt(const char *continuation_prompt);
0174
0175
0176 void TerminalSizeChanged();
0177
0178
0179 const char *GetPrompt();
0180
0181
0182 uint32_t GetCurrentLine();
0183
0184
0185 bool Interrupt();
0186
0187
0188 bool Cancel();
0189
0190
0191 void SetSuggestionCallback(SuggestionCallbackType callback) {
0192 m_suggestion_callback = std::move(callback);
0193 }
0194
0195
0196 void SetAutoCompleteCallback(CompleteCallbackType callback) {
0197 m_completion_callback = std::move(callback);
0198 }
0199
0200
0201 void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback) {
0202 m_is_input_complete_callback = std::move(callback);
0203 }
0204
0205
0206
0207
0208 void SetFixIndentationCallback(FixIndentationCallbackType callback,
0209 const char *indent_chars) {
0210 m_fix_indentation_callback = std::move(callback);
0211 m_fix_indentation_callback_chars = indent_chars;
0212 }
0213
0214 void SetPromptAnsiPrefix(std::string prefix) {
0215 if (m_color)
0216 m_prompt_ansi_prefix = std::move(prefix);
0217 }
0218
0219 void SetPromptAnsiSuffix(std::string suffix) {
0220 if (m_color)
0221 m_prompt_ansi_suffix = std::move(suffix);
0222 }
0223
0224 void SetSuggestionAnsiPrefix(std::string prefix) {
0225 if (m_color)
0226 m_suggestion_ansi_prefix = std::move(prefix);
0227 }
0228
0229 void SetSuggestionAnsiSuffix(std::string suffix) {
0230 if (m_color)
0231 m_suggestion_ansi_suffix = std::move(suffix);
0232 }
0233
0234
0235 bool GetLine(std::string &line, bool &interrupted);
0236
0237
0238 bool GetLines(int first_line_number, StringList &lines, bool &interrupted);
0239
0240 void PrintAsync(Stream *stream, const char *s, size_t len);
0241
0242
0243 StringList GetInputAsStringList(int line_count = UINT32_MAX);
0244
0245 size_t GetTerminalWidth() { return m_terminal_width; }
0246
0247 size_t GetTerminalHeight() { return m_terminal_height; }
0248
0249 private:
0250
0251
0252 void SetBaseLineNumber(int line_number);
0253
0254
0255
0256
0257 std::string PromptForIndex(int line_index);
0258
0259
0260
0261 void SetCurrentLine(int line_index);
0262
0263
0264
0265 size_t GetPromptWidth();
0266
0267
0268
0269 bool IsEmacs();
0270
0271
0272
0273 bool IsOnlySpaces();
0274
0275
0276 int GetLineIndexForLocation(CursorLocation location, int cursor_row);
0277
0278
0279
0280 void MoveCursor(CursorLocation from, CursorLocation to);
0281
0282
0283
0284
0285
0286 void DisplayInput(int firstIndex = 0);
0287
0288
0289
0290
0291 int CountRowsForLine(const EditLineStringType &content);
0292
0293
0294 void SaveEditedLine();
0295
0296
0297 unsigned char RecallHistory(HistoryOperation op);
0298
0299
0300
0301 int GetCharacter(EditLineGetCharType *c);
0302
0303
0304 const char *Prompt();
0305
0306
0307 unsigned char BreakLineCommand(int ch);
0308
0309
0310 unsigned char EndOrAddLineCommand(int ch);
0311
0312
0313 unsigned char DeleteNextCharCommand(int ch);
0314
0315
0316 unsigned char DeletePreviousCharCommand(int ch);
0317
0318
0319
0320 unsigned char PreviousLineCommand(int ch);
0321
0322
0323
0324 unsigned char NextLineCommand(int ch);
0325
0326
0327
0328 unsigned char PreviousHistoryCommand(int ch);
0329
0330
0331
0332 unsigned char NextHistoryCommand(int ch);
0333
0334
0335 unsigned char BufferStartCommand(int ch);
0336
0337
0338 unsigned char BufferEndCommand(int ch);
0339
0340
0341
0342 unsigned char TabCommand(int ch);
0343
0344
0345 unsigned char ApplyAutosuggestCommand(int ch);
0346
0347
0348 unsigned char TypedCharacter(int ch);
0349
0350
0351 unsigned char FixIndentationCommand(int ch);
0352
0353
0354 unsigned char RevertLineCommand(int ch);
0355
0356
0357
0358 void ConfigureEditor(bool multiline);
0359
0360 bool CompleteCharacter(char ch, EditLineGetCharType &out);
0361
0362 void ApplyTerminalSizeChange();
0363
0364
0365
0366
0367
0368 void AddFunctionToEditLine(const EditLineCharType *command,
0369 const EditLineCharType *helptext,
0370 EditlineCommandCallbackType callbackFn);
0371 void SetEditLinePromptCallback(EditlinePromptCallbackType callbackFn);
0372 void SetGetCharacterFunction(EditlineGetCharCallbackType callbackFn);
0373
0374 ::EditLine *m_editline = nullptr;
0375 EditlineHistorySP m_history_sp;
0376 bool m_in_history = false;
0377 std::vector<EditLineStringType> m_live_history_lines;
0378 bool m_multiline_enabled = false;
0379 std::vector<EditLineStringType> m_input_lines;
0380 EditorStatus m_editor_status;
0381 int m_terminal_width = 0;
0382 int m_terminal_height = 0;
0383 int m_base_line_number = 0;
0384 unsigned m_current_line_index = 0;
0385 int m_current_line_rows = -1;
0386 int m_revert_cursor_index = 0;
0387 int m_line_number_digits = 3;
0388 std::string m_set_prompt;
0389 std::string m_set_continuation_prompt;
0390 std::string m_current_prompt;
0391 bool m_needs_prompt_repaint = false;
0392 volatile std::sig_atomic_t m_terminal_size_has_changed = 0;
0393 std::string m_editor_name;
0394 FILE *m_input_file;
0395 FILE *m_output_file;
0396 FILE *m_error_file;
0397 ConnectionFileDescriptor m_input_connection;
0398
0399 IsInputCompleteCallbackType m_is_input_complete_callback;
0400
0401 FixIndentationCallbackType m_fix_indentation_callback;
0402 const char *m_fix_indentation_callback_chars = nullptr;
0403
0404 CompleteCallbackType m_completion_callback;
0405 SuggestionCallbackType m_suggestion_callback;
0406
0407 bool m_color;
0408 std::string m_prompt_ansi_prefix;
0409 std::string m_prompt_ansi_suffix;
0410 std::string m_suggestion_ansi_prefix;
0411 std::string m_suggestion_ansi_suffix;
0412
0413 std::size_t m_previous_autosuggestion_size = 0;
0414 std::recursive_mutex &m_output_mutex;
0415 };
0416 }
0417
0418 #endif