1 #include "keymapper.hpp"
9 #include "videodumper2.hpp"
10 #include "settings.hpp"
11 #include "memorymanip.hpp"
12 #include "fieldsplit.hpp"
16 std::map
<std::string
, std::list
<std::string
>> aliases
;
18 void handle_alias(std::string cmd
, window
* win
)
20 std::string syntax
= "Syntax: alias-command <alias> <command>";
22 std::string dummy
= t
;
23 std::string aliasname
= t
;
24 std::string command
= t
.tail();
26 throw std::runtime_error(syntax
);
27 aliases
[aliasname
].push_back(command
);
28 out(win
) << "Command '" << aliasname
<< "' aliased to '" << command
<< "'" << std::endl
;
31 void handle_unalias(std::string cmd
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
33 std::string syntax
= "Syntax: unalias-command <alias>";
35 std::string dummy
= t
;
36 std::string aliasname
= t
;
37 if(aliasname
== "" || t
.tail() != "")
38 throw std::runtime_error(syntax
);
39 aliases
.erase(aliasname
);
40 out(win
) << "Removed alias '" << aliasname
<< "'" << std::endl
;
43 void handle_aliases(window
* win
) throw(std::bad_alloc
, std::runtime_error
)
45 for(auto i
= aliases
.begin(); i
!= aliases
.end(); i
++)
46 for(auto j
= i
->second
.begin(); j
!= i
->second
.end(); j
++)
47 out(win
) << "alias " << i
->first
<< " " << *j
<< std::endl
;
50 void handle_run(std::string cmd
, window
* win
, aliasexpand_commandhandler
& cmdh
,
51 std::set
<std::string
>& recursive_commands
) throw(std::bad_alloc
, std::runtime_error
)
53 std::string syntax
= "Syntax: run-script <file>";
55 std::string dummy
= t
;
56 std::string file
= t
.tail();
58 throw std::runtime_error(syntax
);
59 std::istream
* o
= NULL
;
61 o
= &open_file_relative(file
, "");
62 out(win
) << "Running '" << file
<< "'" << std::endl
;
64 while(std::getline(*o
, line
))
65 cmdh
.docommand(line
, win
, recursive_commands
);
67 } catch(std::bad_alloc
& e
) {
69 } catch(std::exception
& e
) {
70 out(win
) << "Error running script: " << e
.what() << std::endl
;
76 void handle_set(std::string cmd
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
78 std::string syntax
= "Syntax: set-setting <setting> [<value>]";
80 std::string dummy
= t
;
81 std::string settingname
= t
;
82 std::string settingvalue
= t
.tail();
84 throw std::runtime_error(syntax
);
85 setting_set(settingname
, settingvalue
);
86 out(win
) << "Setting '" << settingname
<< "' set to '" << settingvalue
<< "'" << std::endl
;
89 void handle_unset(std::string cmd
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
91 std::string syntax
= "Syntax: unset-setting <setting>";
93 std::string dummy
= t
;
94 std::string settingname
= t
;
95 if(settingname
== "" || t
.tail() != "")
96 throw std::runtime_error(syntax
);
97 setting_blank(settingname
);
98 out(win
) << "Setting '" << settingname
<< "' blanked" << std::endl
;
101 void handle_get(std::string cmd
, window
* win
) throw(std::bad_alloc
, std::runtime_error
)
103 std::string syntax
= "Syntax: get-setting <setting>";
104 tokensplitter
t(cmd
);
105 std::string dummy
= t
;
106 std::string settingname
= t
;
107 if(settingname
== "" || t
.tail() != "")
108 throw std::runtime_error(syntax
);
109 if(!setting_isblank(settingname
))
110 out(win
) << "Setting '" << settingname
<< "' has value '" << setting_get(settingname
)
113 out(win
) << "Setting '" << settingname
<< "' unset" << std::endl
;
116 struct binding_request
118 binding_request(std::string
& cmd
) throw(std::bad_alloc
, std::runtime_error
);
128 set_raii(std::set
<std::string
>& _set
, const std::string
& _foo
) throw(std::bad_alloc
)
129 : set(_set
), foo(_foo
)
139 std::set
<std::string
>& set
;
144 aliasexpand_commandhandler::aliasexpand_commandhandler() throw()
148 aliasexpand_commandhandler::~aliasexpand_commandhandler() throw()
152 void aliasexpand_commandhandler::docommand(std::string
& cmd
, window
* win
) throw(std::bad_alloc
)
154 std::set
<std::string
> recursive_commands
;
155 docommand(cmd
, win
, recursive_commands
);
158 void aliasexpand_commandhandler::docommand(std::string
& cmd
, window
* win
, std::set
<std::string
>& recursive_commands
)
159 throw(std::bad_alloc
)
161 std::string tmp
= cmd
;
162 bool noalias
= false;
163 if(cmd
.length() > 0 && cmd
[0] == '*') {
167 if(recursive_commands
.count(tmp
)) {
168 out(win
) << "Not executing '" << tmp
<< "' recursively" << std::endl
;
171 set_raii
rce(recursive_commands
, tmp
);
173 if(is_cmd_prefix(tmp
, "set-setting")) {
174 handle_set(tmp
, win
);
177 if(is_cmd_prefix(tmp
, "get-setting")) {
178 handle_get(tmp
, win
);
181 if(is_cmd_prefix(tmp
, "print-settings")) {
182 setting_print_all(win
);
185 if(is_cmd_prefix(tmp
, "unset-setting")) {
186 handle_unset(tmp
, win
);
189 if(is_cmd_prefix(tmp
, "print-keybindings")) {
193 throw std::runtime_error("Can't list bindings without graphics context");
196 if(is_cmd_prefix(tmp
, "print-aliases")) {
200 if(is_cmd_prefix(tmp
, "alias-command")) {
201 handle_alias(tmp
, win
);
204 if(is_cmd_prefix(tmp
, "unalias-command")) {
205 handle_unalias(tmp
, win
);
208 if(is_cmd_prefix(tmp
, "run-script")) {
209 handle_run(tmp
, win
, *this, recursive_commands
);
212 if(is_cmd_prefix(tmp
, "bind-key")) {
213 binding_request
req(tmp
);
215 win
->bind(req
.mod
, req
.modmask
, req
.keyname
, req
.command
);
217 throw std::runtime_error("Can't bind keys without graphics context");
220 if(is_cmd_prefix(tmp
, "unbind-key")) {
221 binding_request
req(tmp
);
223 win
->unbind(req
.mod
, req
.modmask
, req
.keyname
);
225 throw std::runtime_error("Can't unbind keys without graphics context");
228 if(win
&& win
->exec_command(tmp
))
230 if(vid_dumper_command(tmp
, win
))
232 if(memorymanip_command(tmp
, win
))
234 if(lua_command(tmp
, win
))
236 } catch(std::bad_alloc
& e
) {
238 } catch(std::exception
& e
) {
239 out(win
) << "Error: " << e
.what() << std::endl
;
242 if(!noalias
&& aliases
.count(tmp
)) {
243 auto& x
= aliases
[tmp
];
244 for(auto i
= x
.begin(); i
!= x
.end(); i
++) {
246 docommand(y
, win
, recursive_commands
);
249 docommand2(tmp
, win
);
253 std::string
fixup_command_polarity(std::string cmd
, bool polarity
) throw(std::bad_alloc
)
257 if(cmd
[0] != '+' && polarity
)
259 if(cmd
[0] == '+' && !polarity
)
264 binding_request::binding_request(std::string
& cmd
) throw(std::bad_alloc
, std::runtime_error
)
266 if(is_cmd_prefix(cmd
, "bind-key")) {
267 std::string syntax
= "Syntax: bind-key [<mod>/<modmask>] <key> <command>";
268 tokensplitter
t(cmd
);
269 std::string dummy
= t
;
270 std::string mod_or_key
= t
;
271 if(mod_or_key
.find_first_of("/") < mod_or_key
.length()) {
273 size_t split
= mod_or_key
.find_first_of("/");
274 mod
= mod_or_key
.substr(0, split
);
275 modmask
= mod_or_key
.substr(split
+ 1);
276 mod_or_key
= static_cast<std::string
>(t
);
279 throw std::runtime_error(syntax
);
280 keyname
= mod_or_key
;
283 throw std::runtime_error(syntax
);
285 } else if(is_cmd_prefix(cmd
, "unbind-key")) {
286 std::string syntax
= "Syntax: unbind-key [<mod>/<modmask>] <key>";
287 tokensplitter
t(cmd
);
288 std::string dummy
= t
;
289 std::string mod_or_key
= t
;
290 if(mod_or_key
.find_first_of("/") < mod_or_key
.length()) {
292 size_t split
= mod_or_key
.find_first_of("/");
293 mod
= mod_or_key
.substr(0, split
);
294 modmask
= mod_or_key
.substr(split
+ 1);
295 mod_or_key
= static_cast<std::string
>(t
);
298 throw std::runtime_error(syntax
);
299 keyname
= mod_or_key
;
301 throw std::runtime_error(syntax
);
304 throw std::runtime_error("Not a valid binding request");