mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-01-19 11:42:47 +08:00
backport set --show
from fish 3.0
I decided this was just too useful not to include in our final fish 2.x release. And since it does not modify any existing behavior it is safe to include at this late date in the process of creating 2.7.
This commit is contained in:
parent
067892c4f1
commit
38024a50dc
|
@ -8,6 +8,7 @@ set [OPTIONS] VARIABLE_NAME[INDICES]... VALUES...
|
|||
set ( -q | --query ) [SCOPE_OPTIONS] VARIABLE_NAMES...
|
||||
set ( -e | --erase ) [SCOPE_OPTIONS] VARIABLE_NAME
|
||||
set ( -e | --erase ) [SCOPE_OPTIONS] VARIABLE_NAME[INDICES]...
|
||||
set ( -S | --show ) [SCOPE_OPTIONS] [VARIABLE_NAME]...
|
||||
\endfish
|
||||
|
||||
\subsection set-description Description
|
||||
|
@ -39,12 +40,14 @@ The following options are available:
|
|||
|
||||
- `-n` or `--names` List only the names of all defined variables, not their value. The names are guaranteed to be sorted.
|
||||
|
||||
- `-S` or `--show` Shows information about the given variables. If no variable names are given then all variables are shown in sorted order. No other flags can be used with this option. The information shown includes whether or not it is set in each of the local, global, and universal scopes. If it is set in one of those scopes whether or not it is exported is reported. The individual elements are also shown along with the length of each element.
|
||||
|
||||
- `-L` or `--long` do not abbreviate long values when printing set variables
|
||||
|
||||
|
||||
If a variable is set to more than one value, the variable will be an array with the specified elements. If a variable is set to zero elements, it will become an array with zero elements.
|
||||
|
||||
If the variable name is one or more array elements, such as `PATH[1 3 7]`, only those array elements specified will be changed. When array indices are specified to `set`, multiple arguments may be used to specify additional indexes, e.g. `set PATH[1] PATH[4] /bin /sbin`. If you specify a negative index when expanding or assigning to an array variable, the index will be calculated from the end of the array. For example, the index -1 means the last index of an array.
|
||||
If the variable name is one or more array elements, such as `PATH[1 3 7]`, only those array elements specified will be changed. If you specify a negative index when expanding or assigning to an array variable, the index will be calculated from the end of the array. For example, the index -1 means the last index of an array.
|
||||
|
||||
The scoping rules when creating or updating a variable are:
|
||||
|
||||
|
|
|
@ -303,6 +303,91 @@ static void print_variables(int include_values, int esc, bool shorten_ok, int sc
|
|||
}
|
||||
}
|
||||
|
||||
static void show_scope(const wchar_t *var_name, int scope, io_streams_t &streams) {
|
||||
const wchar_t *scope_name;
|
||||
switch (scope) {
|
||||
case ENV_LOCAL: {
|
||||
scope_name = L"local";
|
||||
break;
|
||||
}
|
||||
case ENV_GLOBAL: {
|
||||
scope_name = L"global";
|
||||
break;
|
||||
}
|
||||
case ENV_UNIVERSAL: {
|
||||
scope_name = L"universal";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
DIE("invalid scope");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (env_exist(var_name, scope)) {
|
||||
const env_var_t evar = env_get_string(var_name, scope | ENV_EXPORT | ENV_USER);
|
||||
const wchar_t *exportv = evar.missing() ? _(L"unexported") : _(L"exported");
|
||||
|
||||
const env_var_t var = env_get_string(var_name, scope | ENV_USER);
|
||||
wcstring_list_t result;
|
||||
if (!var.empty()) tokenize_variable_array(var, result);
|
||||
|
||||
streams.out.append_format(_(L"$%ls: set in %ls scope, %ls, with %d elements\n"), var_name,
|
||||
scope_name, exportv, result.size());
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
if (result.size() > 100) {
|
||||
if (i == 50) streams.out.append(L"...\n");
|
||||
if (i >= 50 && i < result.size() - 50) continue;
|
||||
}
|
||||
const wcstring value = result[i];
|
||||
const wcstring escaped_val =
|
||||
escape_string(value.c_str(), ESCAPE_NO_QUOTED, STRING_STYLE_SCRIPT);
|
||||
streams.out.append_format(_(L"$%ls[%d]: length=%d value=|%ls|\n"), var_name, i,
|
||||
value.size(), escaped_val.c_str());
|
||||
}
|
||||
} else {
|
||||
streams.out.append_format(_(L"$%ls: not set in %ls scope\n"), var_name, scope_name);
|
||||
}
|
||||
}
|
||||
|
||||
/// Show mode. Show information about the named variable(s).
|
||||
static int builtin_set_show(const wchar_t *cmd, int argc, wchar_t **argv,
|
||||
parser_t &parser, io_streams_t &streams) {
|
||||
if (argc == 0) { // show all vars
|
||||
wcstring_list_t names = env_get_names(ENV_USER);
|
||||
sort(names.begin(), names.end());
|
||||
for (auto it : names) {
|
||||
show_scope(it.c_str(), ENV_LOCAL, streams);
|
||||
show_scope(it.c_str(), ENV_GLOBAL, streams);
|
||||
show_scope(it.c_str(), ENV_UNIVERSAL, streams);
|
||||
streams.out.push_back(L'\n');
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < argc; i++) {
|
||||
wchar_t *arg = argv[i];
|
||||
|
||||
if (!valid_var_name(arg)) {
|
||||
streams.err.append_format(_(L"$%ls: invalid var name\n"), arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wcschr(arg, L'[')) {
|
||||
streams.err.append_format(
|
||||
_(L"%ls: `set --show` does not allow slices with the var names\n"), cmd);
|
||||
builtin_print_help(parser, streams, cmd, streams.err);
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
|
||||
show_scope(arg, ENV_LOCAL, streams);
|
||||
show_scope(arg, ENV_GLOBAL, streams);
|
||||
show_scope(arg, ENV_UNIVERSAL, streams);
|
||||
streams.out.push_back(L'\n');
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_CMD_OK;
|
||||
}
|
||||
|
||||
/// The set builtin creates, updates, and erases (removes, deletes) variables.
|
||||
int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
wchar_t *cmd = argv[0];
|
||||
|
@ -312,6 +397,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
int local = 0, global = 0, exportv = 0;
|
||||
int erase = 0, list = 0, unexport = 0;
|
||||
int universal = 0, query = 0;
|
||||
bool show = false;
|
||||
bool shorten_ok = true;
|
||||
bool preserve_failure_exit_status = true;
|
||||
const int incoming_exit_status = proc_get_last_status();
|
||||
|
@ -325,7 +411,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
// Variables used for parsing the argument list. This command is atypical in using the "+"
|
||||
// (REQUIRE_ORDER) option for flag parsing. This is not typical of most fish commands. It means
|
||||
// we stop scanning for flags when the first non-flag argument is seen.
|
||||
static const wchar_t *short_options = L"+:LUeghlnqux";
|
||||
static const wchar_t *short_options = L"+:LSUeghlnqux";
|
||||
static const struct woption long_options[] = {{L"export", no_argument, NULL, 'x'},
|
||||
{L"global", no_argument, NULL, 'g'},
|
||||
{L"local", no_argument, NULL, 'l'},
|
||||
|
@ -335,6 +421,7 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
{L"universal", no_argument, NULL, 'U'},
|
||||
{L"long", no_argument, NULL, 'L'},
|
||||
{L"query", no_argument, NULL, 'q'},
|
||||
{L"show", no_argument, NULL, 'S'},
|
||||
{L"help", no_argument, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0}};
|
||||
|
||||
|
@ -382,6 +469,11 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
preserve_failure_exit_status = false;
|
||||
break;
|
||||
}
|
||||
case 'S': {
|
||||
show = true;
|
||||
preserve_failure_exit_status = false;
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
builtin_print_help(parser, streams, cmd, streams.out);
|
||||
return STATUS_CMD_OK;
|
||||
|
@ -401,6 +493,12 @@ int builtin_set(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (show) {
|
||||
argc -= w.woptind;
|
||||
argv += w.woptind;
|
||||
return builtin_set_show(cmd, argc, argv, parser, streams);
|
||||
}
|
||||
|
||||
// Ok, all arguments have been parsed, let's validate them. If we are checking the existance of
|
||||
// a variable (-q) we can not also specify scope.
|
||||
if (query && (erase || list)) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user