Commit graph

337 commits

Author SHA1 Message Date
Aaron Gyes
362319d25f Cleanup on aisle haphazard-everywhere 2021-10-28 01:47:49 -07:00
Fabian Homborg
76f3564e2a Remove now unused out_events parameter 2021-10-26 17:38:40 +02:00
ridiculousfish
15cee66df1 Wrap even more stuff in anonymous namespaces 2021-09-30 11:33:03 -07:00
ridiculousfish
f577c221eb Introduce get_by_sorted_name
Given that we have several lists of things sorted by name, replace a
bunch of ad-hoc lower_bound calls with a single function.
2021-08-26 13:40:37 -07:00
Rosen Penev
a00ebc65af remove make_pair
There are better alternatives with C++11.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-05 12:12:28 +02:00
Fabian Homborg
0059192f61 Allow erasing vars via function-scope
This triggered an assert because the remove code had no idea how to
find the function scope.

Oops!
2021-08-04 17:55:41 +02:00
Fabian Homborg
733114fefb
Add set --function (#8145)
* Add `set --function`

This makes the function's scope available, even inside of blocks. Outside of blocks it's the toplevel local scope.

This removes the need to declare variables locally before use, and will probably end up being the main way variables get set.

E.g.:

```fish
set -l thing
if condition
    set thing one
else
    set thing two
end
```

could be written as

```fish
if condition
    set -f thing one
else
    set -f thing two
end
```

Note: Many scripts shipped with fish use workarounds like `and`/`or`
instead of `if`, so it isn't easy to find good examples.

Also, if there isn't an else-branch in that above, just with

```fish
if condition
    set -f thing one
end
```

that means something different from setting it before! Now, if
`condition` isn't true, it would use a global (or universal) variable of
te same name!

Some more interesting parts:

Because it *is* a local scope, setting a variable `-f` and
`-l` in the toplevel of a function ends up the same:

```fish
function foo2
    set -l foo bar
    set -f foo baz # modifies the *same* variable!
end
```

but setting it locally inside a block creates a new local variable
that shadows the function-scoped variable:

```fish
function foo3
    set -f foo bar
    begin
        set -l foo banana
        # $foo is banana
    end
    # $foo is bar again
end
```

This is how local variables already work. "Local" is actually "block-scoped".

Also `set --show` will only show the closest local scope, so it won't
show a shadowed function-level variable. Again, this is how local
variables already work, and could be done as a separate change.

As a fun tidbit, functions with --no-scope-shadowing can now use this to set variables in the calling function. That's probably okay given that it's already an escape hatch (but to be clear: if it turns out to problematic I reserve the right to remove it).

Fixes #565
2021-08-01 20:08:12 +02:00
Fabian Homborg
80888eed57 Remove read_only stuff from env_var_t
This doesn't work.

The real thing that tells if something is read-only is
electric_var_t::readonly().

This wasn't used, and we provide no way to make a variable read-only,
which makes this an unnecessary footgun.
2021-07-30 15:33:08 +02:00
Fabian Homborg
b9ba3020f8 Don't check config directories with --no-config
If we don't use 'em, we should not complain about 'em.
2021-07-27 18:35:20 +02:00
ridiculousfish
5f7e03ccf4 Introduce noncopyable_t and nonmovable_t
These are little helper types that allow us to get rid of lots of
'=delete' declarations.
2021-07-23 11:19:42 -07:00
ridiculousfish
a32248277f Make commandline state thread safe
Today the reader exposes its internals directly, e.g. to the commandline
builtin. This is of course not thread safe. For example in concurrent
execution, running `commandline` twice in separate threads would cause a
race and likely a crash.

Fix this by factoring all the commandline state into a new type
'commandline_state_t'. Make it a singleton (there is only one command
line
after all) and protect it with a lock.

No user visible change here.
2021-07-21 11:51:46 -07:00
ridiculousfish
f345464879 Simplify ASSERT_SORT_ORDER
In practice this only looked at the name property, so we can simplify it
by using an ordinary template function instead of a macro.
2021-07-15 13:15:24 -07:00
David Dorfman
f2448e3f0e env: remove trailing null-terminator from default path 2021-05-25 08:12:21 +02:00
ridiculousfish
8d06357fbb Take advantage of empty uvars
Now that we allow uvars to be empty and uninitialized, we can always
instantiate it; we don't need to test whether it is null or not.
2021-05-10 15:23:56 -07:00
ridiculousfish
16ba45fe64 Early work towards changing locking discipline of uvars
Rather than universal variables holding their own lock, we will wrap the
instance in a lock.
2021-05-10 14:23:07 -07:00
ridiculousfish
6ab7945623 Mild refactoring of universal variables
This removes some unnecessary returns and other miscellaneous cleanup.
2021-05-10 14:23:07 -07:00
ridiculousfish
d1fd3d5825 Detect at startup whether config and data paths are remote
This is in preparation for changing the locking regime of history.
2021-05-10 14:23:07 -07:00
Fabian Homborg
b16e537b66 Only set default fish_function_path when --no-config is used
Otherwise config.fish will keep $fish_function_path.
2021-05-01 19:43:31 +02:00
Fabian Homborg
5ddb1adac1 Only use DATADIR in $fish_function_path if no-config is used
This only uses the functions fish ships with, but still doesn't allow
any *customization*, which is the point of no-config.

This makes it a lot more usable, given that the actual normal prompt
and things are there.

This still doesn't set any colors, because we don't run
__fish_config_interactive because we don't read config.fish (any
config.fish), because that would run the snippets.
2021-05-01 18:59:25 +02:00
Fabian Homborg
848f7a0787 Don't do uvars if no-config is in effect 2021-05-01 18:59:25 +02:00
Fabian Homborg
980365735a If no uvars are available, fall back to global when setting
Otherwise `set -U foo bar` if uvars aren't available would simply not
set *anything*.
2021-05-01 18:59:25 +02:00
Karolina Gontarek
9d66ddc840 Rename variable to fish_killring 2021-04-21 16:39:29 -07:00
Karolina Gontarek
ed64cf5e34 Implementation of variable with killring entries 2021-04-21 16:39:29 -07:00
ridiculousfish
0a559ac457 Reformat source files with clang-format 2021-04-21 13:31:58 -07:00
ridiculousfish
8e95bba25e Clean up and reduce some allocations in env.cpp 2021-04-20 15:15:52 -07:00
Fabian Homborg
e1d19cf571 Don't touch $SHLVL if not interactive
It's not super clear what $SHLVL is useful for, but the current
definition is essentially
"number of shells in the parent processes + 1"

