mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
split builtin bind into its own module
As part of putting the `bind` command code into its own module refactor how it parses its flags.
This commit is contained in:
parent
ed6c8a95d7
commit
a6227f6c3a
6 changed files with 471 additions and 398 deletions
112
Makefile.in
112
Makefile.in
|
@ -98,7 +98,7 @@ HAVE_DOXYGEN=@HAVE_DOXYGEN@
|
|||
#
|
||||
# All objects that the system needs to build fish, except fish.o
|
||||
#
|
||||
FISH_OBJS := obj/autoload.o obj/builtin.o obj/builtin_commandline.o \
|
||||
FISH_OBJS := obj/autoload.o obj/builtin.o obj/builtin_bind.o obj/builtin_commandline.o \
|
||||
obj/builtin_complete.o obj/builtin_jobs.o obj/builtin_printf.o \
|
||||
obj/builtin_set.o obj/builtin_set_color.o obj/builtin_string.o \
|
||||
obj/builtin_test.o obj/builtin_ulimit.o obj/color.o obj/common.o \
|
||||
|
@ -943,10 +943,10 @@ v = $(V$(V))
|
|||
|
||||
obj/autoload.o: config.h src/autoload.h src/common.h src/fallback.h
|
||||
obj/autoload.o: src/signal.h src/lru.h src/env.h src/exec.h src/wutil.h
|
||||
obj/builtin.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin.o: src/signal.h src/builtin_commandline.h src/builtin_complete.h
|
||||
obj/builtin.o: src/builtin_jobs.h src/builtin_printf.h src/builtin_set.h
|
||||
obj/builtin.o: src/builtin_set_color.h src/builtin_string.h
|
||||
obj/builtin.o: config.h src/signal.h src/builtin.h src/common.h
|
||||
obj/builtin.o: src/fallback.h src/builtin_bind.h src/builtin_commandline.h
|
||||
obj/builtin.o: src/builtin_complete.h src/builtin_jobs.h src/builtin_printf.h
|
||||
obj/builtin.o: src/builtin_set.h src/builtin_set_color.h src/builtin_string.h
|
||||
obj/builtin.o: src/builtin_test.h src/builtin_ulimit.h src/complete.h
|
||||
obj/builtin.o: src/env.h src/event.h src/exec.h src/expand.h
|
||||
obj/builtin.o: src/parse_constants.h src/function.h src/highlight.h
|
||||
|
@ -954,12 +954,17 @@ obj/builtin.o: src/color.h src/history.h src/wutil.h src/input.h src/intern.h
|
|||
obj/builtin.o: src/io.h src/parse_util.h src/tokenizer.h src/parser.h
|
||||
obj/builtin.o: src/parse_tree.h src/proc.h src/parser_keywords.h src/path.h
|
||||
obj/builtin.o: src/reader.h src/wcstringutil.h src/wgetopt.h
|
||||
obj/builtin_bind.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_bind.o: src/signal.h src/builtin_bind.h src/env.h src/input.h
|
||||
obj/builtin_bind.o: src/io.h src/tokenizer.h src/wcstringutil.h src/wgetopt.h
|
||||
obj/builtin_bind.o: src/wutil.h
|
||||
obj/builtin_commandline.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_commandline.o: src/signal.h src/input.h src/env.h src/io.h
|
||||
obj/builtin_commandline.o: src/parse_util.h src/parse_constants.h
|
||||
obj/builtin_commandline.o: src/tokenizer.h src/proc.h src/parse_tree.h
|
||||
obj/builtin_commandline.o: src/reader.h src/complete.h src/highlight.h
|
||||
obj/builtin_commandline.o: src/color.h src/util.h src/wgetopt.h src/wutil.h
|
||||
obj/builtin_commandline.o: src/signal.h src/input.h src/builtin_bind.h
|
||||
obj/builtin_commandline.o: src/env.h src/io.h src/parse_util.h
|
||||
obj/builtin_commandline.o: src/parse_constants.h src/tokenizer.h src/proc.h
|
||||
obj/builtin_commandline.o: src/parse_tree.h src/reader.h src/complete.h
|
||||
obj/builtin_commandline.o: src/highlight.h src/color.h src/util.h
|
||||
obj/builtin_commandline.o: src/wgetopt.h src/wutil.h
|
||||
obj/builtin_complete.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_complete.o: src/signal.h src/complete.h src/env.h src/io.h
|
||||
obj/builtin_complete.o: src/parse_constants.h src/parse_util.h
|
||||
|
@ -971,44 +976,44 @@ obj/builtin_jobs.o: src/signal.h src/io.h src/proc.h src/parse_tree.h
|
|||
obj/builtin_jobs.o: src/parse_constants.h src/tokenizer.h src/wgetopt.h
|
||||
obj/builtin_jobs.o: src/wutil.h
|
||||
obj/builtin_printf.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_printf.o: src/signal.h src/io.h src/proc.h src/parse_tree.h
|
||||
obj/builtin_printf.o: src/parse_constants.h src/tokenizer.h src/wutil.h
|
||||
obj/builtin_printf.o: src/signal.h src/io.h src/wutil.h
|
||||
obj/builtin_set.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_set.o: src/signal.h src/env.h src/expand.h src/parse_constants.h
|
||||
obj/builtin_set.o: src/io.h src/proc.h src/parse_tree.h src/tokenizer.h
|
||||
obj/builtin_set.o: src/wgetopt.h src/wutil.h
|
||||
obj/builtin_set_color.o: config.h src/builtin.h src/common.h src/env.h src/fallback.h
|
||||
obj/builtin_set_color.o: src/signal.h src/color.h src/io.h src/output.h
|
||||
obj/builtin_set_color.o: src/proc.h src/parse_tree.h src/parse_constants.h
|
||||
obj/builtin_set_color.o: src/tokenizer.h src/wgetopt.h src/wutil.h
|
||||
obj/builtin_set_color.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_set_color.o: src/signal.h src/color.h src/env.h src/io.h
|
||||
obj/builtin_set_color.o: src/output.h src/wgetopt.h src/wutil.h
|
||||
obj/builtin_string.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_string.o: src/signal.h src/io.h src/parse_util.h
|
||||
obj/builtin_string.o: src/parse_constants.h src/tokenizer.h src/wgetopt.h
|
||||
obj/builtin_string.o: src/wildcard.h src/complete.h src/expand.h src/wutil.h
|
||||
obj/builtin_test.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_test.o: src/signal.h src/io.h src/proc.h src/parse_tree.h
|
||||
obj/builtin_test.o: src/parse_constants.h src/tokenizer.h src/wutil.h
|
||||
obj/builtin_test.o: src/signal.h src/io.h src/wutil.h
|
||||
obj/builtin_ulimit.o: config.h src/builtin.h src/common.h src/fallback.h
|
||||
obj/builtin_ulimit.o: src/signal.h src/io.h src/util.h src/wgetopt.h
|
||||
obj/builtin_ulimit.o: src/wutil.h
|
||||
obj/color.o: config.h src/color.h src/common.h src/fallback.h src/signal.h
|
||||
obj/common.o: config.h src/signal.h src/common.h src/fallback.h src/expand.h
|
||||
obj/common.o: src/parse_constants.h src/wildcard.h src/complete.h src/wutil.h
|
||||
obj/common.o: config.h src/common.h src/fallback.h src/signal.h src/env.h
|
||||
obj/common.o: src/expand.h src/parse_constants.h src/proc.h src/io.h
|
||||
obj/common.o: src/parse_tree.h src/tokenizer.h src/wildcard.h src/complete.h
|
||||
obj/common.o: src/wutil.h
|
||||
obj/complete.o: config.h src/autoload.h src/common.h src/fallback.h
|
||||
obj/complete.o: src/signal.h src/lru.h src/builtin.h src/complete.h src/env.h
|
||||
obj/complete.o: src/exec.h src/expand.h src/parse_constants.h src/function.h
|
||||
obj/complete.o: src/event.h src/iothread.h src/parse_tree.h src/tokenizer.h
|
||||
obj/complete.o: src/parse_util.h src/parser.h src/proc.h src/io.h src/path.h
|
||||
obj/complete.o: src/util.h src/wildcard.h src/wutil.h
|
||||
obj/env.o: config.h src/common.h src/fallback.h src/signal.h src/env.h
|
||||
obj/env.o: src/env_universal_common.h src/wutil.h src/event.h src/expand.h
|
||||
obj/env.o: src/parse_constants.h src/fish_version.h src/history.h src/input.h
|
||||
obj/env.o: src/input_common.h src/path.h src/proc.h src/io.h src/parse_tree.h
|
||||
obj/env.o: config.h src/builtin_bind.h src/common.h src/fallback.h
|
||||
obj/env.o: src/signal.h src/env.h src/env_universal_common.h src/wutil.h
|
||||
obj/env.o: src/event.h src/expand.h src/parse_constants.h src/fish_version.h
|
||||
obj/env.o: src/history.h src/input.h src/input_common.h src/output.h
|
||||
obj/env.o: src/color.h src/path.h src/proc.h src/io.h src/parse_tree.h
|
||||
obj/env.o: src/tokenizer.h src/reader.h src/complete.h src/highlight.h
|
||||
obj/env.o: src/color.h src/sanity.h
|
||||
obj/env.o: src/sanity.h src/screen.h
|
||||
obj/env_universal_common.o: config.h src/common.h src/fallback.h src/signal.h
|
||||
obj/env_universal_common.o: src/env.h src/env_universal_common.h src/wutil.h
|
||||
obj/env_universal_common.o: src/utf8.h src/util.h
|
||||
obj/env_universal_common.o: src/path.h src/utf8.h src/util.h
|
||||
obj/event.o: config.h src/signal.h src/common.h src/fallback.h src/event.h
|
||||
obj/event.o: src/input_common.h src/io.h src/parser.h src/expand.h
|
||||
obj/event.o: src/parse_constants.h src/parse_tree.h src/tokenizer.h
|
||||
|
@ -1027,28 +1032,29 @@ obj/fallback.o: config.h src/signal.h src/common.h src/fallback.h src/util.h
|
|||
obj/fish.o: config.h src/builtin.h src/common.h src/fallback.h src/signal.h
|
||||
obj/fish.o: src/env.h src/event.h src/expand.h src/parse_constants.h
|
||||
obj/fish.o: src/fish_version.h src/function.h src/history.h src/wutil.h
|
||||
obj/fish.o: src/input.h src/io.h src/parser.h src/parse_tree.h
|
||||
obj/fish.o: src/tokenizer.h src/proc.h src/path.h src/reader.h src/complete.h
|
||||
obj/fish.o: src/highlight.h src/color.h
|
||||
obj/fish.o: src/io.h src/parser.h src/parse_tree.h src/tokenizer.h src/proc.h
|
||||
obj/fish.o: src/path.h src/reader.h src/complete.h src/highlight.h
|
||||
obj/fish.o: src/color.h
|
||||
obj/fish_indent.o: config.h src/color.h src/common.h src/fallback.h
|
||||
obj/fish_indent.o: src/signal.h src/env.h src/fish_version.h src/highlight.h
|
||||
obj/fish_indent.o: src/input.h src/output.h src/parse_constants.h
|
||||
obj/fish_indent.o: src/parse_tree.h src/tokenizer.h src/print_help.h
|
||||
obj/fish_indent.o: src/wutil.h
|
||||
obj/fish_indent.o: src/output.h src/parse_constants.h src/parse_tree.h
|
||||
obj/fish_indent.o: src/tokenizer.h src/print_help.h src/wutil.h
|
||||
obj/fish_key_reader.o: config.h src/signal.h src/common.h src/fallback.h
|
||||
obj/fish_key_reader.o: src/env.h src/input.h src/input_common.h
|
||||
obj/fish_key_reader.o: src/print_help.h src/proc.h src/io.h src/parse_tree.h
|
||||
obj/fish_key_reader.o: src/parse_constants.h src/tokenizer.h src/reader.h
|
||||
obj/fish_key_reader.o: src/complete.h src/highlight.h src/color.h src/wutil.h
|
||||
obj/fish_key_reader.o: src/env.h src/input.h src/builtin_bind.h
|
||||
obj/fish_key_reader.o: src/input_common.h src/print_help.h src/proc.h
|
||||
obj/fish_key_reader.o: src/io.h src/parse_tree.h src/parse_constants.h
|
||||
obj/fish_key_reader.o: src/tokenizer.h src/reader.h src/complete.h
|
||||
obj/fish_key_reader.o: src/highlight.h src/color.h src/wutil.h
|
||||
obj/fish_tests.o: config.h src/signal.h src/builtin.h src/common.h
|
||||
obj/fish_tests.o: src/fallback.h src/color.h src/complete.h src/env.h
|
||||
obj/fish_tests.o: src/env_universal_common.h src/wutil.h src/event.h
|
||||
obj/fish_tests.o: src/expand.h src/parse_constants.h src/function.h
|
||||
obj/fish_tests.o: src/highlight.h src/history.h src/input.h
|
||||
obj/fish_tests.o: src/input_common.h src/io.h src/iothread.h src/lru.h
|
||||
obj/fish_tests.o: src/pager.h src/reader.h src/screen.h src/parse_tree.h
|
||||
obj/fish_tests.o: src/tokenizer.h src/parse_util.h src/parser.h src/proc.h
|
||||
obj/fish_tests.o: src/path.h src/utf8.h src/wcstringutil.h src/wildcard.h
|
||||
obj/fish_tests.o: src/builtin_bind.h src/input_common.h src/io.h
|
||||
obj/fish_tests.o: src/iothread.h src/lru.h src/pager.h src/reader.h
|
||||
obj/fish_tests.o: src/screen.h src/parse_tree.h src/tokenizer.h
|
||||
obj/fish_tests.o: src/parse_util.h src/parser.h src/proc.h src/path.h
|
||||
obj/fish_tests.o: src/utf8.h src/util.h src/wcstringutil.h src/wildcard.h
|
||||
obj/fish_version.o: src/fish_version.h
|
||||
obj/function.o: config.h src/autoload.h src/common.h src/fallback.h
|
||||
obj/function.o: src/signal.h src/lru.h src/env.h src/event.h src/function.h
|
||||
|
@ -1064,13 +1070,13 @@ obj/highlight.o: src/wildcard.h src/complete.h
|
|||
obj/history.o: config.h src/common.h src/fallback.h src/signal.h src/env.h
|
||||
obj/history.o: src/history.h src/wutil.h src/io.h src/iothread.h src/lru.h
|
||||
obj/history.o: src/parse_constants.h src/parse_tree.h src/tokenizer.h
|
||||
obj/history.o: src/path.h src/reader.h src/complete.h src/highlight.h
|
||||
obj/history.o: src/color.h
|
||||
obj/history.o: src/parse_util.h src/path.h src/reader.h src/complete.h
|
||||
obj/history.o: src/highlight.h src/color.h
|
||||
obj/input.o: config.h src/common.h src/fallback.h src/signal.h src/env.h
|
||||
obj/input.o: src/event.h src/input.h src/input_common.h src/io.h src/output.h
|
||||
obj/input.o: src/color.h src/parser.h src/expand.h src/parse_constants.h
|
||||
obj/input.o: src/event.h src/input.h src/builtin_bind.h src/input_common.h
|
||||
obj/input.o: src/io.h src/parser.h src/expand.h src/parse_constants.h
|
||||
obj/input.o: src/parse_tree.h src/tokenizer.h src/proc.h src/reader.h
|
||||
obj/input.o: src/complete.h src/highlight.h src/wutil.h
|
||||
obj/input.o: src/complete.h src/highlight.h src/color.h src/wutil.h
|
||||
obj/input_common.o: config.h src/common.h src/fallback.h src/signal.h
|
||||
obj/input_common.o: src/env.h src/env_universal_common.h src/wutil.h
|
||||
obj/input_common.o: src/input_common.h src/iothread.h src/util.h
|
||||
|
@ -1078,7 +1084,7 @@ obj/intern.o: config.h src/common.h src/fallback.h src/signal.h src/intern.h
|
|||
obj/io.o: config.h src/common.h src/fallback.h src/signal.h src/exec.h
|
||||
obj/io.o: src/io.h src/wutil.h
|
||||
obj/iothread.o: config.h src/signal.h src/common.h src/fallback.h
|
||||
obj/iothread.o: src/iothread.h
|
||||
obj/iothread.o: src/iothread.h src/wutil.h
|
||||
obj/kill.o: config.h src/common.h src/fallback.h src/signal.h
|
||||
obj/output.o: config.h src/color.h src/common.h src/fallback.h src/signal.h
|
||||
obj/output.o: src/env.h src/output.h src/wutil.h
|
||||
|
@ -1128,18 +1134,18 @@ obj/proc.o: src/sanity.h src/util.h src/wutil.h
|
|||
obj/reader.o: config.h src/signal.h src/color.h src/common.h src/fallback.h
|
||||
obj/reader.o: src/complete.h src/env.h src/event.h src/exec.h src/expand.h
|
||||
obj/reader.o: src/parse_constants.h src/function.h src/highlight.h
|
||||
obj/reader.o: src/history.h src/wutil.h src/input.h src/input_common.h
|
||||
obj/reader.o: src/intern.h src/io.h src/iothread.h src/kill.h src/output.h
|
||||
obj/reader.o: src/pager.h src/reader.h src/screen.h src/parse_tree.h
|
||||
obj/reader.o: src/tokenizer.h src/parse_util.h src/parser.h src/proc.h
|
||||
obj/reader.o: src/sanity.h src/util.h
|
||||
obj/reader.o: src/history.h src/wutil.h src/input.h src/builtin_bind.h
|
||||
obj/reader.o: src/input_common.h src/intern.h src/io.h src/iothread.h
|
||||
obj/reader.o: src/kill.h src/output.h src/pager.h src/reader.h src/screen.h
|
||||
obj/reader.o: src/parse_tree.h src/tokenizer.h src/parse_util.h src/parser.h
|
||||
obj/reader.o: src/proc.h src/sanity.h src/util.h
|
||||
obj/sanity.o: config.h src/common.h src/fallback.h src/signal.h src/history.h
|
||||
obj/sanity.o: src/wutil.h src/kill.h src/proc.h src/io.h src/parse_tree.h
|
||||
obj/sanity.o: src/parse_constants.h src/tokenizer.h src/reader.h
|
||||
obj/sanity.o: src/complete.h src/highlight.h src/color.h src/env.h
|
||||
obj/sanity.o: src/sanity.h
|
||||
obj/screen.o: config.h src/common.h src/fallback.h src/signal.h
|
||||
obj/screen.o: src/highlight.h src/color.h src/env.h src/output.h src/pager.h
|
||||
obj/screen.o: config.h src/common.h src/fallback.h src/signal.h src/env.h
|
||||
obj/screen.o: src/highlight.h src/color.h src/output.h src/pager.h
|
||||
obj/screen.o: src/complete.h src/reader.h src/parse_constants.h src/screen.h
|
||||
obj/screen.o: src/util.h
|
||||
obj/signal.o: config.h src/signal.h src/common.h src/fallback.h src/event.h
|
||||
|
|
345
src/builtin.cpp
345
src/builtin.cpp
|
@ -38,6 +38,7 @@
|
|||
#include <utility>
|
||||
|
||||
#include "builtin.h"
|
||||
#include "builtin_bind.h"
|
||||
#include "builtin_commandline.h"
|
||||
#include "builtin_complete.h"
|
||||
#include "builtin_jobs.h"
|
||||
|
@ -57,7 +58,6 @@
|
|||
#include "function.h"
|
||||
#include "highlight.h"
|
||||
#include "history.h"
|
||||
#include "input.h"
|
||||
#include "intern.h"
|
||||
#include "io.h"
|
||||
#include "parse_constants.h"
|
||||
|
@ -244,349 +244,6 @@ void builtin_missing_argument(parser_t &parser, io_streams_t &streams, const wch
|
|||
builtin_print_help(parser, streams, cmd, streams.err);
|
||||
}
|
||||
|
||||
// Here follows the definition of all builtin commands. The function names are all of the form
|
||||
// builtin_NAME where NAME is the name of the builtin. so the function name for the builtin 'fg' is
|
||||
// 'builtin_fg'.
|
||||
//
|
||||
// A few builtins, including 'while', 'command' and 'builtin' are not defined here as they are
|
||||
// handled directly by the parser. (They are not parsed as commands, instead they only alter the
|
||||
// parser state)
|
||||
//
|
||||
// The builtins 'break' and 'continue' are so closely related that they share the same
|
||||
// implementation, namely 'builtin_break_continue.
|
||||
//
|
||||
// Several other builtins, including jobs, ulimit and set are so big that they have been given their
|
||||
// own module. These files are all named 'builtin_NAME.cpp', where NAME is the name of the builtin.
|
||||
|
||||
/// List a single key binding.
|
||||
/// Returns false if no binding with that sequence and mode exists.
|
||||
static bool builtin_bind_list_one(const wcstring &seq, const wcstring &bind_mode,
|
||||
io_streams_t &streams) {
|
||||
std::vector<wcstring> ecmds;
|
||||
wcstring sets_mode;
|
||||
|
||||
if (!input_mapping_get(seq, bind_mode, &ecmds, &sets_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
streams.out.append(L"bind");
|
||||
|
||||
// Append the mode flags if applicable.
|
||||
if (bind_mode != DEFAULT_BIND_MODE) {
|
||||
const wcstring emode = escape_string(bind_mode, ESCAPE_ALL);
|
||||
streams.out.append(L" -M ");
|
||||
streams.out.append(emode);
|
||||
}
|
||||
if (!sets_mode.empty() && sets_mode != bind_mode) {
|
||||
const wcstring esets_mode = escape_string(sets_mode, ESCAPE_ALL);
|
||||
streams.out.append(L" -m ");
|
||||
streams.out.append(esets_mode);
|
||||
}
|
||||
|
||||
// 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.
|
||||
streams.out.append_format(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);
|
||||
streams.out.append_format(L" %ls", eseq.c_str());
|
||||
}
|
||||
|
||||
// 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);
|
||||
streams.out.push_back(' ');
|
||||
streams.out.append(escaped_ecmd);
|
||||
}
|
||||
streams.out.push_back(L'\n');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// List all current key bindings.
|
||||
static void builtin_bind_list(const wchar_t *bind_mode, io_streams_t &streams) {
|
||||
const std::vector<input_mapping_name_t> lst = input_mapping_get_names();
|
||||
|
||||
for (const input_mapping_name_t &binding : lst) {
|
||||
if (bind_mode != NULL && bind_mode != binding.mode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
builtin_bind_list_one(binding.seq, binding.mode, streams);
|
||||
}
|
||||
}
|
||||
|
||||
/// Print terminfo key binding names to string buffer used for standard output.
|
||||
///
|
||||
/// \param all if set, all terminfo key binding names will be printed. If not set, only ones that
|
||||
/// are defined for this terminal are printed.
|
||||
static void builtin_bind_key_names(int all, io_streams_t &streams) {
|
||||
const wcstring_list_t names = input_terminfo_get_names(!all);
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
const wcstring &name = names.at(i);
|
||||
|
||||
streams.out.append_format(L"%ls\n", name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/// Print all the special key binding functions to string buffer used for standard output.
|
||||
static void builtin_bind_function_names(io_streams_t &streams) {
|
||||
wcstring_list_t names = input_function_get_names();
|
||||
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
const wchar_t *seq = names.at(i).c_str();
|
||||
streams.out.append_format(L"%ls\n", seq);
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps input_terminfo_get_sequence(), appending the correct error messages as needed.
|
||||
static bool get_terminfo_sequence(const wchar_t *seq, wcstring *out_seq, io_streams_t &streams) {
|
||||
if (input_terminfo_get_sequence(seq, out_seq)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wcstring eseq = escape_string(seq, 0);
|
||||
if (errno == ENOENT) {
|
||||
streams.err.append_format(_(L"%ls: No key with name '%ls' found\n"), L"bind", eseq.c_str());
|
||||
} else if (errno == EILSEQ) {
|
||||
streams.err.append_format(_(L"%ls: Key with name '%ls' does not have any mapping\n"),
|
||||
L"bind", eseq.c_str());
|
||||
} else {
|
||||
streams.err.append_format(_(L"%ls: Unknown error trying to bind to key named '%ls'\n"),
|
||||
L"bind", eseq.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Add specified key binding.
|
||||
static bool builtin_bind_add(const wchar_t *seq, const wchar_t *const *cmds, size_t cmds_len,
|
||||
const wchar_t *mode, const wchar_t *sets_mode, int terminfo,
|
||||
io_streams_t &streams) {
|
||||
if (terminfo) {
|
||||
wcstring seq2;
|
||||
if (get_terminfo_sequence(seq, &seq2, streams)) {
|
||||
input_mapping_add(seq2.c_str(), cmds, cmds_len, mode, sets_mode);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
input_mapping_add(seq, cmds, cmds_len, mode, sets_mode);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Erase specified key bindings
|
||||
///
|
||||
/// @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.
|
||||
/// @param use_terminfo
|
||||
/// Whether to look use terminfo -k name
|
||||
///
|
||||
static bool builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int use_terminfo,
|
||||
io_streams_t &streams) {
|
||||
if (all) {
|
||||
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) {
|
||||
if (mode == NULL || mode == it->mode) {
|
||||
input_mapping_erase(it->seq, it->mode);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
if (mode == NULL) mode = DEFAULT_BIND_MODE; //!OCLINT(parameter reassignment)
|
||||
|
||||
while (*seq) {
|
||||
if (use_terminfo) {
|
||||
wcstring seq2;
|
||||
if (get_terminfo_sequence(*seq++, &seq2, streams)) {
|
||||
input_mapping_erase(seq2, mode);
|
||||
} else {
|
||||
res = true;
|
||||
}
|
||||
} else {
|
||||
input_mapping_erase(*seq++, mode);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// List all current bind modes.
|
||||
static void builtin_bind_list_modes(io_streams_t &streams) {
|
||||
const std::vector<input_mapping_name_t> lst = input_mapping_get_names();
|
||||
// A set accomplishes two things for us here:
|
||||
// - It removes duplicates (no twenty "default" entries).
|
||||
// - It sorts it, which makes it nicer on the user.
|
||||
std::set<wcstring> modes;
|
||||
|
||||
for (const input_mapping_name_t &binding : lst) {
|
||||
modes.insert(binding.mode);
|
||||
}
|
||||
for (const auto &mode : modes) {
|
||||
streams.out.append_format(L"%ls\n", mode.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/// The bind builtin, used for setting character sequences.
|
||||
static int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
enum { BIND_INSERT, BIND_ERASE, BIND_KEY_NAMES, BIND_FUNCTION_NAMES };
|
||||
wchar_t *cmd = argv[0];
|
||||
int argc = builtin_count_args(argv);
|
||||
int mode = BIND_INSERT;
|
||||
int res = STATUS_CMD_OK;
|
||||
bool all = false;
|
||||
bool use_terminfo = false;
|
||||
const wchar_t *bind_mode = DEFAULT_BIND_MODE;
|
||||
bool bind_mode_given = false;
|
||||
const wchar_t *sets_bind_mode = L"";
|
||||
|
||||
static const wchar_t *short_options = L"aehkKfM:Lm:";
|
||||
static const struct woption long_options[] = {{L"all", no_argument, NULL, 'a'},
|
||||
{L"erase", no_argument, NULL, 'e'},
|
||||
{L"function-names", no_argument, NULL, 'f'},
|
||||
{L"help", no_argument, NULL, 'h'},
|
||||
{L"key", no_argument, NULL, 'k'},
|
||||
{L"key-names", no_argument, NULL, 'K'},
|
||||
{L"mode", required_argument, NULL, 'M'},
|
||||
{L"list-modes", no_argument, NULL, 'L'},
|
||||
{L"sets-mode", required_argument, NULL, 'm'},
|
||||
{NULL, 0, NULL, 0}};
|
||||
|
||||
int opt;
|
||||
wgetopter_t w;
|
||||
while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case L'a': {
|
||||
all = true;
|
||||
break;
|
||||
}
|
||||
case L'e': {
|
||||
mode = BIND_ERASE;
|
||||
break;
|
||||
}
|
||||
case L'h': {
|
||||
builtin_print_help(parser, streams, argv[0], streams.out);
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
case L'k': {
|
||||
use_terminfo = true;
|
||||
break;
|
||||
}
|
||||
case L'K': {
|
||||
mode = BIND_KEY_NAMES;
|
||||
break;
|
||||
}
|
||||
case L'f': {
|
||||
mode = BIND_FUNCTION_NAMES;
|
||||
break;
|
||||
}
|
||||
case L'M': {
|
||||
if (!valid_var_name(w.woptarg)) {
|
||||
streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
bind_mode = w.woptarg;
|
||||
bind_mode_given = true;
|
||||
break;
|
||||
}
|
||||
case L'm': {
|
||||
if (!valid_var_name(w.woptarg)) {
|
||||
streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
sets_bind_mode = w.woptarg;
|
||||
break;
|
||||
}
|
||||
case L'L': {
|
||||
builtin_bind_list_modes(streams);
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
case L'?': {
|
||||
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
default: {
|
||||
DIE("unexpected retval from wgetopt_long");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case BIND_ERASE: {
|
||||
if (builtin_bind_erase(&argv[w.woptind], all, bind_mode_given ? bind_mode : NULL,
|
||||
use_terminfo, streams)) {
|
||||
res = STATUS_CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BIND_INSERT: {
|
||||
int arg_count = argc - w.woptind;
|
||||
if (arg_count == 0) {
|
||||
builtin_bind_list(bind_mode_given ? bind_mode : NULL, streams);
|
||||
} else if (arg_count == 1) {
|
||||
wcstring seq;
|
||||
if (use_terminfo) {
|
||||
if (!get_terminfo_sequence(argv[w.woptind], &seq, streams)) {
|
||||
res = STATUS_CMD_ERROR;
|
||||
// get_terminfo_sequence already printed the error.
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
seq = argv[w.woptind];
|
||||
}
|
||||
if (!builtin_bind_list_one(seq, bind_mode, streams)) {
|
||||
res = STATUS_CMD_ERROR;
|
||||
wcstring eseq = escape_string(argv[w.woptind], 0);
|
||||
if (use_terminfo) {
|
||||
streams.err.append_format(_(L"%ls: No binding found for key '%ls'\n"),
|
||||
argv[0], eseq.c_str());
|
||||
} else {
|
||||
streams.err.append_format(_(L"%ls: No binding found for sequence '%ls'\n"),
|
||||
argv[0], eseq.c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (builtin_bind_add(argv[w.woptind], argv + (w.woptind + 1),
|
||||
argc - (w.woptind + 1), bind_mode, sets_bind_mode,
|
||||
use_terminfo, streams)) {
|
||||
res = STATUS_CMD_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BIND_KEY_NAMES: {
|
||||
builtin_bind_key_names(all, streams);
|
||||
break;
|
||||
}
|
||||
case BIND_FUNCTION_NAMES: {
|
||||
builtin_bind_function_names(streams);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
res = STATUS_CMD_ERROR;
|
||||
streams.err.append_format(_(L"%ls: Invalid state\n"), argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// The block builtin, used for temporarily blocking events.
|
||||
static int builtin_block(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
enum {
|
||||
|
|
398
src/builtin_bind.cpp
Normal file
398
src/builtin_bind.cpp
Normal file
|
@ -0,0 +1,398 @@
|
|||
// Implementation of the bind builtin.
|
||||
#include "config.h" // IWYU pragma: keep
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "builtin.h"
|
||||
#include "builtin_bind.h"
|
||||
#include "common.h"
|
||||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "input.h" // IWYU pragma: keep
|
||||
#include "io.h" // IWYU pragma: keep
|
||||
#include "wgetopt.h"
|
||||
#include "wutil.h" // IWYU pragma: keep
|
||||
|
||||
enum { BIND_INSERT, BIND_ERASE, BIND_KEY_NAMES, BIND_FUNCTION_NAMES };
|
||||
struct bind_opts {
|
||||
int mode = BIND_INSERT;
|
||||
int res = STATUS_CMD_OK;
|
||||
bool all = false;
|
||||
bool use_terminfo = false;
|
||||
const wchar_t *bind_mode = DEFAULT_BIND_MODE;
|
||||
bool bind_mode_given = false;
|
||||
bool list_modes = false;
|
||||
bool print_help = false;
|
||||
const wchar_t *sets_bind_mode = L"";
|
||||
};
|
||||
|
||||
// Here follows the definition of all builtin commands. The function names are all of the form
|
||||
// builtin_NAME where NAME is the name of the builtin. so the function name for the builtin 'fg' is
|
||||
// 'builtin_fg'.
|
||||
//
|
||||
// A few builtins, including 'while', 'command' and 'builtin' are not defined here as they are
|
||||
// handled directly by the parser. (They are not parsed as commands, instead they only alter the
|
||||
// parser state)
|
||||
//
|
||||
// The builtins 'break' and 'continue' are so closely related that they share the same
|
||||
// implementation, namely 'builtin_break_continue.
|
||||
//
|
||||
// Several other builtins, including jobs, ulimit and set are so big that they have been given their
|
||||
// own module. These files are all named 'builtin_NAME.cpp', where NAME is the name of the builtin.
|
||||
|
||||
/// List a single key binding.
|
||||
/// Returns false if no binding with that sequence and mode exists.
|
||||
static bool builtin_bind_list_one(const wcstring &seq, const wcstring &bind_mode,
|
||||
io_streams_t &streams) {
|
||||
std::vector<wcstring> ecmds;
|
||||
wcstring sets_mode;
|
||||
|
||||
if (!input_mapping_get(seq, bind_mode, &ecmds, &sets_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
streams.out.append(L"bind");
|
||||
|
||||
// Append the mode flags if applicable.
|
||||
if (bind_mode != DEFAULT_BIND_MODE) {
|
||||
const wcstring emode = escape_string(bind_mode, ESCAPE_ALL);
|
||||
streams.out.append(L" -M ");
|
||||
streams.out.append(emode);
|
||||
}
|
||||
if (!sets_mode.empty() && sets_mode != bind_mode) {
|
||||
const wcstring esets_mode = escape_string(sets_mode, ESCAPE_ALL);
|
||||
streams.out.append(L" -m ");
|
||||
streams.out.append(esets_mode);
|
||||
}
|
||||
|
||||
// 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.
|
||||
streams.out.append_format(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);
|
||||
streams.out.append_format(L" %ls", eseq.c_str());
|
||||
}
|
||||
|
||||
// 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);
|
||||
streams.out.push_back(' ');
|
||||
streams.out.append(escaped_ecmd);
|
||||
}
|
||||
streams.out.push_back(L'\n');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// List all current key bindings.
|
||||
static void builtin_bind_list(const wchar_t *bind_mode, io_streams_t &streams) {
|
||||
const std::vector<input_mapping_name_t> lst = input_mapping_get_names();
|
||||
|
||||
for (const input_mapping_name_t &binding : lst) {
|
||||
if (bind_mode && bind_mode != binding.mode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
builtin_bind_list_one(binding.seq, binding.mode, streams);
|
||||
}
|
||||
}
|
||||
|
||||
/// Print terminfo key binding names to string buffer used for standard output.
|
||||
///
|
||||
/// \param all if set, all terminfo key binding names will be printed. If not set, only ones that
|
||||
/// are defined for this terminal are printed.
|
||||
static void builtin_bind_key_names(int all, io_streams_t &streams) {
|
||||
const wcstring_list_t names = input_terminfo_get_names(!all);
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
const wcstring &name = names.at(i);
|
||||
|
||||
streams.out.append_format(L"%ls\n", name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/// Print all the special key binding functions to string buffer used for standard output.
|
||||
static void builtin_bind_function_names(io_streams_t &streams) {
|
||||
wcstring_list_t names = input_function_get_names();
|
||||
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
const wchar_t *seq = names.at(i).c_str();
|
||||
streams.out.append_format(L"%ls\n", seq);
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps input_terminfo_get_sequence(), appending the correct error messages as needed.
|
||||
static bool get_terminfo_sequence(const wchar_t *seq, wcstring *out_seq, io_streams_t &streams) {
|
||||
if (input_terminfo_get_sequence(seq, out_seq)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wcstring eseq = escape_string(seq, 0);
|
||||
if (errno == ENOENT) {
|
||||
streams.err.append_format(_(L"%ls: No key with name '%ls' found\n"), L"bind", eseq.c_str());
|
||||
} else if (errno == EILSEQ) {
|
||||
streams.err.append_format(_(L"%ls: Key with name '%ls' does not have any mapping\n"),
|
||||
L"bind", eseq.c_str());
|
||||
} else {
|
||||
streams.err.append_format(_(L"%ls: Unknown error trying to bind to key named '%ls'\n"),
|
||||
L"bind", eseq.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Add specified key binding.
|
||||
static bool builtin_bind_add(const wchar_t *seq, const wchar_t *const *cmds, size_t cmds_len,
|
||||
const wchar_t *mode, const wchar_t *sets_mode, int terminfo,
|
||||
io_streams_t &streams) {
|
||||
if (terminfo) {
|
||||
wcstring seq2;
|
||||
if (get_terminfo_sequence(seq, &seq2, streams)) {
|
||||
input_mapping_add(seq2.c_str(), cmds, cmds_len, mode, sets_mode);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
input_mapping_add(seq, cmds, cmds_len, mode, sets_mode);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Erase specified key bindings
|
||||
///
|
||||
/// @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.
|
||||
/// @param use_terminfo
|
||||
/// Whether to look use terminfo -k name
|
||||
///
|
||||
static bool builtin_bind_erase(wchar_t **seq, int all, const wchar_t *mode, int use_terminfo,
|
||||
io_streams_t &streams) {
|
||||
if (all) {
|
||||
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) {
|
||||
if (mode == NULL || mode == it->mode) {
|
||||
input_mapping_erase(it->seq, it->mode);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
if (mode == NULL) mode = DEFAULT_BIND_MODE; //!OCLINT(parameter reassignment)
|
||||
|
||||
while (*seq) {
|
||||
if (use_terminfo) {
|
||||
wcstring seq2;
|
||||
if (get_terminfo_sequence(*seq++, &seq2, streams)) {
|
||||
input_mapping_erase(seq2, mode);
|
||||
} else {
|
||||
res = true;
|
||||
}
|
||||
} else {
|
||||
input_mapping_erase(*seq++, mode);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool builtin_bind_insert(struct bind_opts *opts, int optind, int argc, wchar_t **argv,
|
||||
io_streams_t &streams) {
|
||||
wchar_t *cmd = argv[0];
|
||||
int arg_count = argc - optind;
|
||||
|
||||
if (arg_count == 0) {
|
||||
builtin_bind_list(opts->bind_mode_given ? opts->bind_mode : NULL, streams);
|
||||
} else if (arg_count == 1) {
|
||||
wcstring seq;
|
||||
if (opts->use_terminfo) {
|
||||
if (!get_terminfo_sequence(argv[optind], &seq, streams)) {
|
||||
// get_terminfo_sequence already printed the error.
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
seq = argv[optind];
|
||||
}
|
||||
|
||||
if (!builtin_bind_list_one(seq, opts->bind_mode, streams)) {
|
||||
wcstring eseq = escape_string(argv[optind], 0);
|
||||
if (opts->use_terminfo) {
|
||||
streams.err.append_format(_(L"%ls: No binding found for key '%ls'\n"), cmd,
|
||||
eseq.c_str());
|
||||
} else {
|
||||
streams.err.append_format(_(L"%ls: No binding found for sequence '%ls'\n"), cmd,
|
||||
eseq.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (builtin_bind_add(argv[optind], argv + (optind + 1), argc - (optind + 1),
|
||||
opts->bind_mode, opts->sets_bind_mode, opts->use_terminfo, streams)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// List all current bind modes.
|
||||
static void builtin_bind_list_modes(io_streams_t &streams) {
|
||||
const std::vector<input_mapping_name_t> lst = input_mapping_get_names();
|
||||
// A set accomplishes two things for us here:
|
||||
// - It removes duplicates (no twenty "default" entries).
|
||||
// - It sorts it, which makes it nicer on the user.
|
||||
std::set<wcstring> modes;
|
||||
|
||||
for (const input_mapping_name_t &binding : lst) {
|
||||
modes.insert(binding.mode);
|
||||
}
|
||||
for (const auto &mode : modes) {
|
||||
streams.out.append_format(L"%ls\n", mode.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_bind_opts(struct bind_opts *opts, int *optind, //!OCLINT(high ncss method)
|
||||
int argc, wchar_t **argv, parser_t &parser, io_streams_t &streams) {
|
||||
wchar_t *cmd = argv[0];
|
||||
static const wchar_t *short_options = L"aehkKfM:Lm:";
|
||||
static const struct woption long_options[] = {{L"all", no_argument, NULL, 'a'},
|
||||
{L"erase", no_argument, NULL, 'e'},
|
||||
{L"function-names", no_argument, NULL, 'f'},
|
||||
{L"help", no_argument, NULL, 'h'},
|
||||
{L"key", no_argument, NULL, 'k'},
|
||||
{L"key-names", no_argument, NULL, 'K'},
|
||||
{L"mode", required_argument, NULL, 'M'},
|
||||
{L"list-modes", no_argument, NULL, 'L'},
|
||||
{L"sets-mode", required_argument, NULL, 'm'},
|
||||
{NULL, 0, NULL, 0}};
|
||||
|
||||
int opt;
|
||||
wgetopter_t w;
|
||||
while ((opt = w.wgetopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case L'a': {
|
||||
opts->all = true;
|
||||
break;
|
||||
}
|
||||
case L'e': {
|
||||
opts->mode = BIND_ERASE;
|
||||
break;
|
||||
}
|
||||
case L'h': {
|
||||
opts->print_help = true;
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
case L'k': {
|
||||
opts->use_terminfo = true;
|
||||
break;
|
||||
}
|
||||
case L'K': {
|
||||
opts->mode = BIND_KEY_NAMES;
|
||||
break;
|
||||
}
|
||||
case L'f': {
|
||||
opts->mode = BIND_FUNCTION_NAMES;
|
||||
break;
|
||||
}
|
||||
case L'M': {
|
||||
if (!valid_var_name(w.woptarg)) {
|
||||
streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
opts->bind_mode = w.woptarg;
|
||||
opts->bind_mode_given = true;
|
||||
break;
|
||||
}
|
||||
case L'm': {
|
||||
if (!valid_var_name(w.woptarg)) {
|
||||
streams.err.append_format(BUILTIN_ERR_BIND_MODE, cmd, w.woptarg);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
opts->sets_bind_mode = w.woptarg;
|
||||
break;
|
||||
}
|
||||
case L'L': {
|
||||
opts->list_modes = true;
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
case L'?': {
|
||||
builtin_unknown_option(parser, streams, argv[0], argv[w.woptind - 1]);
|
||||
return STATUS_INVALID_ARGS;
|
||||
}
|
||||
default: {
|
||||
DIE("unexpected retval from wgetopt_long");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*optind = w.woptind;
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
|
||||
/// The bind builtin, used for setting character sequences.
|
||||
int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wchar_t *cmd = argv[0];
|
||||
int argc = builtin_count_args(argv);
|
||||
struct bind_opts opts;
|
||||
|
||||
int optind;
|
||||
int retval = parse_bind_opts(&opts, &optind, argc, argv, parser, streams);
|
||||
if (retval != STATUS_CMD_OK) return retval;
|
||||
|
||||
if (opts.list_modes) {
|
||||
builtin_bind_list_modes(streams);
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
if (opts.print_help) {
|
||||
builtin_print_help(parser, streams, cmd, streams.out);
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
|
||||
switch (opts.mode) {
|
||||
case BIND_ERASE: {
|
||||
const wchar_t *bind_mode = opts.bind_mode_given ? opts.bind_mode : NULL;
|
||||
if (builtin_bind_erase(&argv[optind], opts.all, bind_mode, opts.use_terminfo,
|
||||
streams)) {
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BIND_INSERT: {
|
||||
if (builtin_bind_insert(&opts, optind, argc, argv, streams)) {
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BIND_KEY_NAMES: {
|
||||
builtin_bind_key_names(opts.all, streams);
|
||||
break;
|
||||
}
|
||||
case BIND_FUNCTION_NAMES: {
|
||||
builtin_bind_function_names(streams);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
streams.err.append_format(_(L"%ls: Invalid state\n"), cmd);
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_CMD_OK;
|
||||
}
|
11
src/builtin_bind.h
Normal file
11
src/builtin_bind.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Prototypes for functions for executing builtin_bind functions.
|
||||
#ifndef FISH_BUILTIN_BIND_H
|
||||
#define FISH_BUILTIN_BIND_H
|
||||
|
||||
#define DEFAULT_BIND_MODE L"default"
|
||||
|
||||
class parser_t;
|
||||
struct io_streams_t;
|
||||
|
||||
int builtin_bind(parser_t &parser, io_streams_t &streams, wchar_t **argv);
|
||||
#endif
|
|
@ -36,6 +36,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "builtin_bind.h"
|
||||
#include "common.h"
|
||||
#include "env.h"
|
||||
#include "env_universal_common.h"
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "builtin_bind.h"
|
||||
#include "common.h"
|
||||
#include "env.h"
|
||||
|
||||
#define DEFAULT_BIND_MODE L"default"
|
||||
#define FISH_BIND_MODE_VAR L"fish_bind_mode"
|
||||
|
||||
wcstring describe_char(wint_t c);
|
||||
|
|
Loading…
Reference in a new issue