aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--input.cpp29
-rw-r--r--input.h6
-rw-r--r--reader.cpp5
3 files changed, 31 insertions, 9 deletions
diff --git a/input.cpp b/input.cpp
index 128fe0fb..0d7a91be 100644
--- a/input.cpp
+++ b/input.cpp
@@ -549,8 +549,10 @@ void input_function_push_args(int code)
/**
Perform the action of the specified binding
+ allow_commands controls whether fish commands should be executed, or should
+ be deferred until later.
*/
-static void input_mapping_execute(const input_mapping_t &m)
+static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
{
/* By default input functions always succeed */
input_function_status = true;
@@ -575,7 +577,7 @@ static void input_mapping_execute(const input_mapping_t &m)
{
input_unreadch(code);
}
- else
+ else if (allow_commands)
{
/*
This key sequence is bound to a command, which
@@ -588,6 +590,16 @@ static void input_mapping_execute(const input_mapping_t &m)
input_unreadch(R_NULL);
}
+ else
+ {
+ /* 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_unreadch(*it);
+ }
+ input_unreadch(R_NULL);
+ return; /* skip the input_set_bind_mode */
+ }
}
input_set_bind_mode(m.sets_mode.c_str());
@@ -644,7 +656,7 @@ void input_unreadch(wint_t ch)
input_common_unreadch(ch);
}
-static void input_mapping_execute_matching_or_generic()
+static void input_mapping_execute_matching_or_generic(bool allow_commands)
{
const input_mapping_t *generic = NULL;
@@ -669,14 +681,14 @@ static void input_mapping_execute_matching_or_generic()
}
else if (input_mapping_is_match(m))
{
- input_mapping_execute(m);
+ input_mapping_execute(m, allow_commands);
return;
}
}
if (generic)
{
- input_mapping_execute(*generic);
+ input_mapping_execute(*generic, allow_commands);
}
else
{
@@ -687,7 +699,7 @@ static void input_mapping_execute_matching_or_generic()
}
}
-wint_t input_readch()
+wint_t input_readch(bool allow_commands)
{
CHECK_BLOCK(R_NULL);
@@ -738,7 +750,10 @@ wint_t input_readch()
else
{
input_unreadch(c);
- input_mapping_execute_matching_or_generic();
+ input_mapping_execute_matching_or_generic(allow_commands);
+ // regarding allow_commands, we're in a loop, but if a fish command
+ // is executed, R_NULL is unread, so the next pass through the loop
+ // we'll break out and return it.
}
}
}
diff --git a/input.h b/input.h
index 1ab43c03..18d0d2b6 100644
--- a/input.h
+++ b/input.h
@@ -103,8 +103,12 @@ void input_destroy();
readch attempts to parse it. If no more input follows after the
escape key, it is assumed to be an actual escape key press, and is
returned as such.
+
+ The argument determines whether fish commands are allowed to be run
+ as bindings. If false, when a character is encountered that would
+ invoke a fish command, it is unread and R_NULL is returned.
*/
-wint_t input_readch();
+wint_t input_readch(bool allow_commands = true);
/**
Push a character or a readline function onto the stack of unread
diff --git a/reader.cpp b/reader.cpp
index bb3b57fc..c45e62b2 100644
--- a/reader.cpp
+++ b/reader.cpp
@@ -3117,7 +3117,10 @@ const wchar_t *reader_readline(void)
c = 0;
break;
}
- c = input_readch();
+ // only allow commands on the first key; otherwise, we might
+ // have data we need to insert on the commandline that the
+ // commmand might need to be able to see.
+ c = input_readch(i == 1);
if ((!wchar_private(c)) && (c>31) && (c != 127))
{
arr[i]=c;