xref: /freebsd/contrib/llvm-project/llvm/include/llvm/LineEditor/LineEditor.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- llvm/LineEditor/LineEditor.h - line editor --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LINEEDITOR_LINEEDITOR_H
10 #define LLVM_LINEEDITOR_LINEEDITOR_H
11 
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/Compiler.h"
14 #include <cstdio>
15 #include <memory>
16 #include <optional>
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   LLVM_ABI LineEditor(StringRef ProgName, StringRef HistoryPath = "",
35                       FILE *In = stdin, FILE *Out = stdout, FILE *Err = stderr);
36   LLVM_ABI ~LineEditor();
37 
38   /// Reads a line.
39   ///
40   /// \return The line, or std::optional<std::string>() on EOF.
41   LLVM_ABI std::optional<std::string> readLine() const;
42 
43   LLVM_ABI void saveHistory();
44   LLVM_ABI void loadHistory();
45   LLVM_ABI void setHistorySize(int size);
46 
47   LLVM_ABI static std::string getDefaultHistoryPath(StringRef ProgName);
48 
49   /// The action to perform upon a completion request.
50   struct CompletionAction {
51     enum ActionKind {
52       /// Insert Text at the cursor position.
53       AK_Insert,
54       /// Show Completions, or beep if the list is empty.
55       AK_ShowCompletions
56     };
57 
58     ActionKind Kind;
59 
60     /// The text to insert.
61     std::string Text;
62 
63     /// The list of completions to show.
64     std::vector<std::string> Completions;
65   };
66 
67   /// A possible completion at a given cursor position.
68   struct Completion {
69     Completion() = default;
CompletionCompletion70     Completion(const std::string &TypedText, const std::string &DisplayText)
71         : TypedText(TypedText), DisplayText(DisplayText) {}
72 
73     /// The text to insert. If the user has already input some of the
74     /// completion, this should only include the rest of the text.
75     std::string TypedText;
76 
77     /// A description of this completion. This may be the completion itself, or
78     /// maybe a summary of its type or arguments.
79     std::string DisplayText;
80   };
81 
82   /// Set the completer for this LineEditor. A completer is a function object
83   /// which takes arguments of type StringRef (the string to complete) and
84   /// size_t (the zero-based cursor position in the StringRef) and returns a
85   /// CompletionAction.
setCompleter(T Comp)86   template <typename T> void setCompleter(T Comp) {
87     Completer.reset(new CompleterModel<T>(Comp));
88   }
89 
90   /// Set the completer for this LineEditor to the given list completer.
91   /// A list completer is a function object which takes arguments of type
92   /// StringRef (the string to complete) and size_t (the zero-based cursor
93   /// position in the StringRef) and returns a std::vector<Completion>.
setListCompleter(T Comp)94   template <typename T> void setListCompleter(T Comp) {
95     Completer.reset(new ListCompleterModel<T>(Comp));
96   }
97 
98   /// Use the current completer to produce a CompletionAction for the given
99   /// completion request. If the current completer is a list completer, this
100   /// will return an AK_Insert CompletionAction if each completion has a common
101   /// prefix, or an AK_ShowCompletions CompletionAction otherwise.
102   ///
103   /// \param Buffer The string to complete
104   /// \param Pos The zero-based cursor position in the StringRef
105   LLVM_ABI CompletionAction getCompletionAction(StringRef Buffer,
106                                                 size_t Pos) const;
107 
getPrompt()108   const std::string &getPrompt() const { return Prompt; }
setPrompt(const std::string & P)109   void setPrompt(const std::string &P) { Prompt = P; }
110 
111   // Public so callbacks in LineEditor.cpp can use it.
112   struct InternalData;
113 
114 private:
115   std::string Prompt;
116   std::string HistoryPath;
117   std::unique_ptr<InternalData> Data;
118 
119   struct LLVM_ABI CompleterConcept {
120     virtual ~CompleterConcept();
121     virtual CompletionAction complete(StringRef Buffer, size_t Pos) const = 0;
122   };
123 
124   struct LLVM_ABI ListCompleterConcept : CompleterConcept {
125     ~ListCompleterConcept() override;
126     CompletionAction complete(StringRef Buffer, size_t Pos) const override;
127     static std::string getCommonPrefix(const std::vector<Completion> &Comps);
128     virtual std::vector<Completion> getCompletions(StringRef Buffer,
129                                                    size_t Pos) const = 0;
130   };
131 
132   template <typename T>
133   struct CompleterModel : CompleterConcept {
CompleterModelCompleterModel134     CompleterModel(T Value) : Value(Value) {}
completeCompleterModel135     CompletionAction complete(StringRef Buffer, size_t Pos) const override {
136       return Value(Buffer, Pos);
137     }
138     T Value;
139   };
140 
141   template <typename T>
142   struct ListCompleterModel : ListCompleterConcept {
ListCompleterModelListCompleterModel143     ListCompleterModel(T Value) : Value(std::move(Value)) {}
getCompletionsListCompleterModel144     std::vector<Completion> getCompletions(StringRef Buffer,
145                                            size_t Pos) const override {
146       return Value(Buffer, Pos);
147     }
148     T Value;
149   };
150 
151   std::unique_ptr<const CompleterConcept> Completer;
152 };
153 
154 }
155 
156 #endif
157