1 //===-- llvm/LineEditor/LineEditor.h - line editor --------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_LINEEDITOR_LINEEDITOR_H
11 #define LLVM_LINEEDITOR_LINEEDITOR_H
12 
13 #include "llvm/ADT/Optional.h"
14 #include "llvm/ADT/StringRef.h"
15 #include <cstdio>
16 #include <memory>
17 #include <string>
18 #include <utility>
19 #include <vector>
20 
21 namespace llvm {
22 
23 class LineEditor {
24 public:
25   /// Create a LineEditor object.
26   ///
27   /// \param ProgName The name of the current program. Used to form a default
28   /// prompt.
29   /// \param HistoryPath Path to the file in which to store history data, if
30   /// possible.
31   /// \param In The input stream used by the editor.
32   /// \param Out The output stream used by the editor.
33   /// \param Err The error stream used by the editor.
34   LineEditor(StringRef ProgName, StringRef HistoryPath = "", FILE *In = stdin,
35              FILE *Out = stdout, FILE *Err = stderr);
36   ~LineEditor();
37 
38   /// Reads a line.
39   ///
40   /// \return The line, or llvm::Optional<std::string>() on EOF.
41   llvm::Optional<std::string> readLine() const;
42 
43   void saveHistory();
44   void loadHistory();
45 
46   static std::string getDefaultHistoryPath(StringRef ProgName);
47 
48   /// The action to perform upon a completion request.
49   struct CompletionAction {
50     enum ActionKind {
51       /// Insert Text at the cursor position.
52       AK_Insert,
53       /// Show Completions, or beep if the list is empty.
54       AK_ShowCompletions
55     };
56 
57     ActionKind Kind;
58 
59     /// The text to insert.
60     std::string Text;
61 
62     /// The list of completions to show.
63     std::vector<std::string> Completions;
64   };
65 
66   /// A possible completion at a given cursor position.
67   struct Completion {
68     Completion() {}
69     Completion(const std::string &TypedText, const std::string &DisplayText)
70         : TypedText(TypedText), DisplayText(DisplayText) {}
71 
72     /// The text to insert. If the user has already input some of the
73     /// completion, this should only include the rest of the text.
74     std::string TypedText;
75 
76     /// A description of this completion. This may be the completion itself, or
77     /// maybe a summary of its type or arguments.
78     std::string DisplayText;
79   };
80 
81   /// Set the completer for this LineEditor. A completer is a function object
82   /// which takes arguments of type StringRef (the string to complete) and
83   /// size_t (the zero-based cursor position in the StringRef) and returns a
84   /// CompletionAction.
85   template <typename T> void setCompleter(T Comp) {
86     Completer.reset(new CompleterModel<T>(Comp));
87   }
88 
89   /// Set the completer for this LineEditor to the given list completer.
90   /// A list completer is a function object which takes arguments of type
91   /// StringRef (the string to complete) and size_t (the zero-based cursor
92   /// position in the StringRef) and returns a std::vector<Completion>.
93   template <typename T> void setListCompleter(T Comp) {
94     Completer.reset(new ListCompleterModel<T>(Comp));
95   }
96 
97   /// Use the current completer to produce a CompletionAction for the given
98   /// completion request. If the current completer is a list completer, this
99   /// will return an AK_Insert CompletionAction if each completion has a common
100   /// prefix, or an AK_ShowCompletions CompletionAction otherwise.
101   ///
102   /// \param Buffer The string to complete
103   /// \param Pos The zero-based cursor position in the StringRef
104   CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const;
105 
106   const std::string &getPrompt() const { return Prompt; }
107   void setPrompt(const std::string &P) { Prompt = P; }
108 
109   // Public so callbacks in LineEditor.cpp can use it.
110   struct InternalData;
111 
112 private:
113   std::string Prompt;
114   std::string HistoryPath;
getModuleLTOModule115   std::unique_ptr<InternalData> Data;
getModuleLTOModule116 
117   struct CompleterConcept {
118     virtual ~CompleterConcept();
119     virtual CompletionAction complete(StringRef Buffer, size_t Pos) const = 0;
120   };
getTargetTripleLTOModule121 
122   struct ListCompleterConcept : CompleterConcept {
123     ~ListCompleterConcept() override;
124     CompletionAction complete(StringRef Buffer, size_t Pos) const override;
125     static std::string getCommonPrefix(const std::vector<Completion> &Comps);
126     virtual std::vector<Completion> getCompletions(StringRef Buffer,
127                                                    size_t Pos) const = 0;
128   };
129 
130   template <typename T>
getSymbolCountLTOModule131   struct CompleterModel : CompleterConcept {
132     CompleterModel(T Value) : Value(Value) {}
133     CompletionAction complete(StringRef Buffer, size_t Pos) const override {
134       return Value(Buffer, Pos);
135     }
136     T Value;
137   };
138 
139   template <typename T>
140   struct ListCompleterModel : ListCompleterConcept {
141     ListCompleterModel(T Value) : Value(std::move(Value)) {}
142     std::vector<Completion> getCompletions(StringRef Buffer,
getSymbolNameLTOModule143                                            size_t Pos) const override {
144       return Value(Buffer, Pos);
145     }
146     T Value;
147   };
148 
getSymbolGVLTOModule149   std::unique_ptr<const CompleterConcept> Completer;
150 };
151 
152 }
153 
154 #endif
getLinkerOptsLTOModule155