12 #include "llvm/Config/config.h"
31 LineEditor::CompleterConcept::~CompleterConcept() {}
32 LineEditor::ListCompleterConcept::~ListCompleterConcept() {}
34 std::string LineEditor::ListCompleterConcept::getCommonPrefix(
35 const std::vector<Completion> &Comps) {
36 assert(!Comps.empty());
38 std::string CommonPrefix = Comps[0].TypedText;
39 for (std::vector<Completion>::const_iterator
I = Comps.begin() + 1,
42 size_t Len =
std::min(CommonPrefix.size(),
I->TypedText.size());
44 for (; CommonLen != Len; ++CommonLen) {
45 if (CommonPrefix[CommonLen] !=
I->TypedText[CommonLen])
48 CommonPrefix.resize(CommonLen);
54 LineEditor::ListCompleterConcept::complete(
StringRef Buffer,
size_t Pos)
const {
55 CompletionAction Action;
56 std::vector<Completion> Comps = getCompletions(Buffer, Pos);
58 Action.Kind = CompletionAction::AK_ShowCompletions;
62 std::string CommonPrefix = getCommonPrefix(Comps);
69 if (CommonPrefix.empty()) {
70 Action.Kind = CompletionAction::AK_ShowCompletions;
71 for (std::vector<Completion>::iterator
I = Comps.begin(), E = Comps.end();
73 Action.Completions.push_back(
I->DisplayText);
75 Action.Kind = CompletionAction::AK_Insert;
76 Action.Text = CommonPrefix;
90 return Completer->complete(Buffer, Pos);
111 if (el_get(EL, EL_CLIENTDATA, &Data) == 0)
122 if (el_get(EL, EL_CLIENTDATA, &Data) == 0) {
125 FILE *Out = Data->
Out;
133 std::string Prevs(Data->
PrevCount,
'\02');
134 ::el_push(EL, const_cast<char *>(Prevs.c_str()));
141 const LineInfo *LI = ::el_line(EL);
143 StringRef(LI->buffer, LI->lastchar - LI->buffer),
144 LI->cursor - LI->buffer);
145 switch (Action.
Kind) {
147 ::el_insertstr(EL, Action.
Text.c_str());
152 return CC_REFRESH_BEEP;
161 ::el_push(EL, const_cast<char *>(
"\05\t"));
170 for (std::vector<std::string>::iterator
I = Action.
Completions.begin(),
180 <<
StringRef(LI->buffer, LI->lastchar - LI->buffer);
184 Data->
PrevCount = LI->lastchar - LI->cursor;
194 FILE *Out, FILE *Err)
195 : Prompt((ProgName +
"> ").str()), HistoryPath(HistoryPath),
197 if (HistoryPath.
empty())
203 Data->Hist = ::history_init();
206 Data->EL = ::el_init(ProgName.
str().c_str(),
In, Out, Err);
210 ::el_set(Data->EL, EL_EDITOR,
"emacs");
211 ::el_set(Data->EL, EL_HIST, history, Data->Hist);
212 ::el_set(Data->EL, EL_ADDFN,
"tab_complete",
"Tab completion function",
214 ::el_set(Data->EL, EL_BIND,
"\t",
"tab_complete", NULL);
215 ::el_set(Data->EL, EL_BIND,
"^r",
"em-inc-search-prev",
217 ::el_set(Data->EL, EL_BIND,
"^w",
"ed-delete-prev-word",
219 ::el_set(Data->EL, EL_BIND,
"\033[3~",
"ed-delete-next-char",
221 ::el_set(Data->EL, EL_CLIENTDATA, Data.get());
224 ::history(Data->Hist, &HE, H_SETSIZE, 800);
225 ::history(Data->Hist, &HE, H_SETUNIQUE, 1);
232 ::history_end(Data->Hist);
234 ::fwrite(
"\n", 1, 1, Data->Out);
238 if (!HistoryPath.empty()) {
240 ::history(Data->Hist, &HE, H_SAVE, HistoryPath.c_str());
245 if (!HistoryPath.empty()) {
247 ::history(Data->Hist, &HE, H_LOAD, HistoryPath.c_str());
254 const char *Line = ::el_gets(Data->EL, &LineLen);
257 if (!Line || LineLen == 0)
261 while (LineLen > 0 &&
262 (Line[LineLen - 1] ==
'\n' || Line[LineLen - 1] ==
'\r'))
267 ::history(Data->Hist, &HE, H_ENTER, Line);
269 return std::string(Line, LineLen);
282 FILE *Out, FILE *Err)
283 : Prompt((ProgName +
"> ").str()),
Data(new InternalData) {
289 ::fwrite(
"\n", 1, 1, Data->Out);
296 ::fprintf(Data->Out,
"%s", Prompt.c_str());
301 char *Res = ::fgets(Buf,
sizeof(Buf), Data->In);
309 }
while (Line.empty() ||
310 (Line[Line.size() - 1] !=
'\n' && Line[Line.size() - 1] !=
'\r'));
312 while (!Line.empty() &&
313 (Line[Line.size() - 1] ==
'\n' || Line[Line.size() - 1] ==
'\r'))
314 Line.resize(Line.size() - 1);
static const char * ProgName
std::string str() const
str - Get the contents as an std::string.
std::string ContinuationOutput
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
llvm::Optional< std::string > readLine() const
Reads a line.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static const char * ElGetPromptFn(EditLine *EL)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Insert Text at the cursor position.
LineEditor(StringRef ProgName, StringRef HistoryPath="", FILE *In=stdin, FILE *Out=stdout, FILE *Err=stderr)
Create a LineEditor object.
static std::string getDefaultHistoryPath(StringRef ProgName)
The action to perform upon a completion request.
CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const
Use the current completer to produce a CompletionAction for the given completion request.
Show Completions, or beep if the list is empty.
std::vector< std::string > Completions
The list of completions to show.
StringRef str() const
Explicit conversion to StringRef.
static unsigned char ElCompletionFn(EditLine *EL, int ch)
std::string Text
The text to insert.
A raw_ostream that writes to an std::string.
bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
StringRef - Represent a constant reference to a string, i.e.
const std::string & getPrompt() const
bool empty() const
empty - Check if the string is empty.