Commit graph

911 commits

Author SHA1 Message Date
Johannes Altmanninger
f758d39535 string pad: handle padding characters of width > 1
If the padding is not divisible by the char's width without remainder,
we pad the remainder with spaces, so the total width of the output is correct.

Also add completions, changelog entry, adjust documentation, add examples
with emoji and some tests.  Apply some minor style nitpicks and avoid extra
allocations of the input strings.
2020-09-27 21:59:15 +02:00
Andrew Prokhorenkov
92511b09c4 New command "string pad" to pad text to a given width (#7340)
Pads text to a given width, or the maximum width of all inputs.
2020-09-27 21:59:15 +02:00
Fabian Homborg
689e96263e tests: Add yet another sleep 2020-09-27 09:22:45 +02:00
ridiculousfish
e88eb508d0 Rework variable assignments during tab completion
Prior to this change, tab completing with a variable assignment like
`VAR=val cmd<tab>` would parse out and apply VAR=val, then recursively
invoke completions. This caused some awkwardness around the wrap chain -
if a wrapped command had a variable completion we risked infinite
recursion. A secondary problem is that we would run any command
substitutions inside variable assignment, which the user does not expect
to run until pressing enter.

With this change, we explicitly track variable assignments encountered
during tab completion, including both those explicitly given on the
command line and those found during wrap chain walk. We then apply them
while suppressing command substitutions.
2020-09-26 18:39:38 -07:00
ridiculousfish
cc07716dc1 Separate out variable assignments when completing
In preparation for applying variable assignments (VAR=VAL cmd), separate
them out from the command when performing completions. This includes both
those that the user typed, and any that come about through
completion --wraps.
2020-09-26 17:30:25 -07:00
ridiculousfish
45b85d28bb Completion wrap chain visited set to store only wrapped command
The "wrap chain" refers to a sequence of commands which wrap other
commands, for completion purposes. One possibility is that a wrap chain
will produce a combinatorial explosion or even an infinite loop, so there
needs to be logic to prevent that. Part of that logic is encapsulated in a
visited set (wrap_chain_visited_set_t) to prevent exploring the same item
twice.

Prior to this change, we stored pairs (command, wrapped_command). But we
only really need to store the wrapped command. Switch to that.

One consequence is that if a command wraps another command in more than
one way, we won't explore both ways. This seems unlikely in practice.
2020-09-26 17:24:59 -07:00
Fabian Homborg
f708632ca3 tests: Remove test for windows line ending message
This is flaky on launchpad for some reason, and it's really not
important enough to hold it up.

So let's just leave this untested.
2020-09-26 15:19:24 +02:00
Fabian Homborg
caccc0cddb Add more tests for -c arguments 2020-09-26 15:19:24 +02:00
Johannes Altmanninger
45e7c709f4 Consolidate complete cycle detection and always report error on cycle
Detect recursive calls to builtin complete and the internal completion in
the same place.

In 0a0149cc2 (Prevent infinite recursion when completion wraps variable assignment)
we don't print an error when completing certain aliases like:

	alias vim "A=B vim"

But we also gave no completions.
We could make this case work, but I think that trying to salvage situations
like this one is way too complex. Instead, let the user know by printing an
error. Not sure if the style of the error fits.

We could add some heuristic to alias to not add --wraps in some cyclic cases.
2020-09-26 14:56:03 +02:00
Johannes Altmanninger
f415b3b551 Update littlecheck
4a3e4c8 Allow inline #CHECK directives and ignore double-commented directives
2020-09-26 14:56:03 +02:00
Fabian Homborg
fa0c9f90f8 Read arguments with fish -c
This reads any additional positional arguments given to `fish -c` into
$argv.

We don't handle the first argument specially (as `$0`) as that's confusing and
doesn't seem very useful.

Fixes #2314.
2020-09-26 14:47:20 +02:00
Fabian Homborg
537b3f6cb1 tests/exec: Wait after writing to a file before executing it
Otherwise we might get "text file is busy", or worse no error at all.

Hoping .2 seconds is enough here.
2020-09-26 07:22:17 +02:00
Fabian Homborg
0d0ee473fa Detect windows line endings when executing a file
Fixes #2783.
2020-09-25 16:51:05 +02:00
Fabian Homborg
1188a12dfd type: Print *only* the path if given --path or --force-path
This is what happens when you check your tests in the wrong tab,
folks.

Fixes #7345.
2020-09-23 17:24:51 +02:00
Fabian Homborg
1da56f9937 Make history search smartcase
This makes history searches case-insensitive, unless the search string
contains an uppercase character.

This is what vim calls "smartcase".

Fixes #7273.
2020-09-22 16:13:24 +02:00
Johannes Altmanninger
0a0149cc2a Prevent infinite recursion when completion wraps variable assignment
Closes #7344

Apply a targeted fix to the place where complete() is called to handle nested
variable assignments.  Sadly, reporting an error is probably not okay here,
because people might legitimately use aliases like:

	alias vim "A=B command vim"

This is all a bit ugly, and I hope to find a cleaner solution.  Supporting
completions on commandlines like `x=$PWD cd $x/ ` is a nice feature but it
comes with some complexity.
2020-09-22 01:11:18 +02:00
Fabian Homborg
7934972751 Add some more type tests 2020-09-21 17:45:15 +02:00
Fabian Homborg
e8d725e051 Add tests for type
While we use `type -q` a bunch, the other options are kind of
unutilized, and so having a test is nice when we want to reimplement
it.

See #7342.
2020-09-20 10:36:17 +02:00
Fabian Homborg
7ec57f2c50 string: Handle unmatched capturing groups as empty
Instead of erroring out.

Fixes #7343.
2020-09-20 10:36:17 +02:00
ridiculousfish
5c3571d626 Revert accidental merge of #7340
This reverts back to commit d8e2cac83e.
I accidentally did a 'git push' during code review.
2020-09-19 19:31:44 -07:00
Andrew Prokhorenkov
2afa354c14 builtin_string: implement "width" argument for "string pad" 2020-09-19 19:25:57 -07:00
Andrew Prokhorenkov
efe94344e2 builtin_string: extra tests 2020-09-19 19:25:57 -07:00
Andrew Prokhorenkov
f389bb0e97 tests: added tests for "string pad" 2020-09-19 19:25:57 -07:00
Fabian Homborg
a3e20a4d38 Don't use abbreviated long options
"function --argument" is not a thing, it's "--argument-names". This only
accidentally works because our getopt is awful and allows abbreviated
long options.

Similarly, one argparse test used "--d" instead of "-d" or "--def".
2020-09-19 11:47:41 +02:00
Fabian Homborg
58245b6fe7 set_color: Honor modifiers (bold, background..) with --print-colors
Fixes #7314
2020-09-17 12:33:56 +02:00
Fabian Homborg
e86a31f6d4 Use the newly fixed test -t in isatty
Removes a weird dependency on the test command.
2020-09-16 21:02:59 +02:00
Fabian Homborg
709e91c1e6 builtin test: Let -t work for the standard streams
Since builtins don't actually have the streams connected, but instead
read input via the io_streams_t objects, this would just always say
what *fish's* fds were.

Instead, pass along some of the stream data to check those
specifically - nobody cares that `test`s fd 0 *technically* is stdin.
What they want to know is that, if they used another program in that
place, it would connect to the TTY.

This is pretty hacky - I abused static variables for this, but
since it's two bools and an int it's probably okay.

See #1228.

Fixes #4766.
2020-09-16 21:02:59 +02:00
ridiculousfish
1fd9debaad jobs test to detect zombies before running
If there is any zombie process, the jobs.fish test will fail. Add an
explicit check to report when this happens.
2020-09-13 19:28:14 -07:00
ridiculousfish
1ba9c7ea56 Use temporary files for the background job pgroup test
This also reduces the likelihood of a race.
2020-09-13 15:36:26 -07:00
ridiculousfish
a698b1f96c Reenable pgroup eval test in more robust form
This re-enables the test that eval retains pgroups, from #6806.
The old version was racey and failed a lot. In the new version, we use
temp files to resolve the race.
2020-09-13 13:44:35 -07:00
Fabian Homborg
0072367512 fish_add_path: Don't resolve symlinks
The case for symlinked directories being duplicated a lot isn't there,
but there *is* a usecase for adding the symlink rather than the
target, and that's homebrew.

E.g. homebrew installs ruby into /usr/local/Cellar/ruby/2.7.1_2/bin,
and links to it from /usr/local/opt/ruby/bin. If we add the target, we
would miss updates.

Having path entries that point to the same location isn't a big
problem - it's a path lookup, so it takes a teensy bit longer. The
canonicalization is mainly so paths don't end up duplicated via weird
spelling and so relative paths can be used.
2020-09-12 19:28:01 +02:00
Fabian Homborg
568f9031aa builtin realpath: Add --no-symlinks option
Taken from GNU realpath, this one makes realpath not resolve symlinks.

It still makes paths absolute and handles duplicate and trailing
slashes.

(useful in fish_add_path)
2020-09-12 19:26:04 +02:00
Fabian Homborg
0e9b496bba Fix bigword bindings with single-character words
With a commandline like

```
a b c d
```

and the cursor at the beginning, this would eat "a b", which isn't a
sensible bigword.

Bigword should be "a word, with optional leading whitespace".

This was caused by an overly zealous state-machine that always ate one
char and only *then* started eating leading whitespace.

Instead eat *a character*, and if it was whitespace go on eating
whitespace, and if it was a printable go straight to only eating
printables.

Fixes #7325.
2020-09-11 20:13:06 +02:00
Fabian Homborg
30b2dc2b97 Don't enqueue a repaint in the middle of one
This can easily lead to an infinite loop, if a variable handler
triggers a repaint and the variable is set in the prompt, e.g. some of
the git variables.

A simple way to reproduce:

    function fish_mode_prompt
        commandline -f repaint
    end

Repainting executes the mode prompt, which triggers a repaint, which
triggers the mode prompt, ....

So we just set a flag and check it.

Fixes #7324.
2020-09-11 19:23:26 +02:00
Fabian Homborg
903b7888d3 complete: Make -c optional
Currently, completions have to be specified like

```fish
complete -c foo -l opt
```

while

```fish
complete foo -l opt
```

just complains about there being too many arguments.

That's kinda useless, so we just assume if there is one left-over
argument that it's meant to be the command.

Theoretically we could also use *all* the arguments as commands to
complete, but that seems unlikely to be what the user wants.

(I don't think multi-command completions really happen)
2020-09-09 20:23:08 +02:00
Fabian Homborg
a8e237f0f9 Let complete show completions for one command if just given -c
Currently only `complete` will list completions, and it will list all
of them.

That's a bit ridiculous, especially since `complete -c foo` just does nothing.

So just make `complete -c foo` list all the completions for `foo`.
2020-09-09 18:37:39 +02:00
Fabian Homborg
fbe56a84c7 tests: Export $TERM
I think this might be causing problems on Github CI.
2020-09-06 11:15:54 +02:00
Fabian Homborg
340de73172 Call "fish_command_not_found" if a command wasn't found
Previously, when a command wasn't found, fish would emit the
"fish_command_not_found" *event*.

This was annoying as it was hard to override (the code ended up
checking for a function called `__fish_command_not_found_handler`
anyway!), the setup was ugly,
and it's useless - there is no use case for multiple command-not-found handlers.

Instead, let's just call a function `fish_command_not_found` if it
exists, or print the default message otherwise.

The event is completely removed, but because a missing event is not an error
(MEISNAE in C++-speak) this isn't an issue.

Note that, for backwards-compatibility, we still keep the default
handler function around even tho the new one is hard-coded in C++.

Also, if we detect a previous handler, the new handler just calls it.

This way, the backwards-compatible way to install a custom handler is:

```fish
function __fish_command_not_found_handler --on-event fish_command_not_found
    # do a little dance, make a little love, get down tonight
end
```

and the new hotness is

```fish
function fish_command_not_found
    # do the thing
end
```

Fixes #7293.
2020-09-06 11:15:54 +02:00
Fabian Homborg
4817f97823 tests: Print some more info in the job_summary test for debugging
This one fails a bunch on CI and I have no idea why.
2020-09-04 17:53:17 +02:00
Fabian Homborg
bfb5b28d0f Let command, jobs and type take --query instead of --quiet
Now command, jobs, type, abbr, builtin, functions and set take `-q` to
query for existence, but the long option is inconsistent.

The first three use `--quiet`, the latter use `--query`. Add `--query`
to the first three, but keep `--quiet` around.

Fixes #7276.
2020-09-04 16:55:09 +02:00
Fabian Homborg
6ca2dbecfb Remove duplicated test
Fixes #7307.
2020-09-04 16:30:13 +02:00
Fabian Homborg
3fcf4e1b20 tests: Shorten a sleep
This waited for a full second just to call `wait`.

Instead let's use 300ms, saving a full 700ms per test run.
2020-09-04 16:29:53 +02:00
ridiculousfish
30d0315b60 Add a test that fish_exit handlers run on receipt of SIGHUP 2020-08-30 15:09:34 -07:00
ridiculousfish
0379f21870 Correctly cancel on receipt of SIGHUP
When we receive SIGHUP, stop executing normal fish script (but allow
exit handlers to run).
2020-08-30 15:09:34 -07:00
Fabian Homborg
5b1c000a2e math: Add bitwise and/or functions
Just as `math "bitand(5,3)"` and `math "bitor(6,2)"`.

These cast to long long before doing their thing,
so they truncate to an integer, producing weird results with floats.

That's to be expected because float representation is *very*
different, and performing bitwise operations on floats feels quite useless.

Fixes #7281.
2020-08-26 17:48:58 +02:00
ridiculousfish
47480b2dbd Remove redraw coalescing logic
Prior to this change, if we saw more than one repaint readline command in
a row, we would try to ignore the second one. However this was never the
right thing to do since sometimes we really do need to repaint twice in a
row (e.g. the user hits Ctrl+L twice). Previously we were saved by the
buginess of this mechanism but with the repainting refactoring we see
missing redraws.

Remove the coalescing logic and add a test. Fixes #7280.
2020-08-24 13:22:35 -07:00
ridiculousfish
073334f307 Stop setting TERM in history test
Because TERM was set to something other than 'dumb', we were subject to
syntax highlighting and other interactive features that would affect the
output. In practice we were getting lucky timing-wise, but with upcoming
interactive changes syntax highlighting started to fail this test.
2020-08-22 19:15:54 -07:00
ridiculousfish
29c1139a6e Correct a missing function call in bind.py
Unclear why this test was passing...
2020-08-22 17:48:50 -07:00
Johannes Altmanninger
19943576e4 fish_indent: preserve semis in if and while conditions
It could be nice to use a heuristic for this in future, but for now let's
stick to the old behavior so we can keep formatting scripts without occasional
bad formatting changes.

A heuristic could also be used to break lines after |, && or || but I don't
think there is much need for that at the moment.

Closes #7252
2020-08-17 17:40:28 +02:00
ridiculousfish
82fed6fc2f Correctly propagate signals from cancelled jobs into parse_execution_context
This concerns code like the following:

    while true ; sleep 100; end

Here 'while' is a "simple block execution" and does not create a new job,
or get a pgid. Each 'sleep' however is an external command execution, and
is treated as a distinct job. (bash is the same way). So `while` and
`sleep` are always in different job groups.

The problem comes about if 'sleep' is cancelled through SIGINT or SIGQUIT.
Prior to 2a4c545b21, if *any* process got a SIGINT or SIGQUIT, then fish
would mark a global "stop executing" variable. This obviously prevents
background execution of fish functions.

In 2a4c545b21, this was changed so only the job's group gets marked as
cancelled. However in the case of one job group spawning another, we
weren't propagating the signal.

This adds a signal to parse_execution_context which the parser checks after
execution. It's not ideal since now we have three different places where
signals can be recorded. However it fixes this regression which is too
important to leave unfixed for long.

Fixes #7259
2020-08-13 15:30:15 -07:00