mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-29 21:43:55 +08:00
self-insert bindings to insert their own sequence
Prior to this fix, self-insert would always wait for a new character. Track in char_event what sequence generated the readline event, and then if the sequence is not empty, insert that sequence. This will support implementing the space binding via pure readline functions.
This commit is contained in:
parent
1ecbe363d0
commit
18b56637f7
|
@ -377,7 +377,7 @@ void inputter_t::mapping_execute(const input_mapping_t &m, bool allow_commands)
|
||||||
it != end; ++it) {
|
it != end; ++it) {
|
||||||
readline_cmd_t code = input_function_get_code(*it).value();
|
readline_cmd_t code = input_function_get_code(*it).value();
|
||||||
function_push_args(code);
|
function_push_args(code);
|
||||||
event_queue_.push_front(code);
|
event_queue_.push_front(char_event_t(code, m.seq));
|
||||||
}
|
}
|
||||||
} else if (has_commands && !has_functions) {
|
} else if (has_commands && !has_functions) {
|
||||||
// Execute all commands.
|
// Execute all commands.
|
||||||
|
@ -404,7 +404,7 @@ void inputter_t::mapping_execute(const input_mapping_t &m, bool allow_commands)
|
||||||
bool inputter_t::mapping_is_match(const input_mapping_t &m) {
|
bool inputter_t::mapping_is_match(const input_mapping_t &m) {
|
||||||
const wcstring &str = m.seq;
|
const wcstring &str = m.seq;
|
||||||
|
|
||||||
assert(str.size() > 0 && "zero-length input string passed to input_mapping_is_match!");
|
assert(str.size() > 0 && "zero-length input string passed to mapping_is_match!");
|
||||||
|
|
||||||
bool timed = false;
|
bool timed = false;
|
||||||
for (size_t i = 0; i < str.size(); ++i) {
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
|
@ -495,6 +495,11 @@ char_event_t inputter_t::readch(bool allow_commands) {
|
||||||
if (evt.is_readline()) {
|
if (evt.is_readline()) {
|
||||||
switch (evt.get_readline()) {
|
switch (evt.get_readline()) {
|
||||||
case readline_cmd_t::self_insert: {
|
case readline_cmd_t::self_insert: {
|
||||||
|
// Typically self-insert is generated by the generic (empty) binding.
|
||||||
|
// However if it is generated by a real sequence, then insert that sequence.
|
||||||
|
for (auto iter = evt.seq.crbegin(); iter != evt.seq.crend(); ++iter) {
|
||||||
|
event_queue_.push_front(*iter);
|
||||||
|
}
|
||||||
// Issue #1595: ensure we only insert characters, not readline functions. The
|
// Issue #1595: ensure we only insert characters, not readline functions. The
|
||||||
// common case is that this will be empty.
|
// common case is that this will be empty.
|
||||||
return read_characters_no_readline();
|
return read_characters_no_readline();
|
||||||
|
|
|
@ -105,8 +105,13 @@ class char_event_t {
|
||||||
} v_{};
|
} v_{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// The type of event.
|
||||||
char_event_type_t type;
|
char_event_type_t type;
|
||||||
|
|
||||||
|
/// The sequence of characters in the input mapping which generated this event.
|
||||||
|
/// Note that the generic self-insert case does not have any characters, so this would be empty.
|
||||||
|
wcstring seq{};
|
||||||
|
|
||||||
bool is_timeout() const { return type == char_event_type_t::timeout; }
|
bool is_timeout() const { return type == char_event_type_t::timeout; }
|
||||||
|
|
||||||
bool is_char() const { return type == char_event_type_t::charc; }
|
bool is_char() const { return type == char_event_type_t::charc; }
|
||||||
|
@ -129,7 +134,8 @@ class char_event_t {
|
||||||
|
|
||||||
/* implicit */ char_event_t(wchar_t c) : type(char_event_type_t::charc) { v_.c = c; }
|
/* implicit */ char_event_t(wchar_t c) : type(char_event_type_t::charc) { v_.c = c; }
|
||||||
|
|
||||||
/* implicit */ char_event_t(readline_cmd_t rl) : type(char_event_type_t::readline) {
|
/* implicit */ char_event_t(readline_cmd_t rl, wcstring seq = {})
|
||||||
|
: type(char_event_type_t::readline), seq(std::move(seq)) {
|
||||||
v_.rl = rl;
|
v_.rl = rl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user