diff --git a/src/builtin_command.cpp b/src/builtin_command.cpp index 50b985691..6a04a1262 100644 --- a/src/builtin_command.cpp +++ b/src/builtin_command.cpp @@ -10,6 +10,7 @@ #include "common.h" #include "fallback.h" // IWYU pragma: keep #include "io.h" +#include "parser.h" #include "path.h" #include "wgetopt.h" #include "wutil.h" // IWYU pragma: keep @@ -102,7 +103,7 @@ int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } } else { wcstring path; - if (path_get_path(command_name, &path)) { + if (path_get_path(command_name, &path, parser.vars())) { if (!opts.quiet) streams.out.append_format(L"%ls\n", path.c_str()); ++found; } diff --git a/src/builtin_read.cpp b/src/builtin_read.cpp index bfe2e0089..1bab82707 100644 --- a/src/builtin_read.cpp +++ b/src/builtin_read.cpp @@ -455,7 +455,6 @@ int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) { auto clear_remaining_vars = [&] () { while (vars_left()) { parser.vars().set_empty(*var_ptr, opts.place); - // env_set_one(*var_ptr, opts.place, L""); ++var_ptr; } }; diff --git a/src/complete.cpp b/src/complete.cpp index 5e1ee9f9c..f9a633383 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -495,18 +495,19 @@ void complete_remove_all(const wcstring &cmd, bool cmd_is_path) { } /// Find the full path and commandname from a command string 'str'. -static void parse_cmd_string(const wcstring &str, wcstring &path, wcstring &cmd) { - if (!path_get_path(str, &path)) { +static void parse_cmd_string(const wcstring &str, wcstring *path, wcstring *cmd, + const environment_t &vars) { + if (!path_get_path(str, path, vars)) { /// Use the empty string as the 'path' for commands that can not be found. - path = L""; + *path = L""; } // Make sure the path is not included in the command. size_t last_slash = str.find_last_of(L'/'); if (last_slash != wcstring::npos) { - cmd = str.substr(last_slash + 1); + *cmd = str.substr(last_slash + 1); } else { - cmd = str; + *cmd = str; } } @@ -865,7 +866,7 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt, bool use_common = 1, use_files = 1; wcstring cmd, path; - parse_cmd_string(cmd_orig, path, cmd); + parse_cmd_string(cmd_orig, &path, &cmd, vars); // mqudsi: run_on_main_thread() already just runs `func` if we're on the main thread, // but it makes a kcall to get the current thread id to ascertain that. Perhaps even @@ -891,8 +892,8 @@ bool completer_t::complete_param(const wcstring &cmd_orig, const wcstring &popt, // may be faster, path_get_path can potentially do a lot of FS/IO access, so env.get() + // function_exists() should still be faster. head_exists = - head_exists || - path_get_path(cmd_orig, nullptr); // use cmd_orig here as it is potentially pathed + head_exists || path_get_path(cmd_orig, nullptr, + vars); // use cmd_orig here as it is potentially pathed } if (!head_exists) { diff --git a/src/env.cpp b/src/env.cpp index f3fa69416..4e7d9738c 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -1658,19 +1658,7 @@ env_vars_snapshot_t::env_vars_snapshot_t(const environment_t &source, const wcha env_vars_snapshot_t::~env_vars_snapshot_t() = default; -// The "current" variables are not a snapshot at all, but instead trampoline to env_get, etc. -// We identify the current snapshot based on pointer values. -// This is an ugly thing that has to go away. -const env_vars_snapshot_t env_vars_snapshot_t::s_current; -const env_vars_snapshot_t &env_vars_snapshot_t::current() { return s_current; } - -bool env_vars_snapshot_t::is_current() const { return this == &s_current; } - maybe_t env_vars_snapshot_t::get(const wcstring &key, env_mode_flags_t mode) const { - // If we represent the current state, bounce to env_get. - if (this->is_current()) { - return env_get(key, mode); - } auto iter = vars.find(key); if (iter == vars.end()) return none(); return iter->second; diff --git a/src/env.h b/src/env.h index 32a425f5e..ef9a9b5ae 100644 --- a/src/env.h +++ b/src/env.h @@ -255,9 +255,6 @@ class env_stack_t : public environment_t { class env_vars_snapshot_t : public environment_t { std::map vars; wcstring_list_t names; - bool is_current() const; - - static const env_vars_snapshot_t s_current; public: env_vars_snapshot_t() = default; @@ -270,9 +267,6 @@ class env_vars_snapshot_t : public environment_t { wcstring_list_t get_names(int flags) const override; - // Returns the fake snapshot representing the live variables array. - static const env_vars_snapshot_t ¤t(); - // Vars necessary for highlighting. static const wchar_t *const highlighting_keys[]; diff --git a/src/fish_indent.cpp b/src/fish_indent.cpp index 428bd417f..f985c4b19 100644 --- a/src/fish_indent.cpp +++ b/src/fish_indent.cpp @@ -529,7 +529,7 @@ int main(int argc, char *argv[]) { std::vector colors; if (output_type != output_type_plain_text) { highlight_shell_no_io(output_wtext, colors, output_wtext.size(), NULL, - env_vars_snapshot_t::current()); + env_stack_t::globals()); } std::string colored_output; diff --git a/src/highlight.cpp b/src/highlight.cpp index 2b49d64da..2d1179140 100644 --- a/src/highlight.cpp +++ b/src/highlight.cpp @@ -364,7 +364,7 @@ bool autosuggest_validate_from_history(const history_item_t &item, // Not handled specially so handle it here. bool cmd_ok = false; - if (path_get_path(parsed_command, NULL)) { + if (path_get_path(parsed_command, NULL, vars)) { cmd_ok = true; } else if (builtin_exists(parsed_command) || function_exists_no_autoload(parsed_command, vars)) { diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index f5e4d4aa2..a2d739277 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -800,7 +800,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process( wcstring path_to_external_command; if (process_type == EXTERNAL || process_type == INTERNAL_EXEC) { // Determine the actual command. This may be an implicit cd. - bool has_command = path_get_path(cmd, &path_to_external_command); + bool has_command = path_get_path(cmd, &path_to_external_command, parser->vars()); // If there was no command, then we care about the value of errno after checking for it, to // distinguish between e.g. no file vs permissions problem. diff --git a/src/path.h b/src/path.h index 3d9b596d0..48ac8d654 100644 --- a/src/path.h +++ b/src/path.h @@ -34,13 +34,12 @@ bool path_get_data(wcstring &path); /// Args: /// cmd - The name of the executable. /// output_or_NULL - If non-NULL, store the full path. -/// vars - The environment variables snapshot to use +/// vars - The environment variables to use /// /// Returns: /// false if the command can not be found else true. The result /// should be freed with free(). -bool path_get_path(const wcstring &cmd, wcstring *output_or_NULL, - const environment_t &vars = env_vars_snapshot_t::current()); +bool path_get_path(const wcstring &cmd, wcstring *output_or_NULL, const environment_t &vars); /// Return all the paths that match the given command. wcstring_list_t path_get_paths(const wcstring &cmd);