diff options
author | 2014-09-22 21:04:06 -0700 | |
---|---|---|
committer | 2014-09-22 21:04:06 -0700 | |
commit | 0a3f2205729d13897e86efe2b7d9452000117605 (patch) | |
tree | d90226dfbc496312cfa1d4de2b39c503d4ed905e /builtin.cpp | |
parent | 5eee7d17f610f58e4e797529f64751c18e237559 (diff) |
Rework mode handling of `bind`
Binds with the same sequence in multiple modes was not working right.
Fix up the implementation to propagate modes everywhere as necessary.
This means that `bind` will properly list distinct binds with the same
sequence, and `bind -e` will take mode into account properly as well.
Note that `bind -e seq` now assumes the bind is in the default bind
mode, whereas before it would erase the first binding with that sequence
regardless of mode.
`bind -e -a` still erases all binds in all modes, though `bind -M mode
-e -a` still only erases all binds in the selected mode.
Diffstat (limited to 'builtin.cpp')
-rw-r--r-- | builtin.cpp | 125 |
1 files changed, 71 insertions, 54 deletions
diff --git a/builtin.cpp b/builtin.cpp index 190841fd..ab258acd 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -400,70 +400,79 @@ static void builtin_missing_argument(parser_t &parser, const wchar_t *cmd, const int builtin_test(parser_t &parser, wchar_t **argv); /** - List all current key bindings + List a single key binding. + Returns false if no binding with that sequence and mode exists. */ -static void builtin_bind_list(const wchar_t *bind_mode) +static bool builtin_bind_list_one(const wcstring& seq, const wcstring& bind_mode) { - size_t i; - const wcstring_list_t lst = input_mapping_get_names(); + std::vector<wcstring> ecmds; + wcstring sets_mode; - for (i=0; i<lst.size(); i++) + if (!input_mapping_get(seq, bind_mode, &ecmds, &sets_mode)) { - wcstring seq = lst.at(i); + return false; + } - std::vector<wcstring> ecmds; - wcstring mode; - wcstring sets_mode; + stdout_buffer.append(L"bind"); - if (! input_mapping_get(seq, &ecmds, &mode, &sets_mode)) - { - continue; - } + // Append the mode flags if applicable + if (bind_mode != DEFAULT_BIND_MODE) + { + const wcstring emode = escape_string(bind_mode, ESCAPE_ALL); + stdout_buffer.append(L" -M "); + stdout_buffer.append(emode); + } + if (sets_mode != bind_mode) + { + const wcstring esets_mode = escape_string(sets_mode, ESCAPE_ALL); + stdout_buffer.append(L" -m "); + stdout_buffer.append(esets_mode); + } - if (bind_mode != NULL && bind_mode != mode) - { - continue; - } + // Append the name + wcstring tname; + if (input_terminfo_get_name(seq, &tname)) + { + // Note that we show -k here because we have an input key name + append_format(stdout_buffer, L" -k %ls", tname.c_str()); + } + else + { + // No key name, so no -k; we show the escape sequence directly + const wcstring eseq = escape_string(seq, ESCAPE_ALL); + append_format(stdout_buffer, L" %ls", eseq.c_str()); + } - stdout_buffer.append(L"bind"); + // Now show the list of commands + for (size_t i = 0; i < ecmds.size(); i++) + { + const wcstring &ecmd = ecmds.at(i); + const wcstring escaped_ecmd = escape_string(ecmd, ESCAPE_ALL); + stdout_buffer.push_back(' '); + stdout_buffer.append(escaped_ecmd); + } + stdout_buffer.push_back(L'\n'); - // Append the mode flags if applicable - if (mode != DEFAULT_BIND_MODE) - { - const wcstring emode = escape_string(mode, ESCAPE_ALL); - stdout_buffer.append(L" -M "); - stdout_buffer.append(emode); - } - if (sets_mode != mode) - { - const wcstring esets_mode = escape_string(sets_mode, ESCAPE_ALL); - stdout_buffer.append(L" -m "); - stdout_buffer.append(esets_mode); - } + return true; +} - // Append the name - wcstring tname; - if (input_terminfo_get_name(seq, &tname)) - { - // Note that we show -k here because we have an input key name - append_format(stdout_buffer, L" -k %ls", tname.c_str()); - } - else - { - // No key name, so no -k; we show the escape sequence directly - const wcstring eseq = escape_string(seq, ESCAPE_ALL); - append_format(stdout_buffer, L" %ls", eseq.c_str()); - } +/** + List all current key bindings + */ +static void builtin_bind_list(const wchar_t *bind_mode) +{ + const std::vector<input_mapping_name_t> lst = input_mapping_get_names(); - // Now show the list of commands - for (size_t i = 0; i < ecmds.size(); i++) + for (std::vector<input_mapping_name_t>::const_iterator it = lst.begin(), end = lst.end(); + it != end; + ++it) + { + if (bind_mode != NULL && bind_mode != it->mode) { - const wcstring &ecmd = ecmds.at(i); - const wcstring escaped_ecmd = escape_string(ecmd, ESCAPE_ALL); - stdout_buffer.push_back(' '); - stdout_buffer.append(escaped_ecmd); + continue; } - stdout_buffer.push_back(L'\n'); + + builtin_bind_list_one(it->seq, it->mode); } } @@ -564,15 +573,21 @@ static int builtin_bind_add(const wchar_t *seq, const wchar_t **cmds, size_t cmd \param seq an array of all key bindings to erase \param all if specified, _all_ key bindings will be erased + \param mode if specified, only bindings from that mode will be erased. If not given and \c all is \c false, \c DEFAULT_BIND_MODE will be used. */ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int use_terminfo) { if (all) { - const wcstring_list_t lst = input_mapping_get_names(); - for (size_t i=0; i<lst.size(); i++) + const std::vector<input_mapping_name_t> lst = input_mapping_get_names(); + for (std::vector<input_mapping_name_t>::const_iterator it = lst.begin(), end = lst.end(); + it != end; + ++it) { - input_mapping_erase(lst.at(i).c_str(), mode); + if (mode == NULL || mode == it->mode) + { + input_mapping_erase(it->seq, it->mode); + } } return 0; @@ -581,6 +596,8 @@ static int builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int u { int res = 0; + if (mode == NULL) mode = DEFAULT_BIND_MODE; + while (*seq) { if (use_terminfo) |