which isn't *super useful*?

Bash's behavior here is a bit weird in that it increments $SHLVL
basically always, but since it auto-execs the last process it will
decrement it again, so in practice it's often not incremented.

E.g.

```
> echo $SHLVL
1
> bash -c 'echo $SHLVL; bash'
2
>> echo $SHLVL
2
```

Both bashes here end up having the same $SHLVL because this is
equivalent to `echo $SHLVL; exec bash`. Running `echo $SHLVL` and then
`bash -c 'echo $SHLVL'` in an interactive bash will have a different
result (1 and 2) because that doesn't *exec* the inner bash.

That's not something we want to get into, so what we do is increment
$SHLVL in every interactive fish. Non-interactive fish will simply
import the existing value.

That means if you had e.g. a bash that runs a fish script that ends up
opening a new fish session, you would have a $SHLVL of *2* - one for the
bash, and one for the inner fish.

We key this off is_interactive_session() (which can also be enabled
via `fish -i`) because it's easy and because `fish -i` is asking for
fish to be, in some form, "interactive".

That means most of the time $SHLVL will be "how many shells am I deep,
how often do I have to `exit`", except for when you specifically asked
for a fish to be "interactive". If that's a problem, we can rethink it.

Fixes #7864.
2021-03-29 17:44:13 +02:00
ridiculousfish
fb92ad946b Rework null terminated arrays
Several functions including wgetopt and execve operate on null-terminated
arrays of nul-terminated pointers: a list of pointers to C strings where
the last pointer is null. Prior to this change, each process_t stored its
argv in such an array. This had two problems:

1. It was awkward to work with this type, instead of using std::vector,
etc.
2. The process's arguments would be rearranged by builtins which is
surprising

Our null terminated arrays were built around a fancy type that would copy
input strings and also generate an array of pointers to them, in one big
allocation.

Switch to a new model where we construct an array of pointers over
existing strings. So you can supply a `vector<string>` and now
`null_terminated_array_t` will just make a list of pointers to them. Now
processes can just store their argv in a familiar wcstring_list_t.
2021-03-28 15:31:25 -07:00
Mahmoud Al-Qudsi
2d39568ec4 Statically assert the sort order of more lists
Add compile-time checks to ensure list of string subcommands, builtins,
and electric variables are kept in asciibetical order to facilitate
binary search lookups.
2021-02-08 15:31:49 -06:00
Fabian Homborg
8b133833fa Don't inherit windows paths for $PWD
If given a windows path like `F:\foo`, this currently ends up
assert()ing in path_normalize_for_cd.

Instead, since these paths violate a bunch of assumptions we make, we
reject them and fall back on getting $PWD via getcwd() (which should
give us a nice proper unixy path).

Fixes #7636.

This isn't tested because it would require a system where a windowsy
path passes paths_are_same_file, and on the unix systems we run our
tests that's impossible as far as I can tell?
2021-01-17 23:08:04 +01:00
Fabian Homborg
19efd22468 env: Setup $HOME/$USER *before* the config directories
They are based on $HOME, so setting $HOME has to be done first.

Fixes #7620

