SuggestionManager.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Forward.h>
  8. #include <AK/String.h>
  9. #include <AK/Utf32View.h>
  10. #include <AK/Utf8View.h>
  11. #include <LibLine/Style.h>
  12. #include <stdlib.h>
  13. namespace Line {
  14. // FIXME: These objects are pretty heavy since they store two copies of text
  15. // somehow get rid of one.
  16. struct CompletionSuggestion {
  17. private:
  18. struct ForSearchTag {
  19. };
  20. public:
  21. static constexpr ForSearchTag ForSearch {};
  22. // Intentionally not explicit. (To allow suggesting bare strings)
  23. CompletionSuggestion(String const& completion)
  24. : CompletionSuggestion(completion, "", {})
  25. {
  26. }
  27. CompletionSuggestion(String const& completion, ForSearchTag)
  28. : text_string(completion)
  29. {
  30. }
  31. CompletionSuggestion(StringView completion, StringView trailing_trivia)
  32. : CompletionSuggestion(completion, trailing_trivia, {})
  33. {
  34. }
  35. CompletionSuggestion(StringView completion, StringView trailing_trivia, Style style);
  36. bool operator==(CompletionSuggestion const& suggestion) const
  37. {
  38. return suggestion.text_string == text_string;
  39. }
  40. Vector<u32> text;
  41. Vector<u32> trailing_trivia;
  42. Style style;
  43. size_t start_index { 0 };
  44. size_t input_offset { 0 };
  45. size_t static_offset { 0 };
  46. size_t invariant_offset { 0 };
  47. Utf32View text_view;
  48. Utf32View trivia_view;
  49. String text_string;
  50. bool is_valid { false };
  51. };
  52. class SuggestionManager {
  53. friend class Editor;
  54. public:
  55. void set_suggestions(Vector<CompletionSuggestion>&& suggestions);
  56. void set_current_suggestion_initiation_index(size_t start_index);
  57. size_t count() const { return m_suggestions.size(); }
  58. size_t display_length() const { return m_last_shown_suggestion_display_length; }
  59. size_t start_index() const { return m_last_displayed_suggestion_index; }
  60. size_t next_index() const { return m_next_suggestion_index; }
  61. void set_start_index(size_t index) const { m_last_displayed_suggestion_index = index; }
  62. size_t for_each_suggestion(Function<IterationDecision(CompletionSuggestion const&, size_t)>) const;
  63. enum CompletionMode {
  64. DontComplete,
  65. CompletePrefix,
  66. ShowSuggestions,
  67. CycleSuggestions,
  68. };
  69. class CompletionAttemptResult {
  70. public:
  71. CompletionMode new_completion_mode;
  72. ssize_t new_cursor_offset { 0 };
  73. struct {
  74. size_t start;
  75. size_t end;
  76. } offset_region_to_remove { 0, 0 }; // The region to remove as defined by [start, end) translated by (old_cursor + new_cursor_offset)
  77. Vector<Utf32View> insert {};
  78. Optional<Style> style_to_apply {};
  79. };
  80. CompletionAttemptResult attempt_completion(CompletionMode, size_t initiation_start_index);
  81. void next();
  82. void previous();
  83. CompletionSuggestion const& suggest();
  84. CompletionSuggestion const& current_suggestion() const { return m_last_shown_suggestion; }
  85. bool is_current_suggestion_complete() const { return m_last_shown_suggestion_was_complete; }
  86. void reset()
  87. {
  88. m_last_shown_suggestion = String::empty();
  89. m_last_shown_suggestion_display_length = 0;
  90. m_suggestions.clear();
  91. m_last_displayed_suggestion_index = 0;
  92. }
  93. private:
  94. SuggestionManager()
  95. {
  96. }
  97. Vector<CompletionSuggestion> m_suggestions;
  98. CompletionSuggestion m_last_shown_suggestion { String::empty() };
  99. size_t m_last_shown_suggestion_display_length { 0 };
  100. bool m_last_shown_suggestion_was_complete { false };
  101. mutable size_t m_next_suggestion_index { 0 };
  102. size_t m_largest_common_suggestion_prefix_length { 0 };
  103. mutable size_t m_last_displayed_suggestion_index { 0 };
  104. size_t m_selected_suggestion_index { 0 };
  105. };
  106. }