summaryrefslogtreecommitdiff
path: root/src/option_manager.hh
blob: d31902f2425461224ff6b1aa09a0c0d9f020f2ee (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
#ifndef option_manager_hh_INCLUDED
#define option_manager_hh_INCLUDED

#include "utils.hh"
#include "exception.hh"
#include "completion.hh"

#include <unordered_map>

namespace Kakoune
{

struct option_not_found : public runtime_error
{
    option_not_found(const String& name)
        : runtime_error("option not found: " + name) {}
};

String int_to_str(int value);

class Option
{
public:
    Option() {}
    explicit Option(int value) : m_value(int_to_str(value)) {}
    explicit Option(const String& value) : m_value(value) {}

    Option& operator=(int value) { m_value = int_to_str(value); return *this; }
    Option& operator=(const String& value) { m_value = value; return *this; }

    bool operator==(const Option& other) const { return m_value == other.m_value; }
    bool operator!=(const Option& other) const { return m_value != other.m_value; }

    int    as_int()    const  { return str_to_int(m_value); }
    String as_string() const { return m_value; }
private:
    String m_value;
};

class OptionManagerWatcher
{
public:
    virtual ~OptionManagerWatcher() {}

    virtual void on_option_changed(const String& name,
                                   const Option& option) = 0;
};

class OptionManager : private OptionManagerWatcher
{
public:
    OptionManager(OptionManager& parent);
    ~OptionManager();

    const Option& operator[] (const String& name) const;

    void set_option(const String& name, const Option& value);

    CandidateList complete_option_name(const String& prefix,
                                       ByteCount cursor_pos);

    typedef std::unordered_map<String, Option> OptionMap;
    OptionMap flatten_options() const;

    void register_watcher(OptionManagerWatcher& watcher);
    void unregister_watcher(OptionManagerWatcher& watcher);

private:
    OptionManager()
        : m_parent(nullptr) {}
    // the only one allowed to construct a root option manager
    friend class GlobalOptions;

    OptionMap m_options;
    OptionManager* m_parent;

    void on_option_changed(const String& name,
                           const Option& value);

    std::vector<OptionManagerWatcher*> m_watchers;
};

class GlobalOptions : public OptionManager,
                      public Singleton<GlobalOptions>
{
public:
    GlobalOptions();
};


}

#endif // option_manager_hh_INCLUDED