Instantize env_get
This removes env_get(). All fish variable accesses must go through an environment_t.
This commit is contained in:
parent
b98812dd1a
commit
77884bc21a
@ -6,6 +6,7 @@
|
||||
#include "common.h"
|
||||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "io.h"
|
||||
#include "parser.h"
|
||||
#include "wgetopt.h"
|
||||
#include "wutil.h" // IWYU pragma: keep
|
||||
|
||||
@ -48,7 +49,7 @@ int builtin_pwd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
}
|
||||
|
||||
wcstring pwd;
|
||||
if (auto tmp = env_get(L"PWD")) {
|
||||
if (auto tmp = parser.vars().get(L"PWD")) {
|
||||
pwd = tmp->as_string();
|
||||
}
|
||||
if (resolve_symlinks) {
|
||||
|
@ -424,7 +424,7 @@ int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
||||
case STATUS_CURRENT_CMD: {
|
||||
CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd)
|
||||
// HACK: Go via the deprecated variable to get the command.
|
||||
const auto var = env_get(L"_");
|
||||
const auto var = parser.vars().get(L"_");
|
||||
if (!var.missing_or_empty()) {
|
||||
streams.out.append(var->as_string());
|
||||
streams.out.push_back(L'\n');
|
||||
|
16
src/env.cpp
16
src/env.cpp
@ -349,7 +349,6 @@ static mode_t get_umask() {
|
||||
|
||||
/// Properly sets all timezone information.
|
||||
static void handle_timezone(const wchar_t *env_var_name, const environment_t &vars) {
|
||||
// const env_var_t var = env_get(env_var_name, ENV_EXPORT);
|
||||
const auto var = vars.get(env_var_name, ENV_DEFAULT);
|
||||
debug(2, L"handle_timezone() current timezone var: |%ls| => |%ls|", env_var_name,
|
||||
!var ? L"MISSING" : var->as_string().c_str());
|
||||
@ -697,7 +696,7 @@ void env_stack_t::mark_changed_exported() { vars_stack().mark_changed_exported()
|
||||
wcstring environment_t::get_pwd_slash() const {
|
||||
// Return "/" if PWD is missing.
|
||||
// See https://github.com/fish-shell/fish-shell/issues/5080
|
||||
auto pwd_var = env_get(L"PWD");
|
||||
auto pwd_var = get(L"PWD");
|
||||
wcstring pwd;
|
||||
if (!pwd_var.missing_or_empty()) {
|
||||
pwd = pwd_var->as_string();
|
||||
@ -951,8 +950,8 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
|
||||
get_hostname_identifier(hostname);
|
||||
vars.set_one(L"hostname", ENV_GLOBAL, hostname);
|
||||
|
||||
// Set up SHLVL variable. Not we can't use env_get because SHLVL is read-only, and therefore was
|
||||
// not inherited from the environment.
|
||||
// Set up SHLVL variable. Not we can't use vars.get() because SHLVL is read-only, and therefore
|
||||
// was not inherited from the environment.
|
||||
wcstring nshlvl_str = L"1";
|
||||
if (const char *shlvl_var = getenv("SHLVL")) {
|
||||
const wchar_t *end;
|
||||
@ -1049,7 +1048,7 @@ static int set_umask(const wcstring_list_t &list_val) {
|
||||
}
|
||||
|
||||
if (errno || mask > 0777 || mask < 0) return ENV_INVALID;
|
||||
// Do not actually create a umask variable. On env_get() it will be calculated.
|
||||
// Do not actually create a umask variable. On env_stack_t::get() it will be calculated.
|
||||
umask(mask);
|
||||
return ENV_OK;
|
||||
}
|
||||
@ -1422,7 +1421,7 @@ maybe_t<env_var_t> env_stack_t::get(const wcstring &key, env_mode_flags_t mode)
|
||||
if (!search_universal) return none();
|
||||
|
||||
// Another hack. Only do a universal barrier on the main thread (since it can change variable
|
||||
// values). Make sure we do this outside the env_lock because it may itself call `env_get()`.
|
||||
// values). Make sure we do this outside the env_lock because it may itself call `get()`.
|
||||
if (is_main_thread() && !get_proc_had_barrier()) {
|
||||
set_proc_had_barrier(true);
|
||||
env_universal_barrier();
|
||||
@ -1440,11 +1439,6 @@ maybe_t<env_var_t> env_stack_t::get(const wcstring &key, env_mode_flags_t mode)
|
||||
return none();
|
||||
}
|
||||
|
||||
/// Legacy versions.
|
||||
maybe_t<env_var_t> env_get(const wcstring &key, env_mode_flags_t mode) {
|
||||
return env_stack_t::principal().get(key, mode);
|
||||
}
|
||||
|
||||
void env_universal_barrier() { env_stack_t::principal().universal_barrier(); }
|
||||
|
||||
/// Returns true if the specified scope or any non-shadowed non-global subscopes contain an exported
|
||||
|
@ -22,8 +22,8 @@ extern bool curses_initialized;
|
||||
|
||||
// Flags that may be passed as the 'mode' in env_stack_t::set() / environment_t::get().
|
||||
enum {
|
||||
/// Default mode. Used with `env_get()` to indicate the caller doesn't care what scope the var
|
||||
/// is in or whether it is exported or unexported.
|
||||
/// Default mode. Used with `env_stack_t::get()` to indicate the caller doesn't care what scope
|
||||
/// the var is in or whether it is exported or unexported.
|
||||
ENV_DEFAULT = 0,
|
||||
/// Flag for local (to the current block) variable.
|
||||
ENV_LOCAL = 1 << 0,
|
||||
@ -160,9 +160,6 @@ class null_environment_t : public environment_t {
|
||||
wcstring_list_t get_names(int flags) const override;
|
||||
};
|
||||
|
||||
/// Gets the variable with the specified name, or none() if it does not exist.
|
||||
maybe_t<env_var_t> env_get(const wcstring &key, env_mode_flags_t mode = ENV_DEFAULT);
|
||||
|
||||
/// Synchronizes all universal variable changes: writes everything out, reads stuff in.
|
||||
void env_universal_barrier();
|
||||
|
||||
|
@ -1010,7 +1010,7 @@ static expand_error_t expand_stage_wildcards(wcstring path_to_expand, std::vecto
|
||||
// Get the PATH/CDPATH and CWD. Perhaps these should be passed in. An empty CDPATH
|
||||
// implies just the current directory, while an empty PATH is left empty.
|
||||
wcstring_list_t paths;
|
||||
if (auto paths_var = env_get(for_cd ? L"CDPATH" : L"PATH")) {
|
||||
if (auto paths_var = vars.get(for_cd ? L"CDPATH" : L"PATH")) {
|
||||
paths = paths_var->as_list();
|
||||
}
|
||||
if (paths.empty()) {
|
||||
@ -1193,17 +1193,15 @@ bool fish_xdm_login_hack_hack_hack_hack(std::vector<std::string> *cmds, int argc
|
||||
return result;
|
||||
}
|
||||
|
||||
maybe_t<wcstring> expand_abbreviation(const wcstring &src) {
|
||||
maybe_t<wcstring> expand_abbreviation(const wcstring &src, const environment_t &vars) {
|
||||
if (src.empty()) return none();
|
||||
|
||||
const auto &vars = env_stack_t::principal();
|
||||
wcstring unesc_src;
|
||||
if (!unescape_string(src, &unesc_src, STRING_STYLE_VAR)) {
|
||||
return none();
|
||||
}
|
||||
wcstring var_name = L"_fish_abbr_" + unesc_src;
|
||||
auto var_value = vars.get(var_name);
|
||||
if (var_value) {
|
||||
if (auto var_value = vars.get(var_name)) {
|
||||
return var_value->as_string();
|
||||
}
|
||||
return none();
|
||||
|
@ -160,7 +160,7 @@ wcstring replace_home_directory_with_tilde(const wcstring &str, const environmen
|
||||
|
||||
/// Abbreviation support. Expand src as an abbreviation, returning the expanded form if found,
|
||||
/// none() if not.
|
||||
maybe_t<wcstring> expand_abbreviation(const wcstring &src);
|
||||
maybe_t<wcstring> expand_abbreviation(const wcstring &src, const environment_t &vars);
|
||||
|
||||
/// \return a snapshot of all abbreviations as a map abbreviation->expansion.
|
||||
std::map<wcstring, wcstring> get_abbreviations();
|
||||
|
@ -1787,59 +1787,62 @@ static void test_abbreviations() {
|
||||
if (ret != 0) err(L"Unable to set abbreviation variable");
|
||||
}
|
||||
|
||||
if (expand_abbreviation(L"")) err(L"Unexpected success with empty abbreviation");
|
||||
if (expand_abbreviation(L"nothing")) err(L"Unexpected success with missing abbreviation");
|
||||
if (expand_abbreviation(L"", vars)) err(L"Unexpected success with empty abbreviation");
|
||||
if (expand_abbreviation(L"nothing", vars)) err(L"Unexpected success with missing abbreviation");
|
||||
|
||||
auto mresult = expand_abbreviation(L"gc");
|
||||
auto mresult = expand_abbreviation(L"gc", vars);
|
||||
if (!mresult) err(L"Unexpected failure with gc abbreviation");
|
||||
if (*mresult != L"git checkout") err(L"Wrong abbreviation result for gc");
|
||||
|
||||
mresult = expand_abbreviation(L"foo");
|
||||
mresult = expand_abbreviation(L"foo", vars);
|
||||
if (!mresult) err(L"Unexpected failure with foo abbreviation");
|
||||
if (*mresult != L"bar") err(L"Wrong abbreviation result for foo");
|
||||
|
||||
bool expanded;
|
||||
wcstring result;
|
||||
expanded = reader_expand_abbreviation_in_command(L"just a command", 3, &result);
|
||||
expanded = reader_expand_abbreviation_in_command(L"just a command", 3, vars, &result);
|
||||
if (expanded) err(L"Command wrongly expanded on line %ld", (long)__LINE__);
|
||||
expanded = reader_expand_abbreviation_in_command(L"gc somebranch", 0, &result);
|
||||
expanded = reader_expand_abbreviation_in_command(L"gc somebranch", 0, vars, &result);
|
||||
if (!expanded) err(L"Command not expanded on line %ld", (long)__LINE__);
|
||||
|
||||
expanded = reader_expand_abbreviation_in_command(L"gc somebranch", wcslen(L"gc"), &result);
|
||||
expanded =
|
||||
reader_expand_abbreviation_in_command(L"gc somebranch", wcslen(L"gc"), vars, &result);
|
||||
if (!expanded) err(L"gc not expanded");
|
||||
if (result != L"git checkout somebranch")
|
||||
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
|
||||
|
||||
// Space separation.
|
||||
expanded = reader_expand_abbreviation_in_command(L"gx somebranch", wcslen(L"gc"), &result);
|
||||
expanded =
|
||||
reader_expand_abbreviation_in_command(L"gx somebranch", wcslen(L"gc"), vars, &result);
|
||||
if (!expanded) err(L"gx not expanded");
|
||||
if (result != L"git checkout somebranch")
|
||||
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
|
||||
|
||||
expanded = reader_expand_abbreviation_in_command(L"echo hi ; gc somebranch",
|
||||
wcslen(L"echo hi ; g"), &result);
|
||||
wcslen(L"echo hi ; g"), vars, &result);
|
||||
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__);
|
||||
if (result != L"echo hi ; git checkout somebranch")
|
||||
err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
|
||||
|
||||
expanded = reader_expand_abbreviation_in_command(
|
||||
L"echo (echo (echo (echo (gc ", wcslen(L"echo (echo (echo (echo (gc"), &result);
|
||||
L"echo (echo (echo (echo (gc ", wcslen(L"echo (echo (echo (echo (gc"), vars, &result);
|
||||
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__);
|
||||
if (result != L"echo (echo (echo (echo (git checkout ")
|
||||
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
|
||||
|
||||
// If commands should be expanded.
|
||||
expanded = reader_expand_abbreviation_in_command(L"if gc", wcslen(L"if gc"), &result);
|
||||
expanded = reader_expand_abbreviation_in_command(L"if gc", wcslen(L"if gc"), vars, &result);
|
||||
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__);
|
||||
if (result != L"if git checkout")
|
||||
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
|
||||
|
||||
// Others should not be.
|
||||
expanded = reader_expand_abbreviation_in_command(L"of gc", wcslen(L"of gc"), &result);
|
||||
expanded = reader_expand_abbreviation_in_command(L"of gc", wcslen(L"of gc"), vars, &result);
|
||||
if (expanded) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
|
||||
|
||||
// Others should not be.
|
||||
expanded = reader_expand_abbreviation_in_command(L"command gc", wcslen(L"command gc"), &result);
|
||||
expanded =
|
||||
reader_expand_abbreviation_in_command(L"command gc", wcslen(L"command gc"), vars, &result);
|
||||
if (expanded) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
|
||||
|
||||
vars.pop();
|
||||
@ -2662,9 +2665,9 @@ static void perform_one_autosuggestion_cd_test(const wcstring &command, const wc
|
||||
}
|
||||
|
||||
static void perform_one_completion_cd_test(const wcstring &command, const wcstring &expected,
|
||||
long line) {
|
||||
const environment_t &vars, long line) {
|
||||
std::vector<completion_t> comps;
|
||||
complete(command, &comps, COMPLETION_REQUEST_DEFAULT, env_vars_snapshot_t{});
|
||||
complete(command, &comps, COMPLETION_REQUEST_DEFAULT, vars);
|
||||
|
||||
bool expects_error = (expected == L"<error>");
|
||||
|
||||
@ -2795,8 +2798,8 @@ static void test_autosuggest_suggest_special() {
|
||||
if (system("mkdir -p '~hahaha/path1/path2/'")) err(L"mkdir failed");
|
||||
perform_one_autosuggestion_cd_test(L"cd ~haha", L"ha/path1/path2/", vars, __LINE__);
|
||||
perform_one_autosuggestion_cd_test(L"cd ~hahaha/", L"path1/path2/", vars, __LINE__);
|
||||
perform_one_completion_cd_test(L"cd ~haha", L"ha/", __LINE__);
|
||||
perform_one_completion_cd_test(L"cd ~hahaha/", L"path1/", __LINE__);
|
||||
perform_one_completion_cd_test(L"cd ~haha", L"ha/", vars, __LINE__);
|
||||
perform_one_completion_cd_test(L"cd ~hahaha/", L"path1/", vars, __LINE__);
|
||||
|
||||
parser_t::principal_parser().vars().remove(L"HOME", ENV_LOCAL | ENV_EXPORT);
|
||||
popd();
|
||||
|
@ -1015,7 +1015,7 @@ static bool command_is_valid(const wcstring &cmd, enum parse_statement_decoratio
|
||||
if (!is_valid && function_ok) is_valid = function_exists_no_autoload(cmd, vars);
|
||||
|
||||
// Abbreviations
|
||||
if (!is_valid && abbreviation_ok) is_valid = expand_abbreviation(cmd).has_value();
|
||||
if (!is_valid && abbreviation_ok) is_valid = expand_abbreviation(cmd, vars).has_value();
|
||||
|
||||
// Regular commands
|
||||
if (!is_valid && command_ok) is_valid = path_get_path(cmd, NULL, vars);
|
||||
|
@ -395,7 +395,7 @@ class reader_data_t {
|
||||
void pager_selection_changed();
|
||||
|
||||
/// Expand abbreviations at the current cursor position, minus backtrack_amt.
|
||||
bool expand_abbreviation_as_necessary(size_t cursor_backtrack) const;
|
||||
static bool expand_abbreviation_as_necessary(size_t cursor_backtrack);
|
||||
|
||||
/// Return the variable set used for e.g. command duration.
|
||||
env_stack_t &vars() { return parser_t::principal_parser().vars(); }
|
||||
@ -699,7 +699,7 @@ void reader_data_t::pager_selection_changed() {
|
||||
|
||||
/// Expand abbreviations at the given cursor position. Does NOT inspect 'data'.
|
||||
bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos,
|
||||
wcstring *output) {
|
||||
const environment_t &vars, wcstring *output) {
|
||||
// See if we are at "command position". Get the surrounding command substitution, and get the
|
||||
// extent of the first token.
|
||||
const wchar_t *const buff = cmdline.c_str();
|
||||
@ -750,7 +750,7 @@ bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t curso
|
||||
bool result = false;
|
||||
if (matching_cmd_node) {
|
||||
const wcstring token = matching_cmd_node.get_source(subcmd);
|
||||
if (auto abbreviation = expand_abbreviation(token)) {
|
||||
if (auto abbreviation = expand_abbreviation(token, vars)) {
|
||||
// There was an abbreviation! Replace the token in the full command. Maintain the
|
||||
// relative position of the cursor.
|
||||
if (output != NULL) {
|
||||
@ -767,15 +767,16 @@ bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t curso
|
||||
/// Expand abbreviations at the current cursor position, minus the given cursor backtrack. This may
|
||||
/// change the command line but does NOT repaint it. This is to allow the caller to coalesce
|
||||
/// repaints.
|
||||
bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) const {
|
||||
bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) {
|
||||
reader_data_t *data = current_data();
|
||||
bool result = false;
|
||||
editable_line_t *el = data->active_edit_line();
|
||||
if (this->expand_abbreviations && el == &data->command_line) {
|
||||
if (data->expand_abbreviations && el == &data->command_line) {
|
||||
// Try expanding abbreviations.
|
||||
wcstring new_cmdline;
|
||||
size_t cursor_pos = el->position - mini(el->position, cursor_backtrack);
|
||||
if (reader_expand_abbreviation_in_command(el->text, cursor_pos, &new_cmdline)) {
|
||||
if (reader_expand_abbreviation_in_command(el->text, cursor_pos, data->vars(),
|
||||
&new_cmdline)) {
|
||||
// We expanded an abbreviation! The cursor moves by the difference in the command line
|
||||
// lengths.
|
||||
size_t new_buff_pos = el->position + new_cmdline.size() - el->text.size();
|
||||
|
@ -216,7 +216,7 @@ wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
|
||||
|
||||
/// Expand abbreviations at the given cursor position. Exposed for testing purposes only.
|
||||
bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos,
|
||||
wcstring *output);
|
||||
const environment_t &vars, wcstring *output);
|
||||
|
||||
/// Apply a completion string. Exposed for testing only.
|
||||
wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flags_t flags,
|
||||
|
@ -110,21 +110,11 @@ static bool allow_soft_wrap() {
|
||||
return auto_right_margin;
|
||||
}
|
||||
|
||||
/// Does this look like the escape sequence for setting a screen name.
|
||||
/// Does this look like the escape sequence for setting a screen name?
|
||||
static bool is_screen_name_escape_seq(const wchar_t *code, size_t *resulting_length) {
|
||||
if (code[1] != L'k') {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO: Decide if this should be removed or modified to also test for TERM values that begin
|
||||
// with "tmux". See issue #3512.
|
||||
const env_var_t term_name = env_get(L"TERM");
|
||||
if (term_name.missing_or_empty() || !string_prefixes_string(L"screen", term_name)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
const wchar_t *const screen_name_end_sentinel = L"\x1B\\";
|
||||
const wchar_t *screen_name_end = wcsstr(&code[2], screen_name_end_sentinel);
|
||||
if (screen_name_end == NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user