12 #include "llvm/Config/config.h" 33 LineEditor::CompleterConcept::~CompleterConcept() {}
34 LineEditor::ListCompleterConcept::~ListCompleterConcept() {}
36 std::string LineEditor::ListCompleterConcept::getCommonPrefix(
37 const std::vector<Completion> &Comps) {
40 std::string CommonPrefix = Comps[0].TypedText;
41 for (std::vector<Completion>::const_iterator
I = Comps.begin() + 1,
44 size_t Len = std::min(CommonPrefix.size(),
I->TypedText.size());
46 for (; CommonLen != Len; ++CommonLen) {
47 if (CommonPrefix[CommonLen] !=
I->TypedText[CommonLen])
50 CommonPrefix.resize(CommonLen);
56 LineEditor::ListCompleterConcept::complete(
StringRef Buffer,
size_t Pos)
const {
58 std::vector<Completion> Comps = getCompletions(Buffer, Pos);
64 std::string CommonPrefix = getCommonPrefix(Comps);
71 if (CommonPrefix.empty()) {
73 for (std::vector<Completion>::iterator
I = Comps.begin(),
E = Comps.end();
78 Action.
Text = CommonPrefix;
92 return Completer->complete(Buffer, Pos);
106 std::string ContinuationOutput;
113 const char *ElGetPromptFn(EditLine *EL) {
115 if (el_get(EL, EL_CLIENTDATA, &Data) == 0)
116 return Data->LE->getPrompt().c_str();
124 unsigned char ElCompletionFn(EditLine *EL,
int ch) {
126 if (el_get(EL, EL_CLIENTDATA, &Data) == 0) {
127 if (!Data->ContinuationOutput.empty()) {
129 FILE *Out = Data->
Out;
132 ::fwrite(Data->ContinuationOutput.c_str(),
133 Data->ContinuationOutput.size(), 1, Out);
137 std::string Prevs(Data->PrevCount,
'\02');
138 ::el_push(EL, const_cast<char *>(Prevs.c_str()));
140 Data->ContinuationOutput.clear();
145 const LineInfo *LI = ::el_line(EL);
147 StringRef(LI->buffer, LI->lastchar - LI->buffer),
148 LI->cursor - LI->buffer);
149 switch (Action.
Kind) {
151 ::el_insertstr(EL, Action.
Text.c_str());
156 return CC_REFRESH_BEEP;
165 ::el_push(EL, const_cast<char *>(
"\05\t"));
174 for (std::vector<std::string>::iterator
I = Action.
Completions.begin(),
183 OS << Data->LE->getPrompt()
184 <<
StringRef(LI->buffer, LI->lastchar - LI->buffer);
188 Data->PrevCount = LI->lastchar - LI->cursor;
200 FILE *Out, FILE *Err)
201 : Prompt((ProgName +
"> ").str()), HistoryPath(HistoryPath),
203 if (HistoryPath.
empty())
209 Data->Hist = ::history_init();
212 Data->EL = ::el_init(ProgName.
str().c_str(),
In, Out, Err);
215 ::el_set(
Data->EL, EL_PROMPT, ElGetPromptFn);
216 ::el_set(
Data->EL, EL_EDITOR,
"emacs");
217 ::el_set(
Data->EL, EL_HIST, history,
Data->Hist);
218 ::el_set(
Data->EL, EL_ADDFN,
"tab_complete",
"Tab completion function",
220 ::el_set(
Data->EL, EL_BIND,
"\t",
"tab_complete", NULL);
221 ::el_set(
Data->EL, EL_BIND,
"^r",
"em-inc-search-prev",
223 ::el_set(
Data->EL, EL_BIND,
"^w",
"ed-delete-prev-word",
225 ::el_set(
Data->EL, EL_BIND,
"\033[3~",
"ed-delete-next-char",
227 ::el_set(
Data->EL, EL_CLIENTDATA,
Data.get());
230 ::history(
Data->Hist, &HE, H_SETSIZE, 800);
231 ::history(
Data->Hist, &HE, H_SETUNIQUE, 1);
238 ::history_end(
Data->Hist);
240 ::fwrite(
"\n", 1, 1,
Data->Out);
244 if (!HistoryPath.
empty()) {
246 ::history(
Data->Hist, &HE, H_SAVE, HistoryPath.c_str());
251 if (!HistoryPath.
empty()) {
253 ::history(
Data->Hist, &HE, H_LOAD, HistoryPath.c_str());
260 const char *Line = ::el_gets(
Data->EL, &LineLen);
263 if (!Line || LineLen == 0)
267 while (LineLen > 0 &&
268 (Line[LineLen - 1] ==
'\n' || Line[LineLen - 1] ==
'\r'))
273 ::history(
Data->Hist, &HE, H_ENTER, Line);
275 return std::string(Line, LineLen);
278 #else // HAVE_LIBEDIT 288 FILE *Out, FILE *Err)
295 ::fwrite(
"\n", 1, 1, Data->Out);
302 ::fprintf(Data->Out,
"%s", Prompt.c_str());
307 char *Res = ::fgets(Buf,
sizeof(Buf), Data->In);
315 }
while (Line.empty() ||
316 (Line[Line.size() - 1] !=
'\n' && Line[Line.size() - 1] !=
'\r'));
318 while (!Line.empty() &&
319 (Line[Line.size() - 1] ==
'\n' || Line[Line.size() - 1] ==
'\r'))
320 Line.resize(Line.size() - 1);
325 #endif // HAVE_LIBEDIT
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
This class represents lattice values for constants.
CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const
Use the current completer to produce a CompletionAction for the given completion request.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
StringRef str() const
Explicit conversion to StringRef.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
Show Completions, or beep if the list is empty.
std::vector< std::string > Completions
The list of completions to show.
std::string Text
The text to insert.
llvm::Optional< std::string > readLine() const
Reads a line.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.