-
Notifications
You must be signed in to change notification settings - Fork 712
/
command_manager.hh
177 lines (140 loc) · 4.77 KB
/
command_manager.hh
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#ifndef command_manager_hh_INCLUDED
#define command_manager_hh_INCLUDED
#include "completion.hh"
#include "array_view.hh"
#include "shell_manager.hh"
#include "parameters_parser.hh"
#include "string.hh"
#include "optional.hh"
#include "utils.hh"
#include "hash_map.hh"
#include <functional>
namespace Kakoune
{
class Context;
using CommandParameters = ConstArrayView<String>;
using CommandFunc = std::function<void (const ParametersParser& parser,
Context& context,
const ShellContext& shell_context)>;
using CommandCompleter = std::function<Completions (const Context& context,
CompletionFlags,
CommandParameters,
size_t, ByteCount)>;
using CommandHelper = std::function<String (const Context& context, CommandParameters)>;
enum class CommandFlags
{
None = 0,
Hidden = 1,
};
constexpr bool with_bit_ops(Meta::Type<CommandFlags>) { return true; }
struct CommandInfo { String name, info; };
struct Token
{
enum class Type
{
Raw,
RawQuoted,
Expand,
ShellExpand,
RegisterExpand,
OptionExpand,
ValExpand,
ArgExpand,
FileExpand,
CommandSeparator
};
Type type;
ByteCount pos;
String content;
bool terminated = false;
};
struct ParseState
{
StringView str;
const char* pos;
operator bool() const { return pos != str.end(); }
};
class CommandParser
{
public:
CommandParser(StringView command_line);
Optional<Token> read_token(bool throw_on_unterminated);
const char* pos() const { return m_state.pos; }
bool done() const { return not m_state; }
private:
ParseState m_state;
};
class CommandManager : public Singleton<CommandManager>
{
public:
void execute(StringView command_line, Context& context,
const ShellContext& shell_context = ShellContext{});
void execute_single_command(CommandParameters params,
Context& context,
const ShellContext& shell_context);
Optional<CommandInfo> command_info(const Context& context,
StringView command_line) const;
bool command_defined(StringView command_name) const;
void register_command(String command_name, CommandFunc func,
String docstring,
ParameterDesc param_desc,
CommandFlags flags = CommandFlags::None,
CommandHelper helper = CommandHelper(),
CommandCompleter completer = CommandCompleter());
void set_command_completer(StringView command_name, CommandCompleter completer);
Completions complete_command_name(const Context& context, StringView query) const;
bool module_defined(StringView module_name) const;
void register_module(String module_name, String commands);
void load_module(StringView module_name, Context& context);
HashSet<String> loaded_modules() const;
Completions complete_module_name(StringView query) const;
struct Completer
{
Completions operator()(const Context& context, CompletionFlags flags,
StringView command_line, ByteCount cursor_pos);
private:
String m_last_complete_command;
CommandCompleter m_command_completer;
};
struct NestedCompleter
{
Completions operator()(const Context& context, CompletionFlags flags,
CommandParameters params, size_t token_to_complete, ByteCount pos_in_token);
private:
String m_last_complete_command;
CommandCompleter m_command_completer;
};
private:
struct Command
{
CommandFunc func;
String docstring;
ParameterDesc param_desc;
CommandFlags flags;
CommandHelper helper;
CommandCompleter completer;
};
using CommandMap = HashMap<String, Command, MemoryDomain::Commands>;
CommandMap m_commands;
int m_command_depth = 0;
struct Module
{
enum class State
{
Registered,
Loading,
Loaded
};
State state = State::Registered;
String commands;
};
using ModuleMap = HashMap<String, Module, MemoryDomain::Commands>;
ModuleMap m_modules;
};
String expand(StringView str, const Context& context,
const ShellContext& shell_context = ShellContext{});
String expand(StringView str, const Context& context,
const ShellContext& shell_context,
const FunctionRef<String (String)>& postprocess);
}
#endif // command_manager_hh_INCLUDED