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