(untested because I'm assuming common CI systems have weird $HOME settings)
2021-01-11 18:51:47 +01:00
ridiculousfish
e8c9da100c Track histories with shared_ptr
Prior to this change, histories were immortal and allocated with either
unique_ptr or just leaked via new. But this can result in races in the
path detection test, as the destructor races with the pointer-captured
history. Switch to using shared_ptr.
2021-01-09 17:02:11 -08:00
ridiculousfish
118f710e99 Allow fish_private_mode to change at runtime
Prior to this change, `fish_private_mode` worked by just suppressing
history outright. With this change, `fish_private_mode` can be toggled on
and off. Commands entered while `fish_private_mode` is set are stored but
in memory only; they are not written to disk.

Fixes #7590
Fixes #7589
2021-01-02 22:01:47 -08:00
Mahmoud Al-Qudsi
332287708b Prevent fish from re-importing an exported fish_user_paths
fish_user_paths is a fish-specific variable that can be persisted by
making it a universal variable or by making it a global variable set at
startup in `config.fish`.

Since it is not defined in a clean installation, a user could
inadvertently create it as `set -Ux fish_user_paths ....` the first
time, creating a horrible, ugly, self-loathing mess that will have you
chasing ghosts and bisecting for naught once fish re-imports
fish_user_paths as a *global* variable that shadows the universal one.

While that is true for any universal variable that is re-imported as a
global variable, only fish_user_paths has the potential to really screw
things up because we also re-export PATH based off of its value in turn.
2020-10-25 21:45:45 -05:00
Fabian Homborg
181ce4a6b6 Actually create runtime path if needed
This checked if the path was readable and only then tried creating it,
which... isn't right.

Fixes #7335.
2020-09-17 12:33:56 +02:00
Soumya
a2b2bcef6e Add a $status_generation variable that's incremented for each interactive command that produces a status.
This can be used to determine whether the previous command produced a real status, or just carried over the status from the command before it. Backgrounded commands and variable assignments will not increment status_generation, all other commands will.
2020-08-05 12:23:49 -07:00
ridiculousfish
c9b42c6f1f Stop #include-ing wcstringutil.h in flog.h
This is a header dependency that we can break.
2020-07-29 17:04:18 -07:00
ridiculousfish
db086fc5d4 Eliminate wcs2str
Use std::string variants everywhere instead
2020-07-29 16:37:39 -07:00
ridiculousfish
3571754e06 Only perform universal barriers for the principal env stack
In practice this means that, if fish ever gets multiple variable stacks,
we will only incorporate environment variable changes from other fish
instances on the "main thread."
2020-07-16 16:16:03 -07:00
Johannes Altmanninger
76e0875c8f Apply clang-format 10 and selected lints from "make lint-all" 2020-07-01 00:44:06 +02:00
Mahmoud Al-Qudsi
f5b431c21b Remove std::move blocking potential copy elision 2020-06-28 18:08:13 -05:00
Mahmoud Al-Qudsi
c3849ebeba Convert var_table_t to an unordered_map
Profiling revealed string comparison in variable lookups to be a
significant hotspot. This change causes `make test` to complete ~4.5%
faster per `hyperfine`.
2020-06-25 00:56:49 -05:00
Mahmoud Al-Qudsi
a5be15da69 Optimize lookup of electric variables 2020-06-24 22:46:02 -05:00
ridiculousfish
340c8490f6 Introduce termsize_container_t
fish's handling of terminal sizes is currently rather twisted. The
essential problem is that the terminal size may change at any point from a
SIGWINCH, and common_get_{width,height} may modify it and post variable
change events from arbitrary locations.

Tighten up the semantics. Assign responsibility for managing the tty size
to a new class, `termsize_container_t`. Rationalize locking and reentrancy.

Explicitly nail down the relationship between $COLUMNS/$LINES and the tty
size. The new semantics are: whatever changed most recently takes
precendence.
2020-06-07 20:00:42 -07:00
ridiculousfish
df618a0768 Migrate DFLT_TERM from common.h to env.cpp
There's no reason every .cpp file needs to see these values.
2020-06-07 20:00:41 -07:00
ridiculousfish
229ead9b8a env_stack_t::set_termsize to operate on self, not global stack 2020-06-07 12:57:34 -07:00
Fabian Homborg
7cb452c7e7 Computed variables are global
Variables like $status and $history showed up in all scopes, including
universal, when querying with `set -q` or `set -S`.

This makes it so they all only count as set in global scope, because
we already only allow assignment to electric variables in global scope.

Fixes #7032
2020-05-27 19:59:20 +02:00
Rosen Penev
220f0a132d [clang-tidy] use auto when casting
Found with modernize-use-auto

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-05 10:13:13 +02:00
Soumya
61a9cdaa74 Add $fish_kill_signal to track the signal that terminated a command.
Set to `0` if the command exited normally.
2020-04-02 09:32:32 +02:00
Rosen Penev
06cb0bbe9a
[clang-tidy] Add several references
Found with performance-unnecessary-value-param

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-12-26 21:55:53 -08:00
Rosen Penev
856fa0ca42
[clang-tidy] Use override instead of virtual
Found with modernize-use-override
2019-12-26 21:25:12 -08:00