mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Allow setting feature flags on the command line
This introduces a new command line option --features which can be used for enabling or disabling features for a particular fish session. Examples: fish --features stderr-nocaret fish --features 3.0,no-stderr-nocaret fish --features all Note that the feature set cannot be changed in an existing session.
This commit is contained in:
parent
782cae2d21
commit
8a96f283ba
8 changed files with 63 additions and 1 deletions
12
src/fish.cpp
12
src/fish.cpp
|
@ -44,6 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "fish_version.h"
|
||||
#include "function.h"
|
||||
#include "future_feature_flags.h"
|
||||
#include "history.h"
|
||||
#include "io.h"
|
||||
#include "parser.h"
|
||||
|
@ -61,6 +62,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||
// container to hold the options specified within the command line
|
||||
class fish_cmd_opts_t {
|
||||
public:
|
||||
// Future feature flags values string
|
||||
wcstring features;
|
||||
// Commands to be executed in place of interactive shell.
|
||||
std::vector<std::string> batch_cmds;
|
||||
// Commands to execute after the shell's config has been read.
|
||||
|
@ -238,9 +241,10 @@ int run_command_list(std::vector<std::string> *cmds, const io_chain_t &io) {
|
|||
|
||||
/// Parse the argument list, return the index of the first non-flag arguments.
|
||||
static int fish_parse_opt(int argc, char **argv, fish_cmd_opts_t *opts) {
|
||||
static const char *short_opts = "+hilnvc:C:p:d:D:";
|
||||
static const char *short_opts = "+hilnvc:C:p:d:f:D:";
|
||||
static const struct option long_opts[] = {{"command", required_argument, NULL, 'c'},
|
||||
{"init-command", required_argument, NULL, 'C'},
|
||||
{"features", required_argument, NULL, 'f'},
|
||||
{"debug-level", required_argument, NULL, 'd'},
|
||||
{"debug-stack-frames", required_argument, NULL, 'D'},
|
||||
{"interactive", no_argument, NULL, 'i'},
|
||||
|
@ -277,6 +281,10 @@ static int fish_parse_opt(int argc, char **argv, fish_cmd_opts_t *opts) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
opts->features = str2wcstring(optarg);
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
opts->batch_cmds.push_back("__fish_print_help fish");
|
||||
break;
|
||||
|
@ -375,6 +383,8 @@ int main(int argc, char **argv) {
|
|||
|
||||
const struct config_paths_t paths = determine_config_directory_paths(argv[0]);
|
||||
env_init(&paths);
|
||||
// Set features early in case other initialization depends on them.
|
||||
mutable_fish_features().set_from_string(opts.features);
|
||||
proc_init();
|
||||
builtin_init();
|
||||
misc_init();
|
||||
|
|
|
@ -1363,6 +1363,11 @@ static void test_feature_flags() {
|
|||
f.set(ft::stderr_nocaret, false);
|
||||
do_test(!f.test(ft::stderr_nocaret));
|
||||
|
||||
f.set_from_string(L"stderr-nocaret,nonsense");
|
||||
do_test(f.test(ft::stderr_nocaret));
|
||||
f.set_from_string(L"stderr-nocaret,no-stderr-nocaret,nonsense");
|
||||
do_test(!f.test(ft::stderr_nocaret));
|
||||
|
||||
// Ensure every metadata is represented once.
|
||||
size_t counts[ft::flag_count] = {};
|
||||
for (const auto &md : ft::metadata) {
|
||||
|
|
|
@ -21,3 +21,37 @@ const struct features_t::metadata_t *features_t::metadata_for(const wchar_t *nam
|
|||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void features_t::set_from_string(const wcstring &str) {
|
||||
wcstring_list_t entries = split_string(str, L',');
|
||||
const wchar_t *whitespace = L"\t\n\v\f\r ";
|
||||
for (wcstring entry : entries) {
|
||||
if (entry.empty()) continue;
|
||||
|
||||
// Trim leading and trailing whitespace
|
||||
entry.erase(0, entry.find_first_not_of(whitespace));
|
||||
entry.erase(entry.find_last_not_of(whitespace) + 1);
|
||||
|
||||
const wchar_t *name = entry.c_str();
|
||||
bool value = true;
|
||||
// A "no-" prefix inverts the sense.
|
||||
if (string_prefixes_string(L"no-", name)) {
|
||||
value = false;
|
||||
name += 3; // wcslen(L"no-")
|
||||
}
|
||||
// Look for a feature with this name. If we don't find it, assume it's a group name and set
|
||||
// all features whose group contain it. Do nothing even if the string is unrecognized; this
|
||||
// is to allow uniform invocations of fish (e.g. disable a feature that is only present in
|
||||
// future versions).
|
||||
// The special name 'all' may be used for those who like to live on the edge.
|
||||
if (const metadata_t *md = metadata_for(name)) {
|
||||
this->set(md->flag, value);
|
||||
} else {
|
||||
for (const metadata_t &md : metadata) {
|
||||
if (wcsstr(md.groups, name) || !wcscmp(name, L"all")) {
|
||||
this->set(md.flag, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#define FISH_FUTURE_FEATURE_FLAGS_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
class features_t {
|
||||
public:
|
||||
|
@ -27,6 +30,12 @@ public:
|
|||
values[f] = value;
|
||||
}
|
||||
|
||||
/// Parses a comma-separated feature-flag string, updating ourselves with the values.
|
||||
/// Feature names or group names may be prefixed with "no-" to disable them.
|
||||
/// The special group name "all" may be used for those who like to live on the edge.
|
||||
/// Unknown features are silently ignored.
|
||||
void set_from_string(const wcstring &str);
|
||||
|
||||
/// Metadata about feature flags.
|
||||
struct metadata_t {
|
||||
/// The flag itself.
|
||||
|
|
1
tests/invocation/features-nocaret1.invoke
Normal file
1
tests/invocation/features-nocaret1.invoke
Normal file
|
@ -0,0 +1 @@
|
|||
--features 'no-stderr-nocaret' -c 'status test-feature stderr-nocaret; echo nocaret: $status'
|
1
tests/invocation/features-nocaret1.out
Normal file
1
tests/invocation/features-nocaret1.out
Normal file
|
@ -0,0 +1 @@
|
|||
nocaret: 1
|
1
tests/invocation/features-nocaret2.invoke
Normal file
1
tests/invocation/features-nocaret2.invoke
Normal file
|
@ -0,0 +1 @@
|
|||
--features 'stderr-nocaret' -c 'status test-feature stderr-nocaret; echo nocaret: $status'
|
1
tests/invocation/features-nocaret2.out
Normal file
1
tests/invocation/features-nocaret2.out
Normal file
|
@ -0,0 +1 @@
|
|||
nocaret: 0
|
Loading…
Reference in a new issue