aboutsummaryrefslogtreecommitdiffhomepage
path: root/input.cpp
diff options
context:
space:
mode:
authorGravatar Sanne Wouda <sanne.wouda@gmail.com>2015-04-17 15:49:52 +0200
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-04-19 16:56:48 -0700
commit722fedc8fd590cb436109a553fb68f02790117f3 (patch)
treed528ecaf1af2864f57d539c875b8390ba80ba416 /input.cpp
parent32936b0eb95c9cee54d3887328e4bfd01c961922 (diff)
rewrite input_mapping_execute for clarity
For the case ``` bind \et "commandline -i 1" "commandline -i 2" ``` the order of execution of the commands is now in-order. Note that functions codes are prepended to the queue in reverse order, so they will be executed in-order. This should allow all bindings of the form ``` bind \et beginning-of-line force-repaint ``` to remain unchanged.
Diffstat (limited to 'input.cpp')
-rw-r--r--input.cpp83
1 files changed, 49 insertions, 34 deletions
diff --git a/input.cpp b/input.cpp
index 4ddf3569..02b52688 100644
--- a/input.cpp
+++ b/input.cpp
@@ -562,52 +562,67 @@ void input_function_push_args(int code)
*/
static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
{
- /* By default input functions always succeed */
- input_function_status = true;
+ /* has_functions: there are functions that need to be put on the input
+ queue
+ has_commands: there are shell commands that need to be evaluated */
+ bool has_commands = false, has_functions = false;
- size_t idx = m.commands.size();
- while (idx--)
+ for (wcstring_list_t::const_iterator it = m.commands.begin(), end = m.commands.end(); it != end; it++)
{
- wcstring command = m.commands.at(idx);
- wchar_t code = input_function_get_code(command);
- if (code != (wchar_t)-1)
+ if (input_function_get_code(*it) != -1)
+ has_functions = true;
+ else
+ has_commands = true;
+ }
+
+ /* !has_functions && !has_commands: only set bind mode */
+ if (!has_commands && !has_functions)
+ {
+ input_set_bind_mode(m.sets_mode);
+ return;
+ }
+
+ if (!allow_commands)
+ {
+ /* We don't want to run commands yet. Put the characters back and return
+ R_NULL */
+ for (wcstring::const_reverse_iterator it = m.seq.rbegin(), end = m.seq.rend(); it != end; ++it)
{
- input_function_push_args(code);
+ input_common_next_ch(*it);
}
+ input_common_next_ch(R_NULL);
+ return; /* skip the input_set_bind_mode */
}
-
- idx = m.commands.size();
- while (idx--)
+ else if (has_functions && !has_commands)
{
- wcstring command = m.commands.at(idx);
- wchar_t code = input_function_get_code(command);
- if (code != (wchar_t)-1)
+ /* functions are added at the head of the input queue */
+ for (wcstring_list_t::const_reverse_iterator it = m.commands.rbegin(), end = m.commands.rend (); it != end; it++)
{
+ wchar_t code = input_function_get_code(*it);
+ input_function_push_args(code);
input_common_next_ch(code);
}
- else if (allow_commands)
- {
- /*
- This key sequence is bound to a command, which
- is sent to the parser for evaluation.
- */
- int last_status = proc_get_last_status();
- parser_t::principal_parser().eval(command.c_str(), io_chain_t(), TOP);
-
- proc_set_last_status(last_status);
+ }
+ else if (has_commands && !has_functions)
+ {
+ /* Execute all commands.
- input_common_next_ch(R_NULL);
- }
- else
+ FIXME(snnw): if commands add stuff to input queue (e.g. commandline
+ -f execute), we won't see that until all other commands have also
+ been run. */
+ int last_status = proc_get_last_status();
+ for (wcstring_list_t::const_iterator it = m.commands.begin(), end = m.commands.end(); it != end; it++)
{
- /* We don't want to run commands yet. Put the characters back and return R_NULL */
- for (wcstring::const_reverse_iterator it = m.seq.rbegin(), end = m.seq.rend(); it != end; ++it)
- {
- input_common_next_ch(*it);
- }
- input_common_next_ch(R_NULL);
- return; /* skip the input_set_bind_mode */
+ parser_t::principal_parser().eval(it->c_str(), io_chain_t(), TOP);
}
+ proc_set_last_status(last_status);
+ input_common_next_ch(R_NULL);
+ }
+ else
+ {
+ /* invalid binding, mixed commands and functions. We would need to
+ execute these one by one. */
+ input_common_next_ch(R_NULL);
}
input_set_bind_mode(m.sets_mode);