Commit graph

2717 commits

Author SHA1 Message Date
ridiculousfish
0f7bba5f0e Introduce operation_context_t
This commit recognizes an existing pattern: many operations need some
combination of a set of variables, a way to detect cancellation, and
sometimes a parser. For example, tab completion needs a parser to execute
custom completions, the variable set, should cancel on SIGINT. Background
autosuggestions don't need a parser, but they do need the variables and
should cancel if the user types something new. Etc.

This introduces a new triple operation_context_t that wraps these concepts
up. This simplifies many method signatures and argument passing.
2020-01-16 15:21:28 -08:00
ridiculousfish
db98ee13a9 Make complete() return the completion list directly
Returning it through a pointer was a remnant of pre C++-11 days.
2020-01-16 15:18:50 -08:00
ridiculousfish
4bb18eaf42 Use completion_list_t naming everywhere
std::vector<completion_t> -> completion_list_t
2020-01-16 15:18:49 -08:00
ridiculousfish
98e714f98f clang-format .cpp and .h files 2020-01-16 15:18:28 -08:00
ridiculousfish
6705a2efc6 Migrate a bunch of code out of common.h
Put it into wcstringutil, path, or a new file null_terminated_array.
2020-01-15 13:16:43 -08:00
ridiculousfish
273afca3da Remove some dead code 2020-01-15 11:59:40 -08:00
ridiculousfish
4f01eef88d Default some ivars in wildcard_expander_t 2020-01-15 11:43:10 -08:00
ridiculousfish
5f130c2d6d Give wildcard_expand_result_t a real return value
Use an enum instead of an int.
2020-01-15 11:11:43 -08:00
ridiculousfish
7e1270ae70 Be more disciplined about cancellation signals
Rather than storing a "should cancel" flag in the parser, store the
actual signal which triggered cancellation.
2020-01-14 15:20:04 -08:00
ridiculousfish
47b87dbeb7 Factor internal process short-circuiting together
When executing a buffered block or builtin, the usual approach is to
execute, collect output in a string, and then output that string to
stdout or whatever the redirections say. Similarly for stderr.

If we get no output, then we can elide the outputting which means
skipping the background thread. In this case we just mark the process as
finished immediately.

We do this in multiple locations which is confusing. Factor them all
together into a new function run_internal_process_or_short_circuit.
2020-01-13 14:46:31 -08:00
ridiculousfish
fe4f7fea5c run_internal_process can no longer fail, remove its bool return 2020-01-13 14:40:24 -08:00
ridiculousfish
1efa641105 Move some fflushes around in handle_builtin_output 2020-01-13 14:35:20 -08:00
ridiculousfish
7b25787e52 Mild refactoring of exec_block_or_func_process
Reduce some code duplication.
2020-01-13 14:28:28 -08:00
ridiculousfish
399062c219 Rationalize a bit of how failed exec() works
We don't need to mark the job as completed in this case, because the
caller will remove the job.
2020-01-13 14:18:43 -08:00
ridiculousfish
8d598dcffc Use handle_child_status when reaping internal procs
This reduces the number of distinct locations where we mark a process as
completed.
2020-01-13 14:12:05 -08:00
Fabian Homborg
31e6ae0099 Ignore EPERM for setpgid
In case we are a session leader, we get a harmless EPERM, yet we used
to quit. Stop doing that.

Fixes #6499.
2020-01-13 18:57:19 +01:00
Fabian Homborg
759d5a1fb3 Fix uvar error message
This used a wstring format when it was a narrow string.
2020-01-13 17:48:09 +01:00
Johannes Altmanninger
9a355d5482 complete: replace confusing comment with test case 2020-01-08 17:53:46 +01:00
Johannes Altmanninger
75fa3b6bae unbreak missing argument error on long option 2020-01-08 17:33:36 +01:00
Johannes Altmanninger
fdf398e435 show missing argument error only for last flag
closes #6483
2020-01-08 14:59:26 +01:00
Johannes Altmanninger
0e707b88f0 argparse: fix error message for missing option argument
case #1 in #6483
2020-01-08 14:38:05 +01:00
Johannes Altmanninger
992c864f26 Don't overwrite unrelated variables with for-loop-variables
for-loops that were not inside a function could overwrite global
and universal variables with the loop variable.  Avoid this by making
for-loop-variables local variables in their enclosing scope.

This means that if someone does:

    set a global
    for a in local; end
    echo $a

The local $a will shadow the global one (but not be visible in child
scopes). Which is surprising, but less dangerous than the previous
behavior.

The detection whether the loop is running inside a function was failing
inside command substitutions. Remove this special handling of functions
alltogether, it's not needed anymore.

