136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===-- llvm/LineEditor/LineEditor.h - line editor --------------*- C++ -*-===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef LLVM_LINEEDITOR_LINEEDITOR_H
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define LLVM_LINEEDITOR_LINEEDITOR_H
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/Optional.h"
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringRef.h"
15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include <cstdio>
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include <memory>
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <string>
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <vector>
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm {
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass LineEditor {
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a LineEditor object.
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ///
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \param ProgName The name of the current program. Used to form a default
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// prompt.
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \param HistoryPath Path to the file in which to store history data, if
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// possible.
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \param In The input stream used by the editor.
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \param Out The output stream used by the editor.
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \param Err The error stream used by the editor.
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LineEditor(StringRef ProgName, StringRef HistoryPath = "", FILE *In = stdin,
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             FILE *Out = stdout, FILE *Err = stderr);
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ~LineEditor();
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Reads a line.
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ///
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \return The line, or llvm::Optional<std::string>() on EOF.
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm::Optional<std::string> readLine() const;
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void saveHistory();
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void loadHistory();
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static std::string getDefaultHistoryPath(StringRef ProgName);
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// The action to perform upon a completion request.
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct CompletionAction {
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    enum ActionKind {
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      /// Insert Text at the cursor position.
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AK_Insert,
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      /// Show Completions, or beep if the list is empty.
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AK_ShowCompletions
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    };
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ActionKind Kind;
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// The text to insert.
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::string Text;
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// The list of completions to show.
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::vector<std::string> Completions;
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// A possible completion at a given cursor position.
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct Completion {
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Completion() {}
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Completion(const std::string &TypedText, const std::string &DisplayText)
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        : TypedText(TypedText), DisplayText(DisplayText) {}
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// The text to insert. If the user has already input some of the
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// completion, this should only include the rest of the text.
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::string TypedText;
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// A description of this completion. This may be the completion itself, or
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// maybe a summary of its type or arguments.
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::string DisplayText;
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Set the completer for this LineEditor. A completer is a function object
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// which takes arguments of type StringRef (the string to complete) and
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// size_t (the zero-based cursor position in the StringRef) and returns a
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// CompletionAction.
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename T> void setCompleter(T Comp) {
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Completer.reset(new CompleterModel<T>(Comp));
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Set the completer for this LineEditor to the given list completer.
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// A list completer is a function object which takes arguments of type
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// StringRef (the string to complete) and size_t (the zero-based cursor
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// position in the StringRef) and returns a std::vector<Completion>.
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename T> void setListCompleter(T Comp) {
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Completer.reset(new ListCompleterModel<T>(Comp));
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Use the current completer to produce a CompletionAction for the given
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// completion request. If the current completer is a list completer, this
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// will return an AK_Insert CompletionAction if each completion has a common
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// prefix, or an AK_ShowCompletions CompletionAction otherwise.
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ///
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \param Buffer The string to complete
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \param Pos The zero-based cursor position in the StringRef
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const;
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const std::string &getPrompt() const { return Prompt; }
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void setPrompt(const std::string &P) { Prompt = P; }
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Public so callbacks in LineEditor.cpp can use it.
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct InternalData;
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate:
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::string Prompt;
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::string HistoryPath;
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<InternalData> Data;
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct CompleterConcept {
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    virtual ~CompleterConcept();
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    virtual CompletionAction complete(StringRef Buffer, size_t Pos) const = 0;
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct ListCompleterConcept : CompleterConcept {
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ~ListCompleterConcept();
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CompletionAction complete(StringRef Buffer, size_t Pos) const override;
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    static std::string getCommonPrefix(const std::vector<Completion> &Comps);
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    virtual std::vector<Completion> getCompletions(StringRef Buffer,
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                   size_t Pos) const = 0;
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename T>
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct CompleterModel : CompleterConcept {
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CompleterModel(T Value) : Value(Value) {}
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CompletionAction complete(StringRef Buffer, size_t Pos) const override {
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Value(Buffer, Pos);
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    T Value;
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename T>
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct ListCompleterModel : ListCompleterConcept {
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ListCompleterModel(T Value) : Value(Value) {}
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::vector<Completion> getCompletions(StringRef Buffer,
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           size_t Pos) const override {
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Value(Buffer, Pos);
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    T Value;
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const CompleterConcept> Completer;
14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
154