summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGUI/AutocompleteProvider.h
blob: d9e95739183ba10a6719977f33fd561decee1bde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Copyright (c) 2020-2022, the SerenityOS developers.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <LibGUI/Forward.h>
#include <LibGUI/Label.h>
#include <LibGUI/TableView.h>
#include <LibGUI/TextEditor.h>
#include <LibGUI/Window.h>
#include <LibIPC/Decoder.h>

namespace GUI {

class AutocompleteProvider {
    AK_MAKE_NONCOPYABLE(AutocompleteProvider);
    AK_MAKE_NONMOVABLE(AutocompleteProvider);

public:
    virtual ~AutocompleteProvider() = default;

    enum class Language {
        Unspecified,
        Cpp,
    };

    struct Entry {
        String completion;
        size_t partial_input_length { 0 };
        Language language { Language::Unspecified };
        String display_text {};

        enum class HideAutocompleteAfterApplying {
            No,
            Yes,
        };
        HideAutocompleteAfterApplying hide_autocomplete_after_applying { HideAutocompleteAfterApplying::Yes };
    };

    struct ProjectLocation {
        String file;
        size_t line { 0 };
        size_t column { 0 };

        bool operator==(const ProjectLocation&) const;
    };

    enum class DeclarationType {
        Function,
        Struct,
        Class,
        Variable,
        PreprocessorDefinition,
        Namespace,
        Member,
    };

    struct Declaration {
        String name;
        ProjectLocation position;
        DeclarationType type;
        String scope;

        bool operator==(const Declaration&) const;
    };

    virtual void provide_completions(Function<void(Vector<Entry>)>) = 0;

    struct TokenInfo {
        enum class SemanticType : u32 {
            Unknown,
            Regular,
            Keyword,
            Type,
            Identifier,
            String,
            Number,
            IncludePath,
            PreprocessorStatement,
            Comment,
            Whitespace,
            Function,
            Variable,
            CustomType,
            Namespace,
            Member,
            Parameter,
        } type { SemanticType::Unknown };
        size_t start_line { 0 };
        size_t start_column { 0 };
        size_t end_line { 0 };
        size_t end_column { 0 };
    };

    void attach(TextEditor& editor)
    {
        VERIFY(!m_editor);
        m_editor = editor;
    }
    void detach() { m_editor.clear(); }

protected:
    AutocompleteProvider() = default;

    WeakPtr<TextEditor> m_editor;
};

class AutocompleteBox final {
public:
    explicit AutocompleteBox(TextEditor&);
    ~AutocompleteBox() = default;

    void update_suggestions(Vector<AutocompleteProvider::Entry>&& suggestions);
    bool is_visible() const;
    void show(Gfx::IntPoint suggestion_box_location);
    void close();

    bool has_suggestions() { return m_suggestion_view->model()->row_count() > 0; }
    void next_suggestion();
    void previous_suggestion();
    AutocompleteProvider::Entry::HideAutocompleteAfterApplying apply_suggestion();

private:
    WeakPtr<TextEditor> m_editor;
    RefPtr<GUI::Window> m_popup_window;
    RefPtr<GUI::TableView> m_suggestion_view;
    RefPtr<GUI::Label> m_no_suggestions_view;
};

}