mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
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.
This commit is contained in:
parent
32936b0eb9
commit
722fedc8fd
1 changed files with 50 additions and 35 deletions
85
input.cpp
85
input.cpp
|
@ -562,45 +562,30 @@ void input_function_push_args(int code)
|
||||||
*/
|
*/
|
||||||
static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
|
static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
|
||||||
{
|
{
|
||||||
/* By default input functions always succeed */
|
/* has_functions: there are functions that need to be put on the input
|
||||||
input_function_status = true;
|
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();
|
for (wcstring_list_t::const_iterator it = m.commands.begin(), end = m.commands.end(); it != end; it++)
|
||||||
while (idx--)
|
|
||||||
{
|
{
|
||||||
wcstring command = m.commands.at(idx);
|
if (input_function_get_code(*it) != -1)
|
||||||
wchar_t code = input_function_get_code(command);
|
has_functions = true;
|
||||||
if (code != (wchar_t)-1)
|
|
||||||
{
|
|
||||||
input_function_push_args(code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = m.commands.size();
|
|
||||||
while (idx--)
|
|
||||||
{
|
|
||||||
wcstring command = m.commands.at(idx);
|
|
||||||
wchar_t code = input_function_get_code(command);
|
|
||||||
if (code != (wchar_t)-1)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
input_common_next_ch(R_NULL);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
has_commands = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* !has_functions && !has_commands: only set bind mode */
|
||||||
|
if (!has_commands && !has_functions)
|
||||||
{
|
{
|
||||||
/* We don't want to run commands yet. Put the characters back and return R_NULL */
|
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)
|
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(*it);
|
||||||
|
@ -608,6 +593,36 @@ static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
|
||||||
input_common_next_ch(R_NULL);
|
input_common_next_ch(R_NULL);
|
||||||
return; /* skip the input_set_bind_mode */
|
return; /* skip the input_set_bind_mode */
|
||||||
}
|
}
|
||||||
|
else if (has_functions && !has_commands)
|
||||||
|
{
|
||||||
|
/* 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 (has_commands && !has_functions)
|
||||||
|
{
|
||||||
|
/* Execute all commands.
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
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);
|
input_set_bind_mode(m.sets_mode);
|
||||||
|
|
Loading…
Reference in a new issue