Line data Source code
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 2 : 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 26 : struct Completion {
68 : Completion() {}
69 16 : Completion(const std::string &TypedText, const std::string &DisplayText)
70 16 : : 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 3 : template <typename T> void setListCompleter(T Comp) {
94 3 : Completer.reset(new ListCompleterModel<T>(Comp));
95 3 : }
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;
115 : std::unique_ptr<InternalData> Data;
116 :
117 : struct CompleterConcept {
118 : virtual ~CompleterConcept();
119 : virtual CompletionAction complete(StringRef Buffer, size_t Pos) const = 0;
120 : };
121 :
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>
131 : 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 3 : ListCompleterModel(T Value) : Value(std::move(Value)) {}
142 3 : std::vector<Completion> getCompletions(StringRef Buffer,
143 : size_t Pos) const override {
144 3 : return Value(Buffer, Pos);
145 : }
146 : T Value;
147 : };
148 :
149 : std::unique_ptr<const CompleterConcept> Completer;
150 : };
151 :
152 : }
153 :
154 : #endif
|