Change how we separate toplevel and global scopes

Instead of introducing a new local scope at the point of `set`, merely
push a new local scope at the end of env_init(). This means we have a
single toplevel local scope across the lifetime of the fish process,
which means that

    set -l foo bar
    echo $foo

behaves as expected, without modifying the global environment.
This commit is contained in:
Kevin Ballard 2014-07-13 13:21:06 -07:00
parent 387ec5c06a
commit 7b12fd26f3
3 changed files with 8 additions and 27 deletions

View file

@ -566,17 +566,6 @@ static int builtin_set(parser_t &parser, wchar_t **argv)
*/
scope = (local ? ENV_LOCAL : 0) | (global ? ENV_GLOBAL : 0) | (exportv ? ENV_EXPORT : 0) | (unexport ? ENV_UNEXPORT : 0) | (universal ? ENV_UNIVERSAL:0) | ENV_USER;
/*
If we're interacting with the local scope at all, ensure we actually have
one that's distinct from the global scope. If we don't have one yet,
create one and modify the current block to pop it.
*/
if ((scope & ENV_LOCAL) && env_ensure_local_scope())
{
block_t *block = parser.current_block();
block->wants_pop_env = true;
}
if (query)
{
/*

18
env.cpp
View file

@ -593,6 +593,14 @@ void env_init(const struct config_paths_t *paths /* or NULL */)
/* Set fish_bind_mode to "default" */
env_set(FISH_BIND_MODE_VAR, DEFAULT_BIND_MODE, ENV_GLOBAL);
/*
Now that the global scope is fully initialized, add a toplevel local
scope. This same local scope will persist throughout the lifetime of the
fish process, and it will ensure that `set -l` commands run at the
command-line don't affect the global scope.
*/
env_push(false);
}
/**
@ -1195,16 +1203,6 @@ void env_pop()
}
}
bool env_ensure_local_scope()
{
if (top == global_env)
{
env_push(false);
return true;
}
return false;
}
/**
Function used with to insert keys of one table into a set::set<wcstring>
*/

6
env.h
View file

@ -206,12 +206,6 @@ void env_push(bool new_scope);
*/
void env_pop();
/**
Push the variable stack if the current scope is the global scope. Returns
whether it pushed a scope.
*/
bool env_ensure_local_scope();
/** Synchronizes all universal variable changes: writes everything out, reads stuff in */
void env_universal_barrier();