Fixes #6480
2020-01-08 09:10:14 +01:00
ridiculousfish
e0cdea9bb6 Correct the usleep calculation in fish_test_helper
'fish_test_helper print_pid_then_sleep' tried to sleep for .5 seconds,
but instead it divided by .5 so it actually slept for 2 seconds.

This exceeds the maximum value on NetBSD so it wasn't sleeping at all
there.

Fixes #6476
2020-01-07 17:07:51 -08:00
Norio Nomura
cc7618985a Don't override exit status when stderr is closed by 2>&-
fixes #6470
2020-01-07 19:57:35 +01:00
Fabian Homborg
484e590b7b Readd unconst cast to tparm calls
Removed in 0dfa7421f3, breaks build with NetBSD curses.
2020-01-05 22:28:39 +01:00
ridiculousfish
f1ce967dfa Do not allow empty items to be added to history
Empty items are used as sentinels to indicate that we've reached the end of
history, so they should not be added as actual items. Enforce this.

Fixes #6032
2020-01-05 12:47:02 -08:00
Fabian Homborg
0f362b4bb2 Change c{begin,end} to begin,end
Unfortunately old distributions are old.

Fixes build failures on GCC 4.8 (RHEL6/7).
2020-01-05 15:44:05 +01:00
Fabian Homborg
0a379135a4 exec_job: Only call getpgrp() once
This reduces the syscall count for `fish -c exit` from 651 to 566.

We don't attempt to *cache* the pgrp or anything, we just call it once
when we're about to execute the job to see if we are in foreground and
to assign it to the job, instead of once for checking foreground and
once to give it to the job.

Caching it with a simple `static` would get the count down to 480, but
it's possible for fish to have its pgroup changed.
2020-01-05 09:41:06 +01:00
Aaron Gyes
d0b0c9a77e minor pcre2_matcher_t cleanup 2020-01-03 16:17:41 -08:00
Aaron Gyes
5281aca659 builtin_string.cpp: remove effectively dead variable 2020-01-03 16:17:41 -08:00
Mahmoud Al-Qudsi
038084b8bf Optimize generation, filtering, and sort of completions 2020-01-03 17:54:14 -06:00
ridiculousfish
62302ee172 Properly print leading comments and indentation in functions
Store the entire function declaration, not just its job list.
This allows us to extract the body of the function complete with any
leading comments and indents.

Fixes #5285
2020-01-03 14:40:28 -08:00
Johannes Altmanninger
c3374edc59 Reject time with background jobs
This check could probably done earlier in the parser but it works.
2020-01-03 01:07:49 -06:00
Johannes Altmanninger
3de95038b0 Make "time" a job prefix
In particular, this allows `true && time true`, or `true; and time true`,
and both `time not true` as well as `not time true` (like bash).

time is valid only as job _prefix_, so `true | time true` could call
`/bin/time` (same in bash)

See discussion in #6442
2020-01-03 01:07:49 -06:00
ridiculousfish
89880891d0 Revert "fish_tests to set HOME and other variables to temporary dir"
This reverts commit cca57a7a87.

The tests target already sets some variables - backing this out.
2020-01-01 17:24:14 -08:00
ridiculousfish
cca57a7a87 fish_tests to set HOME and other variables to temporary dir
Rather than placing files in the user's home directory, have fish_tests
manipulate HOME to be a temporary directory.
2020-01-01 16:34:56 -08:00
ridiculousfish
65e9f31c7a Use autoclose_fd_t more pervasively in history 2020-01-01 13:49:10 -08:00
ridiculousfish
5aa22adccc Make history_filename return a maybe_t<wcstring>
This function can fail, so rather than forcing clients to check the return
value as empty, allow it to return none().
2020-01-01 12:34:42 -08:00
ridiculousfish
b691d3130e Don't give job IDs to block processes either
Extend the commit 8e17d29e04 to block processes, for example:

    begin ; stuff ; end

or if/while blocks as well.

Note there's an existing optimization where we do not create a job for a
block if it has no redirections.
2019-12-31 13:12:24 -08:00
ridiculousfish
a6e5583b5b Correct reordering of jobs in job_promote
job_promote attempts to bring the most recently "touched" job to the front
of the job list. It did this via:

    std::rotate(begin, job, end)

However this has the effect of pushing job-1 to the end. That is,
promoting '2' in [1, 2, 3] would result in [2, 3, 1].

Correct this by replacing it with:

    std::rotate(begin, job, job+1);

now we get the desired [2, 1, 3].

Also add a test.
2019-12-31 12:41:11 -08:00
Dan Zimmerman
8e17d29e04 Introduce the internal jobs for functions
This PR is aimed at improving how job ids are assigned. In particular,
previous to this commit, a job id would be consumed by functions (and
thus aliases). Since it's usual to use functions as command wrappers
this results in awkward job id assignments.

