aboutsummaryrefslogtreecommitdiffhomepage
path: root/builtin.cpp
diff options
context:
space:
mode:
authorGravatar Kevin Ballard <kevin@sb.org>2014-09-22 21:04:06 -0700
committerGravatar Kevin Ballard <kevin@sb.org>2014-09-22 21:04:06 -0700
commit0a3f2205729d13897e86efe2b7d9452000117605 (patch)
treed90226dfbc496312cfa1d4de2b39c503d4ed905e /builtin.cpp
parent5eee7d17f610f58e4e797529f64751c18e237559 (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.cpp125
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)