//===-- llvm/LineEditor/LineEditor.h - line editor --------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_LINEEDITOR_LINEEDITOR_H #define LLVM_LINEEDITOR_LINEEDITOR_H #include "llvm/ADT/StringRef.h" #include #include #include #include #include #include namespace llvm { class LineEditor { public: /// Create a LineEditor object. /// /// \param ProgName The name of the current program. Used to form a default /// prompt. /// \param HistoryPath Path to the file in which to store history data, if /// possible. /// \param In The input stream used by the editor. /// \param Out The output stream used by the editor. /// \param Err The error stream used by the editor. LineEditor(StringRef ProgName, StringRef HistoryPath = "", FILE *In = stdin, FILE *Out = stdout, FILE *Err = stderr); ~LineEditor(); /// Reads a line. /// /// \return The line, or std::optional() on EOF. std::optional readLine() const; void saveHistory(); void loadHistory(); static std::string getDefaultHistoryPath(StringRef ProgName); /// The action to perform upon a completion request. struct CompletionAction { enum ActionKind { /// Insert Text at the cursor position. AK_Insert, /// Show Completions, or beep if the list is empty. AK_ShowCompletions }; ActionKind Kind; /// The text to insert. std::string Text; /// The list of completions to show. std::vector Completions; }; /// A possible completion at a given cursor position. struct Completion { Completion() = default; Completion(const std::string &TypedText, const std::string &DisplayText) : TypedText(TypedText), DisplayText(DisplayText) {} /// The text to insert. If the user has already input some of the /// completion, this should only include the rest of the text. std::string TypedText; /// A description of this completion. This may be the completion itself, or /// maybe a summary of its type or arguments. std::string DisplayText; }; /// Set the completer for this LineEditor. A completer is a function object /// which takes arguments of type StringRef (the string to complete) and /// size_t (the zero-based cursor position in the StringRef) and returns a /// CompletionAction. template void setCompleter(T Comp) { Completer.reset(new CompleterModel(Comp)); } /// Set the completer for this LineEditor to the given list completer. /// A list completer is a function object which takes arguments of type /// StringRef (the string to complete) and size_t (the zero-based cursor /// position in the StringRef) and returns a std::vector. template void setListCompleter(T Comp) { Completer.reset(new ListCompleterModel(Comp)); } /// Use the current completer to produce a CompletionAction for the given /// completion request. If the current completer is a list completer, this /// will return an AK_Insert CompletionAction if each completion has a common /// prefix, or an AK_ShowCompletions CompletionAction otherwise. /// /// \param Buffer The string to complete /// \param Pos The zero-based cursor position in the StringRef CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const; const std::string &getPrompt() const { return Prompt; } void setPrompt(const std::string &P) { Prompt = P; } // Public so callbacks in LineEditor.cpp can use it. struct InternalData; private: std::string Prompt; std::string HistoryPath; std::unique_ptr Data; struct CompleterConcept { virtual ~CompleterConcept(); virtual CompletionAction complete(StringRef Buffer, size_t Pos) const = 0; }; struct ListCompleterConcept : CompleterConcept { ~ListCompleterConcept() override; CompletionAction complete(StringRef Buffer, size_t Pos) const override; static std::string getCommonPrefix(const std::vector &Comps); virtual std::vector getCompletions(StringRef Buffer, size_t Pos) const = 0; }; template struct CompleterModel : CompleterConcept { CompleterModel(T Value) : Value(Value) {} CompletionAction complete(StringRef Buffer, size_t Pos) const override { return Value(Buffer, Pos); } T Value; }; template struct ListCompleterModel : ListCompleterConcept { ListCompleterModel(T Value) : Value(std::move(Value)) {} std::vector getCompletions(StringRef Buffer, size_t Pos) const override { return Value(Buffer, Pos); } T Value; }; std::unique_ptr Completer; }; } #endif