For example if the user is like me and just made the jump from vim -> neovim
then the user might create the following alias:
```
alias vim=nvim
```
Previous to this commit if the user ran `vim` after setting up this
alias, backgrounded (^Z) and ran `jobs` then the output might be:
```
Job	Group	State	Command
2	60267	stopped	nvim  $argv
```
If the user subsequently opened another vim (nvim) session, backgrounded
and ran jobs then they might see what follows:
```
Job	Group	State	Command
4	70542	stopped	nvim  $argv
2	60267	stopped	nvim  $argv
```
These job ids feel unnatural, especially when transitioning away from
e.g. bash where job ids are sequentially incremented (and aliases/functions
don't consume a job id).

See #6053 for more details.

As @ridiculousfish pointed out in
https://github.com/fish-shell/fish-shell/issues/6053#issuecomment-559899400,
we want to elide a job's job id if it corresponds to a single function in the
foreground. This translates to the following prerequisites:

- A job must correspond to a single process (i.e. the job continuation
    must be empty)
- A job must be in the foreground (i.e. `&` wasn't appended)
- The job's single process must resolve to a function invocation

If all of these conditions are true then we should mark a job as
"internal" and somehow remove it from consideration when any
infrastructure tries to interact with jobs / job ids.

I saw two paths to implement these requirements:

- At the time of job creation calculate whether or not a job is
  "internal" and use a separate list of job ids to track their ids.
  Additionally introduce a new flag denoting that a job is internal so
  that e.g. `jobs` doesn't list internal jobs
  - I started implementing this route but quickly realized I was
    computing the same information that would be computed later on (e.g.
    "is this job a single process" and "is this jobs statement a
    function"). Specifically I was computing data that populate_job_process
    would end up computing later anyway. Additionally this added some
    weird complexities to the job system (after the change there were two
    job id lists AND an additional flag that had to be taken into
    consideration)
- Once a function is about to be executed we release the current jobs
  job id if the prerequisites are satisfied (which at this point have
  been fully computed).
  - I opted for this solution since it seems cleaner. In this
  implementation "releasing a job id" is done by both calling
  `release_job_id` and by marking the internal job_id member variable to
  -1. The former operation allows subsequent child jobs to reuse that
  same job id (so e.g. the situation described in Motivation doesn't
  occur), and the latter ensures that no other job / job id
  infrastructure will interact with these jobs because valid jobs have
  positive job ids. The second operation causes job_id to become
  non-const which leads to the list of code changes outside of `exec.c`
  (i.e. a codemod from `job_t::job_id` -> `job_t::job_id()` and moving the
   old member variable to a non-const private `job_t::job_id_`)

Note: Its very possible I missed something and setting the job id to -1
will break some other infrastructure, please let me know if so!

I tried to run `make/ninja lint`, but a bunch of non-relevant issues
appeared (e.g. `fatal error: 'config.h' file not found`). I did
successfully clang-format (`git clang-format -f`) and run tests, though.
This PR closes #6053.
2019-12-31 10:08:50 -08:00
Fabian Homborg
033a832687
Merge pull request #6447 from neheb/clang2
Several more small clang-tidy cleanups
2019-12-31 18:47:24 +01:00
ridiculousfish
c963442999 Collapse io_data switch statements
Now that each io_data knows its source and target fd, we don't need to switch
on its types any more.
2019-12-29 15:51:22 -08:00
ridiculousfish
0af5608ce8 io_data_t to store the source_fd directly
Now that all io_data_ts know their source fd, just store it directly in
the base class. This will simplify some uses of io_data_t.
2019-12-29 15:14:08 -08:00
ridiculousfish
5d55004841 Stop adding close actions in pipe and bufferfills
Now that all pipes are marked CLOEXEC, there is no reason to add explicit
close calls here.
2019-12-29 15:00:12 -08:00
ridiculousfish
d0cefe8b65 Always mark pipes as cloexec
There is never a reason to keep these open in exec.
2019-12-29 14:57:16 -08:00
ridiculousfish
b784a0caa3 dup2_list_t::resolve_chain to stop returning maybe
It can no longer fail.
2019-12-29 14:49:05 -08:00
ridiculousfish
94dcd1cc07 Use the given parser when fetching certain histories 2019-12-29 14:26:46 -08:00
ridiculousfish
9f7972a08b clang-format C++ files 2019-12-29 14:25:42 -08:00
Johannes Altmanninger
3d9c0d3c69 Show the first few history entries in set | grep history
As before, but do so efficiently. See #6290
2019-12-29 17:43:25 +01:00