LineEditor.h 5.2 KB

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