diff --git a/src/builtin_status.cpp b/src/builtin_status.cpp index c498dd3bd..1aecc9621 100644 --- a/src/builtin_status.cpp +++ b/src/builtin_status.cpp @@ -10,6 +10,7 @@ #include "builtin_status.h" #include "common.h" #include "fallback.h" // IWYU pragma: keep +#include "future_feature_flags.h" #include "io.h" #include "parser.h" #include "proc.h" @@ -31,6 +32,8 @@ enum status_cmd_t { STATUS_LINE_NUMBER, STATUS_SET_JOB_CONTROL, STATUS_STACK_TRACE, + STATUS_FEATURES, + STATUS_TEST_FEATURE, STATUS_UNDEF }; @@ -40,6 +43,7 @@ const enum_map status_enum_map[] = { {STATUS_FILENAME, L"current-filename"}, {STATUS_FUNCTION, L"current-function"}, {STATUS_LINE_NUMBER, L"current-line-number"}, + {STATUS_FEATURES, L"features"}, {STATUS_FILENAME, L"filename"}, {STATUS_FUNCTION, L"function"}, {STATUS_IS_BLOCK, L"is-block"}, @@ -54,6 +58,7 @@ const enum_map status_enum_map[] = { {STATUS_LINE_NUMBER, L"line-number"}, {STATUS_STACK_TRACE, L"print-stack-trace"}, {STATUS_STACK_TRACE, L"stack-trace"}, + {STATUS_TEST_FEATURE, L"test-feature"}, {STATUS_UNDEF, NULL}}; #define status_enum_map_len (sizeof status_enum_map / sizeof *status_enum_map) @@ -66,6 +71,9 @@ const enum_map status_enum_map[] = { break; \ } +/// Values that may be returned from the test-feature option to status. +enum { TEST_FEATURE_ON, TEST_FEATURE_OFF, TEST_FEATURE_NOT_RECOGNIZED }; + int job_control_str_to_mode(const wchar_t *mode, wchar_t *cmd, io_streams_t &streams) { if (wcscmp(mode, L"full") == 0) { return JOB_CONTROL_ALL; @@ -82,6 +90,7 @@ struct status_cmd_opts_t { bool print_help = false; int level = 1; int new_job_control_mode = -1; + const wchar_t *feature_name; status_cmd_t status_cmd = STATUS_UNDEF; }; @@ -126,6 +135,15 @@ static bool set_status_cmd(wchar_t *const cmd, status_cmd_opts_t &opts, status_c return true; } +/// Print the features and their values. +static void print_features(io_streams_t &streams) { + for (const auto &md : features_t::metadata) { + int set = fish_features().test(md.flag); + streams.out.append_format(L"%ls\t%s\t%ls\t%ls\n", md.name, set ? "on" : "off", md.groups, + md.description); + } +} + static int parse_cmd_opts(status_cmd_opts_t &opts, int *optind, //!OCLINT(high ncss method) int argc, wchar_t **argv, parser_t &parser, io_streams_t &streams) { wchar_t *cmd = argv[0]; @@ -307,6 +325,24 @@ int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) { job_control_mode = opts.new_job_control_mode; break; } + case STATUS_FEATURES: { + print_features(streams); + break; + } + case STATUS_TEST_FEATURE: { + if (args.size() != 1) { + const wchar_t *subcmd_str = enum_to_str(opts.status_cmd, status_enum_map); + streams.err.append_format(BUILTIN_ERR_ARG_COUNT2, cmd, subcmd_str, 1, args.size()); + return STATUS_INVALID_ARGS; + } + const auto *metadata = features_t::metadata_for(args.front().c_str()); + if (!metadata) { + retval = TEST_FEATURE_NOT_RECOGNIZED; + } else { + retval = fish_features().test(metadata->flag) ? TEST_FEATURE_ON : TEST_FEATURE_OFF; + } + break; + } case STATUS_FILENAME: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) const wchar_t *fn = parser.current_filename(); diff --git a/tests/status.err b/tests/status.err index 2dc6956a2..855655277 100644 --- a/tests/status.err +++ b/tests/status.err @@ -6,3 +6,6 @@ status: Invalid combination of options, you cannot do both 'is-block' and 'is-interactive' in the same invocation status: Invalid job control mode 'full1' status: Invalid job control mode '1none' + +#################### +# Future Feature Flags diff --git a/tests/status.in b/tests/status.in index ee16ecdad..008255027 100644 --- a/tests/status.in +++ b/tests/status.in @@ -48,4 +48,9 @@ function test_function end test_function -eval test_function \ No newline at end of file +eval test_function + +logmsg Future Feature Flags +status features +status test-feature stderr-nocaret ; echo $status +status test-feature not-a-feature ; echo $status diff --git a/tests/status.out b/tests/status.out index 989264396..1553d674a 100644 --- a/tests/status.out +++ b/tests/status.out @@ -1,3 +1,9 @@ Not a function test_function test_function + +#################### +# Future Feature Flags +stderr-nocaret off 3.0 ^ no longer redirects stderr +1 +2