mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 12:23:09 +00:00
Add status subcomannds: features and test-feature
This teaches the status command to work with features. 'status features' will show a table listing all known features and whether they are currently on or off. `status test-feature` will test an individual feature, setting the exit status to 0 if the feature is on, 1 if off, 2 if unknown.
This commit is contained in:
parent
14f766b66d
commit
782cae2d21
4 changed files with 51 additions and 1 deletions
|
@ -10,6 +10,7 @@
|
||||||
#include "builtin_status.h"
|
#include "builtin_status.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "fallback.h" // IWYU pragma: keep
|
#include "fallback.h" // IWYU pragma: keep
|
||||||
|
#include "future_feature_flags.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
|
@ -31,6 +32,8 @@ enum status_cmd_t {
|
||||||
STATUS_LINE_NUMBER,
|
STATUS_LINE_NUMBER,
|
||||||
STATUS_SET_JOB_CONTROL,
|
STATUS_SET_JOB_CONTROL,
|
||||||
STATUS_STACK_TRACE,
|
STATUS_STACK_TRACE,
|
||||||
|
STATUS_FEATURES,
|
||||||
|
STATUS_TEST_FEATURE,
|
||||||
STATUS_UNDEF
|
STATUS_UNDEF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,6 +43,7 @@ const enum_map<status_cmd_t> status_enum_map[] = {
|
||||||
{STATUS_FILENAME, L"current-filename"},
|
{STATUS_FILENAME, L"current-filename"},
|
||||||
{STATUS_FUNCTION, L"current-function"},
|
{STATUS_FUNCTION, L"current-function"},
|
||||||
{STATUS_LINE_NUMBER, L"current-line-number"},
|
{STATUS_LINE_NUMBER, L"current-line-number"},
|
||||||
|
{STATUS_FEATURES, L"features"},
|
||||||
{STATUS_FILENAME, L"filename"},
|
{STATUS_FILENAME, L"filename"},
|
||||||
{STATUS_FUNCTION, L"function"},
|
{STATUS_FUNCTION, L"function"},
|
||||||
{STATUS_IS_BLOCK, L"is-block"},
|
{STATUS_IS_BLOCK, L"is-block"},
|
||||||
|
@ -54,6 +58,7 @@ const enum_map<status_cmd_t> status_enum_map[] = {
|
||||||
{STATUS_LINE_NUMBER, L"line-number"},
|
{STATUS_LINE_NUMBER, L"line-number"},
|
||||||
{STATUS_STACK_TRACE, L"print-stack-trace"},
|
{STATUS_STACK_TRACE, L"print-stack-trace"},
|
||||||
{STATUS_STACK_TRACE, L"stack-trace"},
|
{STATUS_STACK_TRACE, L"stack-trace"},
|
||||||
|
{STATUS_TEST_FEATURE, L"test-feature"},
|
||||||
{STATUS_UNDEF, NULL}};
|
{STATUS_UNDEF, NULL}};
|
||||||
#define status_enum_map_len (sizeof status_enum_map / sizeof *status_enum_map)
|
#define status_enum_map_len (sizeof status_enum_map / sizeof *status_enum_map)
|
||||||
|
|
||||||
|
@ -66,6 +71,9 @@ const enum_map<status_cmd_t> status_enum_map[] = {
|
||||||
break; \
|
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) {
|
int job_control_str_to_mode(const wchar_t *mode, wchar_t *cmd, io_streams_t &streams) {
|
||||||
if (wcscmp(mode, L"full") == 0) {
|
if (wcscmp(mode, L"full") == 0) {
|
||||||
return JOB_CONTROL_ALL;
|
return JOB_CONTROL_ALL;
|
||||||
|
@ -82,6 +90,7 @@ struct status_cmd_opts_t {
|
||||||
bool print_help = false;
|
bool print_help = false;
|
||||||
int level = 1;
|
int level = 1;
|
||||||
int new_job_control_mode = -1;
|
int new_job_control_mode = -1;
|
||||||
|
const wchar_t *feature_name;
|
||||||
status_cmd_t status_cmd = STATUS_UNDEF;
|
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;
|
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)
|
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) {
|
int argc, wchar_t **argv, parser_t &parser, io_streams_t &streams) {
|
||||||
wchar_t *cmd = argv[0];
|
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;
|
job_control_mode = opts.new_job_control_mode;
|
||||||
break;
|
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: {
|
case STATUS_FILENAME: {
|
||||||
CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd)
|
CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd)
|
||||||
const wchar_t *fn = parser.current_filename();
|
const wchar_t *fn = parser.current_filename();
|
||||||
|
|
|
@ -6,3 +6,6 @@ status: Invalid combination of options,
|
||||||
you cannot do both 'is-block' and 'is-interactive' in the same invocation
|
you cannot do both 'is-block' and 'is-interactive' in the same invocation
|
||||||
status: Invalid job control mode 'full1'
|
status: Invalid job control mode 'full1'
|
||||||
status: Invalid job control mode '1none'
|
status: Invalid job control mode '1none'
|
||||||
|
|
||||||
|
####################
|
||||||
|
# Future Feature Flags
|
||||||
|
|
|
@ -48,4 +48,9 @@ function test_function
|
||||||
end
|
end
|
||||||
|
|
||||||
test_function
|
test_function
|
||||||
eval test_function
|
eval test_function
|
||||||
|
|
||||||
|
logmsg Future Feature Flags
|
||||||
|
status features
|
||||||
|
status test-feature stderr-nocaret ; echo $status
|
||||||
|
status test-feature not-a-feature ; echo $status
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
Not a function
|
Not a function
|
||||||
test_function
|
test_function
|
||||||
test_function
|
test_function
|
||||||
|
|
||||||
|
####################
|
||||||
|
# Future Feature Flags
|
||||||
|
stderr-nocaret off 3.0 ^ no longer redirects stderr
|
||||||
|
1
|
||||||
|
2
|
||||||
|
|
Loading…
Reference in a new issue