Commit Graph

3777 Commits

Author SHA1 Message Date
ridiculousfish
48b42c0255 Reorganize input_event_queue_t declaration
This moves the private bits to the bottom. No functional change.
2021-04-17 16:43:27 -07:00
ridiculousfish
3b32a32dda Replace some format_strings with to_string
This is hopefully a little faster and a little safer as there's
no format string involved.
2021-04-17 16:43:27 -07:00
ridiculousfish
be9579418f Refactor to use has_external_proc instead of a manual loop
No functional change here.
2021-04-17 16:43:27 -07:00
ridiculousfish
e299f89db3 Rename print_job_summary to call_job_summary
No functional change; this is simply a less misleading name.
2021-04-17 16:43:27 -07:00
Fabian Homborg
ef96a6614b Update termsize before a sigwinch handler
This could have been one iteration off, e.g.

```fish
function on-winch --on-signal winch
    echo $LINES
end
```

Resize the terminal, it'll print e.g.

24

then run `echo $LINES` interactively, it might have a different answer.

This isn't beautiful, but it works. A better solution might be to make
the termsize vars electric and just always update them on read?
2021-04-14 17:27:53 +02:00
Fabian Homborg
3e473b9f37 io: Silence write error with EPIPE
With something like

```
history | head -n 1
```

this would error "write: Broken pipe", which is just annoying. There
is no *problem* here, `head` closes this on purpose.

Fixes #7924.
2021-04-13 10:38:17 +02:00
David Adam
a918cabf5e feature flags: default stderr-nocaret to on 2021-04-12 22:18:48 +08:00
David Adam
2e44076397 feature flags: add the notion of a default value for each flag 2021-04-12 22:18:48 +08:00
Fabian Homborg
7210261513 complete: Obey --force-files without an option
Things like

```fish
complete command -n '__fish_seen_subcommand_from subcommand'
--force-files
```

would not be obeyed because we only checked force-files when there was
an option.

Fixes #7920.
2021-04-10 21:58:40 +02:00
Fabian Homborg
bc4d597e91 Don't abandon line before the first prompt
When a terminal in a tiling WM starts, it might start the shell before
it has reached its "final" size. So we get the terminal width,
then the terminal would be resized (to appease the tiling logic),
and then we would print the abandon line with the omitted newline
char, only if the size got smaller (likely!), we would overflow the
line and land on the next.

So what we do is a bit of a hack: We don't abandon the first line.

This means that `printf %s foo; fish` will overwrite the `foo`, but
that's a super small problem and I don't see another way around this.

Fixes #7893.
2021-04-10 17:13:44 +02:00
Fabian Homborg
e2146a0eee complete: Stop using the function definition as the description
This isn't helpful, and entirely unreadable. Excerpt:

```
__fish_git_prompt_set_char  (set -l user_variable_name "$argv[1]" set -l char $argv[2] if set -q argv[3] and begin set -q __fish_git_prompt_show_informative_status or set -q __fi…)
```

Fixes #7911.
2021-04-08 15:36:59 +02:00
ridiculousfish
ed51e2baac Prevent hanging when restoring the foreground process group at exit
When fish starts, it notices which pgroup owns the tty, and then it
restores that pgroup's tty ownership when it exits. However if fish does
not own the tty, then (on Mac at least) the tcsetpgrp call triggers a
SIGSTOP and fish will hang while trying to exit.

The first change is to ignore SIGTTOU instead of defaulting it. This
prevents the hang; however it risks re-introducing #7060.

The second change somewhat mitigates the risk of the first: only do the
restore if the initial pgroup is different than fish's pgroup. This
prevents some useless calls which might potentially steal the tty from
another process (e.g. in #7060).
2021-04-05 17:44:14 -07:00
ridiculousfish
a69e94d954 add_disowned_job to accept its parameter by const pointer
It never modified the job.
2021-04-03 21:05:32 -07:00
ridiculousfish
73ec89917a Remove the SIGIO signal handler and universal notifier
If fish launches a program and that program marks stdin as O_ASYNC, then
fish will start receiving SIGIO events on Mac. This occurs even though
the file descriptor itself does not have the O_ASYNC flag set.

SIGIO is reported as interrupting select which then breaks multiple-key
bindings, especially in vi-mode.

As the SIGIO based universal notifier is disabled, remove it and the
SIGIO handler itself. This allows fish to ignore properly ignore SIGIO.

Fixes #7853
2021-04-03 18:11:29 -07:00
ridiculousfish
36ad116b34 Properly report errors when builtin output fails
This correctly sets $status when a builtin succeeds but its output fails;
for example if the output is redirected to a file and that write fails.

Fixes #7857
2021-04-03 16:11:25 -07:00
Johannes Altmanninger
ed5e5a9d49 Enhance greppability of the "return symbol" for abandoned newlines
Was looking for this for #7893
2021-04-02 08:09:56 +02:00
Fabian Homborg
dbd608cb6a tinyexpr: Use cmath with std::
The oldschool math.h imports the math functions into the global
namespace, cmath imports them into std::.

Unfortunately, we already use cmath elsewhere, and including math.h
doesn't reimport them in some systems, so now they can't find them
with std::.

Fixes #7882.
2021-03-31 17:21:46 +02:00
David Adam
0c03a0267f Revert "tinyexpr: use std:: namespace for older libstdc++"
This reverts commit f46444f106.

This commit does not build on macOS or RHEL 7.
2021-03-31 22:53:18 +08:00
David Adam
f46444f106 tinyexpr: use std:: namespace for older libstdc++
Fixes the build on Ubuntu Xenial 16.04 and CentOS 7.
2021-03-31 11:21:42 +08:00
Fabian Homborg
ed9268f99c
math: Make function parentheses optional (#7877)
* math: Make function parentheses optional

It's a bit annoying to use parentheses here because that requires
quoting or escaping.

This allows the parens to be omitted, so

math sin pi

is the same as

math 'sin(pi)'

Function calls have the lowest precedence, so

math sin 2 + 6

is the same as

math 'sin(2 + 6)'

* Add more tests

* Add a note to the docs

* even moar docs

Moar docca

* moar tests

Call me Nikola Testla
2021-03-30 17:21:28 +02:00
Fabian Homborg
18e332772d functions: Add "--no-details" flag and use it in funced
This inhibits the function path comment which is annoying in `funced`.

Fixes #7879.
2021-03-30 16:54:26 +02:00
Karolina Gontarek
da2f7999ad
Fix backward-kill-path-component erasing extra tokens (#7872)
Fixes #6258
2021-03-29 22:58:50 +02:00
Fabian Homborg
fd4803ac6a Update BEL comment
We no longer send it.
2021-03-29 18:03:36 +02:00
Fabian Homborg
312cfacf71 Don't ring the bell in reader_flash
The bell is a mechanism for important notifications. Not having things
to do in response to a keypress isn't important enough, especially
because we're already flashing and the bell might actually be a bell.

Fixes #7875.
2021-03-29 17:49:47 +02: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
0f0995cad0 Remove unused COMMAND_NOT_BUILTIN enum
This was an enum whose values were never used; we can just remove it.
2021-03-28 22:19:36 -07:00
ridiculousfish
0aec597a36 Switch a cast from C style to C++ style 2021-03-28 20:04:34 -07:00
ridiculousfish
48868e5667 Switch builtin execution to the performer model
In preparation for concurrent execution, introduce a
`get_performer_for_builtin` function. This function itself returns a
function, which when called will run the builtin. The idea is that the
function may be called on a background thread (but not in this commit).
2021-03-28 15:31:25 -07: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
ridiculousfish
e0e4b11dbd Make arguments to builtins const
Prior to this change, builtins would take their arguments as `wchar_t **`.
This implies that the order of the arguments may be changed (which is
true, `wgetopter` does so) but also that the strings themselves may be
changed, which no builtin should do.

Switch them all to take `const wchar_t **` instead: now the arguments may
be rearranged but their contents may no longer be modified.
2021-03-28 15:31:25 -07:00
ridiculousfish
0b06a0ee07 Further refactoring of builtin_set
This rearranges some error handling to centralize it, and performs
additional cleanup.
2021-03-28 15:31:25 -07:00
ridiculousfish
6c46ea0ed2 Refactor builtin_set
This cleans up builtin_set a bit, with the meat of the change being
reworking `parse_index` into `split_var_and_indexes`.

`parse_index` was a function that split a string like `foo[1 3..5]` into
its variable name `foo` and the indexes (here `1 3 4 5`). It had a funny
interface where it would modify a C string in-place. Switch it to return a
`split_var_t` which is a little struct wrapping up the split operation.
This simplifies memory management, and also avoids modifying the arguments
to the builtin.
2021-03-28 15:31:25 -07:00
ridiculousfish
abc66511f5 Simplify main thread requests
This replaces the main_thread_request struct with just a simple
function.
2021-03-28 15:31:25 -07:00
ridiculousfish
05d8907071 Remove the completion form of iothread_perform
Previously iothread_perform could do something on a background thread, and
then do something on the main thread. But we no longer use that second
part: instead everything goes through debounce. Remove the completion
parameter from iothread_perform.
2021-03-28 15:31:25 -07:00
Ilan Cosman
c762c62464 Add max and min math functions 2021-03-28 13:22:44 -07:00
ridiculousfish
a5ea8570ae Properly syntax highlight commands that get entered too fast
This fixes the following problem: if a command is entered while the
previous command is still executing, fish will see it all at once and
execute it before syntax highlighting as a chance to start. So the
command will appear wrong on the terminal. Fix this by detecting this
case and performing a fast no-io highlight.

An example of how to reproduce this:
run `sleep 3` and then type `echo foo` while the sleep is still running.
2021-03-28 12:52:59 -07:00
Fabian Homborg
4e4852c40a history: Improve bash import check
- Check for special characters *before* attempting to parse
- Also ignore lines with `{` and `*`
- Also skip lines with `<<` because that might be a heredoc (or a
- `<<<` herestring)

Fixes #7874.
2021-03-28 20:30:37 +02:00
Fabian Homborg
e7abb52526 Remove special "default" value for $fish_history
This is really of very little use and makes checking $fish_history
harder because it makes two values mean the same thing.

Fixes #7650
2021-03-28 12:09:58 +02:00
ridiculousfish
b44f40547b Rationalize exit codes for failed execs
This cleans up some exit code processing. Previously a failed exec
would produce exit code 125 unconditionally, while a failed posix_spawn
would produce exit code 1 (!).

With this change, fish reports exit code 126 for not-executable, and 127
for file-not-found. This matches bash.
2021-03-27 21:37:46 -07:00
ridiculousfish
694e112a9b Do not implicitly pass .fish files to /bin/sh
This expands the heuristic introduced in #7802 to prevent implicitly
passing files ending in .fish to /bin/sh.
2021-03-27 19:17:18 -07:00
ridiculousfish
eb71e4555f Clean up and relnote shebangless script support
This adds a test for shebangless support from #7802, cleans up some of
its tricks, and includes it in the changelog.
2021-03-27 16:08:42 -07:00
Justine Tunney
0048730a67 Allow more scripts without #!
This change modifies the fish safety check surrounding execve / spawn so
it can run shell scripts having concatenated binary content. We're using
the same safety check as FreeBSD /bin/sh [1] and the Z-shell [5].  POSIX
was recently revised to require this behavior:

    "The input file may be of any type, but the initial portion of the
     file intended to be parsed according to the shell grammar (XREF to
     XSH 2.10.2 Shell Grammar Rules) shall consist of characters and
     shall not contain the NUL character. The shell shall not enforce
     any line length limits."

    "Earlier versions of this standard required that input files to the
     shell be text files except that line lengths were unlimited.
     However, that was overly restrictive in relation to the fact that
     shells can parse a script without a trailing newline, and in
     relation to a common practice of concatenating a shell script
     ending with an 'exit' or 'exec $command' with a binary data payload
     to form a single-file self-extracting archive." [2] [3]

One example use case of such scripts, is the Cosmopolitan C Library [4]
which configuse the GNU Linker to output a polyglot shell+binary format
that runs on Linux / Mac / Windows / FreeBSD / OpenBSD / NetBSD / BIOS.

Fixes jart/cosmopolitan#88

[1] 9a1cd36331
[2] http://austingroupbugs.net/view.php?id=1250
[3] http://austingroupbugs.net/view.php?id=1226#c4394
[4] https://justine.lol/cosmopolitan/index.html
[5] 326d9c203b
2021-03-27 13:46:11 -07:00
Fabian Homborg
df53d1415d
cd first, ask questions later (#7586)
cd: Just try to cd without checking first

Some filesystems are broken and error out on `stat(3)` of existing and
cd-able directories.

So we just try to `fchdir` and report errors later.

Fixes #7577.
2021-03-27 18:28:03 +01:00
Fabian Homborg
3255999794 Bravely set job control to full at startup
We have no idea why this was even a thing. For now simply set it to
"all"/"full" (why these two names? no idea) at startup and allow
changing it later.

Settting it *immediately* when defining the variable sets it too soon
because we don't have the interactive signal handlers
enabled (including the one for SIGTTOU), so let's first settle for
this little piece of awkwardness.

This needs widespread testing, so we merge it early, immediately after
the release.

Fixes #5036
Fixes #5832
Fixes #7721

(and probably numerous others)
2021-03-26 19:32:14 +01:00
Fabian Homborg
c1fe5be0ce parse_util: Remove locate_cmdsubst
We have *3* functions to find command substitutions, this is the most awkward.
2021-03-26 19:32:14 +01:00
Fabian Homborg
163f42ac62 tinyexpr: Remove invalid const
We const cast these, so they aren't actually const,
and const doesn't actually help with optimization or anything (because const_cast exists),
so I would rather remove this, because const_cast gives me both the heebies and the jeebies.
2021-03-26 19:30:38 +01:00
Fabian Homborg
cbd8f5f63e math: Add log2
This was already in the documentation as an example, now it is
actually working.

Fixes #7734
2021-03-26 19:30:38 +01:00
Fabian Homborg
7f7cfcf339 Only donate term if we're interactive *and* have the terminal
As it turns out otherwise fish would hang when sddm starts it as the login shell.

Belongs to #7842.
2021-03-22 17:00:43 +01:00
ridiculousfish
8d54d2b60e Skip long arguments in syntax highlighting path detection
When fish performs syntax highlighting, it attempts to determine which
arguments are valid paths and underline them. Skip paths whose length
exceeds PATH_MAX. This is an optimization: such strings are almost
certainly not valid paths and checking them may be expensive.

Relevant is #7837
2021-03-21 16:59:22 -07:00
ridiculousfish
cf35431af9 Reimplement wbasename and wdirname
Previously wbasename and wdirname wrapped the system-provided basename
and dirname. But these have thread-safety issues and some surprising
error conditions on Mac. Just reimplement these per the OpenGroup spec.

In particular these no longer trigger a null-dereference if the input
exceeds PATH_MAX.

Add some tests too.

This fixes #7837
2021-03-21 16:33:04 -07:00
ridiculousfish
6e1b324343 Add some tests for dirname and basename
This is in preparation for replacing our wrappers around the C versions,
with custom versions instead.
2021-03-21 16:32:58 -07:00
ridiculousfish
a7c37e4af4 Don't block certain error signals on background threads
Previously fish attempted to block all signals on background threads, so
that they would be delivered to the main thread. But on Mac, SIGSEGV
and probably some others just get silently dropped, leading to potential
infinite loops instead of crashing. So stop blocking these signals.

With this change the null-deref in #7837 will properly crash instead of
spinning.
2021-03-21 16:32:45 -07:00
Johannes Altmanninger
206543c55b fixup! Pass some parameters by reference/move 2021-03-21 19:46:49 +01:00
Johannes Altmanninger
508044bce1 Pass some parameters by reference/move 2021-03-21 19:41:36 +01:00
Johannes Altmanninger
516a70d9cb Misc cleanups
Some as suggested by lgtm.com
2021-03-21 19:41:36 +01:00
Fabian Homborg
1018cb2a81 echo: Buffer output and write it in one go
`streams.out.push_back` for fd_streams_t writes to the
fd *immediately*. We might want to introduce a general buffering
strategy, but in this case writing it in one go is the simplest and
seems acceptable - we already have constrained the argument size, so
just pushing it out should work well enough.

See #7836
2021-03-21 17:49:22 +01:00
Fabian Homborg
e4fd664bbb Only set modes after config.fish if we're *interactive*
013a563ed0 made it so we only try to
adjust terminal modes if we are in the terminal pgroup, but that's not
enough.

Fish starts background jobs in events inside its own pgroup, so

    function on-foo --on-event foo
        fish -c 'sleep 3' &
    end

would have the backgrounded fish try to fiddle with the terminal and
succeed.

Instead, only fiddle with the terminal if we're interactive (this
should probably be extended to other bits, but this is the particular
problematic part)

Fixes #7842.
2021-03-21 10:43:47 +01:00
Karolina Gontarek
e4eaca1032
Fix wrapping for cd (#7843) 2021-03-21 09:27:19 +01:00
Johannes Altmanninger
7fea321b3e
Use the correct case in completion pager (#7744)
Consider

	$ complete -c foo -a 'aab aaB' -f
	$ foo A<TAB>

since 28d67c8 we would insert the common prefix AND show the pager.
Due to case-insensitive comparison, "b/B" was considered to be part
of the prefix. Since the prefix is added to each pager item [1]
we get wrong results. Fix this by removing the insensitive comparison
between completions - I don't think it was of much use anyway.
Commandline tokens are still matched case-insensitively, this is
just about completions.

Test this by running interactive fish inside tmux (pexpect's terminal
emulation not have enough capabilities).  Also add tests for recent
interactive regressions #7526 and #7738.

Closes #3978

[1]: b38a23a would solve this differently by giving every pager item
its own prefix, but was reverted since it needs more fixes.
2021-03-21 09:25:29 +01:00
Fabian Homborg
d79f864072 Add a note for help thing to the missing doc error message
This should cover most cases - the user didn't install the docs and is
trying to view the man page via __fish_print_help, so we don't have a
way to show anything.

But `help thing` will fall back to the online version of the docs,
which should work if there's an internet connection.

See #7824.
2021-03-19 17:39:36 +01:00
Fabian Homborg
02699d1acc Reject empty variable names
This allowed `set "" foo`, which is bogus and results in an unusable variable.
2021-03-18 19:36:57 +01:00
Johannes Altmanninger
f9e131aa93 Show an error when "builtin -h" fails to find a man page
Prior to this commit "builtin -h" would silently fail when no
documentation is installed. This happens when running fish without
installing it, or when the docs are not installed.

See #7824
2021-03-15 23:07:08 +01:00
Johannes Altmanninger
865abebd11 Simplify highlight tests by changing into dedicated test dir 2021-03-13 17:51:49 +01:00
Fabian Homborg
29ebd4a5ff tests: Don't break when a file unexpectedly exists
Creating a file called "xfoo" could break the highlight tests because
we'd suddenly get a color with valid_path set to true.

So what we do is simply compare foreground/background and forced
underline, but only check for path validity if we're expecting a valid
path.

If we're not expecting a valid path, we don't fail whether it is there
or not.

This means that we can't check for a non-valid path, but we don't
currently do that anyway and we can just burn that bridge when we get
to it.

cc @siteshwar @krobelus, who both came across this
2021-03-13 17:25:23 +01:00
ridiculousfish
3cb105adbd Restore terminal modes after running key bindings with external commands
This concerns the behavior when running an external command from a key
binding. The history is:

Prior to 5f16a299a7, fish would run these external commands in shell
modes. This meant that fish would pick up any tty changes from external
commands (see #2114).

After 5f16a299a7, fish would save and restore its shell modes around
these external commands. This introduced a regression where anything the
user typed while a bound external command was executing would be echoed,
because external command mode has ECHO set in c_lflag. (This can be
reproed easily with `bind -q 'sleep 1'` and then pressing q and typing).
So 5f16a299a7 was reverted in fd9355966.

This commit partially reverts fd9355966. It has it both ways: external
commands are launched with shell modes, but/and shell modes are restored
after the external command completes. This allows commands to muck with
the tty, as long as they can handle getting shell modes; but it does not
enable ECHO mode so it fixes the regression found in #7770.

Fixes #7770. Fixes #2114 (for the third time!)

This partially reverts commit fd9355966e.
2021-03-10 22:36:33 -08:00
Fabian Homborg
fd9355966e Stop donating the terminal for bind functions
Unfortunately this causes input coming in while bind functions are
running to show up on screen.

Since the cure is worse than the disease let's just stop doing it.

My guess is this needs to *only* be done while running an external
command.

Fixes #7770
Reintroduces #2114

Partially reverts 5f16a299a7
2021-03-10 21:21:19 +01:00
Fabian Homborg
013a563ed0 Only modify terminal modes after config.fish if we have the terminal
This tried fiddling with the terminal even if fish didn't own it, e.g.
in

    fish -c 'sleep 5' &

Fixes #7808.
2021-03-10 09:38:16 +01:00
Fabian Homborg
daa3cc17c4 Fix crash in string pad
Try:

    string pad -w 8 he \eh
2021-03-09 18:36:02 +01:00
Fabian Homborg
a7df92e187 Fix crash with set_color --print-colors --background normal
Found in conjunction with #7805.
2021-03-09 13:46:08 +01:00
Fabian Homborg
4762d52e52 output: A background is set if it's not a special non-color
For reasons unclear to me, fish enables bold mode unconditionally if
the background is set.

However, this called a background "set" if it wasn't exactly the
"normal" color, whereas set_color --print-colors would set a color
of *none*.

We have three special non-color colors:

- "normal"
- "reset"
- "none"

All of these specify some form of absence of background color, so all
of them should be checked.

Fixes #7805
2021-03-09 13:25:00 +01:00
Ilya Grigoriev
762f3aa0ce
Rewrite the real file if history file is a symlink (#7754)
* Rewrite the real file if history file is a symlink

When the history file is a symbolic link, `fish` used to overwrite
the link with a real file whenever it saved history. This makes
it follow the symlink and overwrite the real file instead.

The same issue was fixed for the `fish_variables` file in 622f2868e
from https://github.com/fish-shell/fish-shell/pull/7728.
This makes `fish_history` behave in the same way. The implementation
is nearly identical.

Since the tests for the two issues are so similar, I combined them
together and slightly expanded the older test.

This also addresses https://github.com/fish-shell/fish-shell/issues/7553.

* Add user-facing error when history renaming fails

Currently, when history file renaming fails, no message is shown to the
user. This happens, for instance, if the history file is a symlink
pointing to another filesystem.

This copies code (with a bit of variation, after reviewer comments) from

589eb34571/src/env_universal_common.cpp (L486-L491)

into `history.cpp`, so that a message is shown to the user.

* fixup! Rewrite the real file if history file is a symlink
2021-03-08 17:46:17 +01:00
Fabian Homborg
dbb74f87ba Re-read terminal modes after config.fish
Before now, we would be getting the terminal modes before config.fish,
then running config.fish without any of the term "stealing" and modes
copying. This meant that changes made to the terminal modes in there
were simply lost.

So, what we do is simply set the modes before config and then copy
them after, once.

Note that this does *not* turn off flow control again - if you turn it
on in config.fish that should work.

Fixes #7783.
2021-03-07 11:23:59 +01:00
Fabian Homborg
371516382d Create job-exit caller events inside event handlers
f7e2e7d26b forbid any job exit events
from happening inside jobs that were themselves event handlers, but
that causes e.g.

```fish
function f --on-event fish_prompt
source (echo "echo hello world" | psub)
end
```

to not trigger psub's cleanup, so it leaves files in $TMPDIR behind.

This was hit by pyenv, because that still uses `source (thing |
psub)`.

Fixes #7792.
2021-03-07 10:00:52 +01:00
Fabian Homborg
25d85bdc64 path_get_path: Remove error on unknown errno
This seems like a good idea, but there isn't anything we or anyone
else can *do* in this case. All we ever do is pile on additional
errors on the ignore pile, we can't handle any of them differently.
The command isn't a thing, so we check the next path.

The impetus for this is Cygwin apparently returning a wonderfully
useless 0, and it's not even the first one to do so.

Fixes #7785
2021-03-06 08:12:27 +01:00
Mahmoud Al-Qudsi
11951a245f Optimize pruning of job/proc exit handlers
Pre-emptively delete the handler while we have possession of the lock
before calling the event itself. It's crude, but it works.
2021-03-05 22:40:06 -06:00
Mahmoud Al-Qudsi
e7398c0248 Prune job exit handlers after running
While pid values may be reused, it is logical to assume that fish event
handlers coded against a particular job or process id mean just the job
that is currently referred to be any given pid/pgrp rather than in
perpetuity.

This trims the list of registered event handlers nice and early, and as
a bonus avoids the issue described in #7721.

The cleanup song-and-dance is extremely ugly due to the repeated locking
and unlocking of the event handler list.

Closes #7221.
2021-03-05 22:32:57 -06:00
Fabian Homborg
6bc0064a2a demangled_backtrace: Cast a thing to const char* instead of char*
Apparently this is const char* on NetBSD, so it complains.

Since it should be harmless to allow this one to be const, just do
that.
2021-03-05 19:40:44 +01:00
Fabian Homborg
c96a07dc96 Revert "Prevent redirecting internal processes to file descriptors above 2"
FDs are inherited, and redirecting those is harmless, and forbidding
that is worse than allowing all.

Fixes #7769.

This reverts commit 11a373f121.
2021-03-03 22:26:33 +01:00
Fabian Homborg
791b42f065 Disable SIGIO notifier
It doesn't work on WSL, Solaris and Archlinux (and presumably that
means future versions of other linux distros).

In its current state I don't trust it enough to enable it anywhere by
default, especially since I'm not aware of an actual issue with the
named pipe (other than that the code is ugly).

Fixes #7774
2021-03-03 22:26:28 +01:00
Fabian Homborg
955c0003ca fd_monitor: Explicity include <thread>
Might fix issues with gcc 11.0.1.

See #7764.
2021-03-02 15:27:13 +01:00
Fabian Homborg
119b978cbc type: Add --quiet back
It's supposed to be *deprecated*, not removed. The documentation even
specifically calls it out.

Fixes #7766
2021-03-02 14:53:02 +01:00
Érico Rolim
d948b34420 Include <termios.h> instead of <sys/termios.h>.
Slipped by with ffa24eb361. Given
daf5ef1bbd, fish should be using
<termios.h> in all cases.
2021-03-02 12:05:07 +01:00
Fabian Homborg
abaa057e5c Replace our only dynamic_cast with old-school casting
dynamic_cast requires rtti to be enabled. Now, this isn't a big
problem, but since this is our only dynamic_cast in the entire
codebase, and it's not serving an important function, we can just
replace it.

See #7764
2021-03-02 09:44:23 +01:00
Fabian Homborg
6b6f8d2295 Avoid changing how custom fish_titles are called
This half-reverts commit a3cb1e2dcd,
avoiding the bit that passed arguments differently.

Note that this means the initial bug is kept in the hardcoded fallback title.

Fixes #7749.
2021-02-28 08:40:39 +01:00
Fabian Homborg
459ac2b566 Reset the readline loop state when setting the buffer
Fixes #7740.
2021-02-25 16:19:28 +01:00
Mahmoud Al-Qudsi
42d9f33e16 Use a platform whitelist for opting into the SIGIO notifier
My bet is that the Illumos, Cygwin, and WSL are not the only Unix-like
systems where the SIGIO notifier won't work, and since we have a good
enough and portable alternative that we can use be default on other
platforms where we don't specifically know it'll work, it doesn't make
sense not to go with that one instead.

Even if this patch is reverted at some point and we go back to
blacklisting platforms that *don't* support the SIGIO strategy, this is
almost certainly the right choice for inclusion in a minor release like
3.2.0.

See discussion in #6585.
2021-02-24 14:40:17 -06:00
Mahmoud Al-Qudsi
ffa24eb361 Fix build on Solaris (and hopefully OpenIndiana)
* memset/memzero needs cstring/string.h (again)
 * winsize_t requires an impl from <sys/termios.h>

With this patch, I was able to get fish master to build on Solaris 11.4
without any additional dependencies (after installing gcc 7, git, and
cmake). I think the ncurses dependency can be dropped from the
OpenIndiana package?
2021-02-23 11:02:55 -06:00
Mahmoud Al-Qudsi
d95e99f2d4 Fix missing memset/memzero on Illumos
Tested w/ GCC 9 under OpenIndiana 2020.
2021-02-22 20:58:42 -06:00
Mahmoud Al-Qudsi
17926a9197 Allow low-level tests to at least run to completion under Cygwin
They still don't pass due to path differences, but at least they run to
completion so we can tell just how broken everything is.
2021-02-22 16:27:45 -06:00
Mahmoud Al-Qudsi
d769582023 Ignore intentional redundant move under GCC
This bubbled up after Wredundant-move was added to the build script and
was observed under the CI environment running GCC 9.3.0.
2021-02-22 15:55:40 -06:00
Fabian Homborg
d0a8493844 Don't open pager with only one completion
Since smartcase, we could land in a situation where we offer one
option in the pager, which is awkward.

So detect this and just insert the option directly, we can add any
more smartness later.

Fixes #7738.
2021-02-22 22:51:52 +01:00
Mahmoud Al-Qudsi
1305a0899c Fix comparison warnings on UTF-16 platforms
Without true handling of UTF-16 surrogate pairs, all we can do is
properly detect the BMP range in UTF-16 environments and bail if the
input is in a non-BMP region.

There isn't much else we can do as it is incorrect to encode the
surrogate pairs themselves (fish doesn't know what to do with them and
they're illegal under either of UTF-8 or UTF-32).

(I'm not aware of fish being used in any UTF-16 platforms other than
Cygwin.)
2021-02-22 15:03:49 -06:00
Mahmoud Al-Qudsi
215df7eec6 Extend PCRE2 wchar_t interop support to 16-bit wchar_t impls
Previously, the interop glue for more friendly access to PCRE2's
fixed-size values was only used when char32_t/wchar_t were
interchangeable and PCRE2 was used with a global 32-bit unit width set;
this patch extends the same to char16_t when wchar_t is also 16-bits
(namely on Cygwin) to avoid compilation fpermissive warnings about casts
between types of potentially different sizes.

Reported in #6585.
2021-02-22 13:51:29 -06:00
Mahmoud Al-Qudsi
2cf5fd3d5d Avoid hard compilation errors on platforms w/out O_ASYNC
Those platforms should not be using the sigio notifier in the first
place, this just stops them from failing to be able to compile fish
altogether.

See #6585
2021-02-21 22:39:32 -06:00
ridiculousfish
11a373f121 Prevent redirecting internal processes to file descriptors above 2
The user may write for example:

    echo foo >&5

and fish would try to output to file descriptor 5, within the fish process
itself. This has unpredictable effects and isn't useful. Make this an
error.

Note that the reverse is "allowed" but ignored:

    echo foo 5>&1

this conceptually dup2s stdout to fd 5, but since no builtin writes to fd
5 we ignore it.
2021-02-20 16:16:45 -08:00
Ilya Grigoriev
622f2868e1 Fix set -U when fish_variables is a symlink
Previously, `set -U` would overwrite the symlink with a
regular file.

Fixes https://github.com/fish-shell/fish-shell/issues/7466
2021-02-20 14:24:11 -08:00
ridiculousfish
8648f52857 Use wcs2string when outputting the screen
The screen output code predates the ENCODE_DIRECT scheme, and
directly-encoded bytes were not being properly output. This manifested as
private-user characters being mangled when printed as part of fish_prompt.
Just use str2wcstring instead.

Fixes #7723
2021-02-17 15:38:46 -08:00
ridiculousfish
f1b6a5939d Introduce wcs2string_appending
wcs2string_appending is like wcs2string, but appends to a std::string
instead of creating a new one. This will be more efficient when a string
can be reused, or if we want to accumulate multiple wcstrings into a
single std::string.
2021-02-17 15:36:22 -08:00
ridiculousfish
fce485e6a8 Rename bufferCount_ to buffer_count_
fish uses snake case for naming.
2021-02-17 14:25:32 -08:00
Mahmoud Al-Qudsi
774488686c Correct handling of SGR mouse tracking events
They are of variable length, taking semicolon-separated ASCII characters
and not single chars/bytes as the parameters. Additionally, the global
maximum size for a CSI is 16 characters (NPAR), even though I believe
the maximum possible mouse-tracking CSI is 12 characters.
2021-02-17 15:45:35 -06:00
ridiculousfish
7e77dc8964 Add a test for round-tripping characters in the private use area
I wrote this test believing that fish had a bug, but actually fish is
behaving correctly here. Still the test is nice so I am checking it in.
2021-02-17 12:29:51 -08:00
ridiculousfish
c0b39aaeb7 Do not reset terminal color when donating term for running key bindings
fish maintains two tty modes: one for itself and one for external
commands. The external command mode is also used when executing
fish-script key bindings, which was added in 5f16a299a7 (note that
commit had the wrong issue, the correct issue is #2114).

Prior to this fix, when switching to external modes, we would also reset
the tty's foreground color. This bumped tty's timestamp, causing us to
believe that the tty had been modified, and then repainting the prompt. If
the prompt were multi-line, we would repaint the whole prompt starting
from its second line, leaving a trailing line above it.

It would be reasonable to save the tty timestamp after resetting the
color, but given that using external modes for keybindings is new, it's
better to instead not reset the color in this case. So migrate the color
resetting to only when we run external commands.

Fixes #7722
2021-02-17 11:10:51 -08:00
Mahmoud Al-Qudsi
75af89699a Patch fish_tests to work with changed const_strlen requirements 2021-02-17 12:55:21 -06:00
Mahmoud Al-Qudsi
70b06a899d Bypass recursion in case of single trailing nul in const_strlen()
The default case for string literals like `"foo"` is a single trailing
nul, and that's what we have almost everywhere. By checking the
second-to-last index for a non-nul byte, we can skip the recursive
invocation, thus speeding up compilation that teeny, tinsy bit faster.
2021-02-17 12:26:40 -06:00
Mahmoud Al-Qudsi
071b9b13cd Reverse const_strlen() recursion logic
Rather than making the run-time complexity of the algorithm 𝒪(n) where n
is the length of the string, make it 𝒪(k) where k is the number of
trailing nul bytes.

The second parameter `index` with a default non-value is in lieu of a
helper function that would have had a name like `count_trailing_nuls()`.
2021-02-17 12:26:40 -06:00
Fabian Homborg
313b70a0c2 math: Set LC_NUMERIC to C again
e94f86e6d2 removed it in favor of using
fish_wcstod, but this broke the *output* - math currently prints
numbers with "," and then can't read them.

So we partially revert it until we come up with something better.
Maybe set $LC_NUMERIC globally inside fish?
2021-02-17 09:07:40 +01:00
Johannes Altmanninger
c0af8dae20 fish_indent: fix extra indent of continuation lines inside blocks
fish_indent used to increment the indentation level whenever we saw an escaped
newline.  This broke because of recent changes to parse_util_compute_indents().
Since parse_util_compute_indents() function already indents continuations
there is not much to do for fish_indent - we can simply query the indentation
level of the newline.  Reshuffle the code since we need to pass the offset
of the newline. Maybe this can even be simplified further.

Fixes #7720
2021-02-16 18:39:03 +01:00
Johannes Altmanninger
444c05dfb1 Do not indent after escaped newline in comment
We do something similar in fish_indent.  This fixes the spurious indent
after comments in share/completions/emerge.fish.

See #7720
2021-02-16 18:39:03 +01:00
Fabian Homborg
00fabb4fe1 Enhance fallback keybindings a bit
Bind \cc like normal, since we now no longer use a function, and bind
some important control bindings like \cs and the ever-important emacs \cb/f/p/n.

What really kills the usability here is the up-line vs up-or-search.
2021-02-15 20:54:35 +01:00
Fabian Homborg
65a760528a Skip figuring out config with --no-execute
Cuts the time to check all our fish scripts in the
check-all-fish-files.fish test roughly in half, from 3.3s
to 1.8s.
2021-02-15 18:59:54 +01:00
Fabian Homborg
c83436d050 Don't overwrite IXON/IXOFF for startup modes
We actually restore those before exit, so this would force-disable
flow control whenever fish exits.
2021-02-15 17:30:50 +01:00
Fabian Homborg
1426d61bc9 Stop disabling VSTOP/VSTART
Without flow control enabled these won't be interpreted any way.
2021-02-15 17:30:50 +01:00
Fabian Homborg
2be720b6cc Set flow control settings also in the shell
Since, unlike e.g. OPOST, this can sometimes be useful, just copy
whatever flow control settings the terminal ends up with.

We still *default* flow control to off (because it's an awful default
and allows us to bind ctrl-s), but if the user decides to enable it so
be it.

Note that it's _possible_ flow control ends up enabled accidentally, I
doubt this happens much and it won't render the shell unusable (and
good terminals might even tell you you've stopped the app).

Fixes #7704
2021-02-15 17:30:50 +01:00
Fabian Homborg
c27fb9b802 source: Escape filenames in errors
Otherwise this would look weird if you had, say, a tab in there.

See #7716.

(note that this doesn't handle e.g. zero-width-joiners, because those
aren't currently escaped. we might want to add an escape mode for
unprintable characters, but for combining codepoints that's tricky!)
2021-02-15 17:08:26 +01:00
Mahmoud Al-Qudsi
ef5db47cf7 Make const_strlen return an unsigned value 2021-02-14 11:42:26 -06:00
Fabian Homborg
552c7bc40b Don't add a space if completion only added a single "/"
This added a space if only one character was added, e.g.

```fish
cd dev<TAB>
```

would complete to

```fish
cd dev/<SPACE>
```

which makes picking deeper directories awkward.

So just go back to the old behavior of doing it for any length.

This is a regression from e27d97b02e.

cc @krobelus
2021-02-14 13:50:43 +01:00
ridiculousfish
9a165b93fb handle_builtin_output to take io_chain by const reference
There was no reason for this to be a pointer or mutable.
2021-02-13 20:05:33 -08:00
ridiculousfish
ee15bc2a36 Add a variant of valid_var_name which accepts const wchar_t *
This avoids creating some unnecessary strings.
2021-02-13 18:49:43 -08:00
Johannes Altmanninger
5b3a466fa9 Refactor: collapse if statements 2021-02-13 09:01:41 +01:00
Johannes Altmanninger
5e8a248758 Indent escaped newlines
Similar to what fish_indent does. After typing "echo \" and hitting return,
the cursor will be indented.

A possible annoyance is that when you have multiple indented lines

	echo 1 \
	    2 \
	    3 \
	    4 \

If you remove lines in the middle with Control-k, the lines below
the deleted one will start jumping around, as they are disconnected
from and reconnected to "echo".
2021-02-13 09:01:41 +01:00
Johannes Altmanninger
511747d59e Indent only leaf nodes and in-between gaps
Probably not necessary for the next commit, but this way feels more logical
2021-02-13 09:01:41 +01:00
Johannes Altmanninger
7ee4a3b40d Indent empty lines inside block 2021-02-13 09:01:41 +01:00
Johannes Altmanninger
fffcdf8792 Highlight redirection target as valid if it contains a to-be-defined variable
If a variable is undefined, but it looks like it will be defined by the
current command line, assume the user knows what they are doing.
This should cover most real-world occurrences.

Closes #6654
2021-02-13 08:59:54 +01:00
Ethel Morgan
5a0aa7824f Saturate exit codes to 255 for all builtins
After commit 6dd6a57c60, 3 remaining
builtins were affected by uint8_t overflow: `exit`, `return`, and
`functions --query`.

This commit:
- Moves the overflow check from `builtin_set_query` to `builtin_run`.
- Removes a conflicting int -> uint8_t conversion in `builtin_return`.
- Adds tests for the 3 remaining affected builtins.
- Simplifies the wording for the documentation for `set --query`.
- Does not change documentation for `functions --query`, because it does
  not state the exit code in its API.
- Updates the CHANGELOG to reflect the change to all builtins.
2021-02-13 08:41:51 +01:00
Johannes Altmanninger
e27d97b02e Do not add spaces after completions ending in "-"
Some programs use this to separate things in a word, see
https://github.com/spf13/cobra/pull/1249#discussion_r563605048

Require the token to be at least length 2 for the no-space behavior,
for completions of "-" like for python.
2021-02-13 08:13:31 +01:00
Johannes Altmanninger
b5df9a7137 Fix a compiler warning about comparison of different signedness 2021-02-13 08:07:20 +01:00
Fabian Homborg
a503371c57 termsize: Default to 80x24 when the terminal says 0 again
This was lost in
6bdbe732e40c2e325aa15fcf0f28ad0dedb3a551..c7160d7cb4970c2a03df34547f357721cb5e88db.

Note that we only print a term-support flog message for now, the
warning seems a bit much.

Fixes #7709.
2021-02-12 18:25:21 +01:00
Fabian Homborg
056153eddd Remove stray comment
[ci skip]
2021-02-11 18:44:53 +01:00
ridiculousfish
17d6aa054b exec_internal_builtin_proc to stop returning failure
Now that closing stdin is no longer an error for builtins, the function
exec_internal_builtin_proc cannot fail. Make it return void instead.
2021-02-10 17:43:12 -08:00
ridiculousfish
84d59accfc builtins to allow stdin to be closed
Prior to this fix, if stdin were explicitly closed, then builtins would
silently fail. For example:

    count <&-

would just fail with status 1. Remove this limitation and allow each
builtin to handle a closed stdin how it sees fit.
2021-02-10 17:43:10 -08:00
ridiculousfish
f239329f33 Attempt to fix the 32 bit fd_monitor test
Speculatively the fd_monitor thread is not scheduled, or we are awoken
early. Add a loop to ensure it gets run.

This is an attempt at #7699
2021-02-10 12:28:34 -08:00
Johannes Altmanninger
51850e9303 Output human-readable descriptions of some parse errors
"echo > )" provokes one of these.
2021-02-09 22:38:16 +01:00
Johannes Altmanninger
86707378cc Also allow unclosed quotes in some places
See #7693
2021-02-09 22:38:16 +01:00
Johannes Altmanninger
38b95defbd Inside an unclosed subshell, do not report other parse errors
In an interactive shell, typing "for x in (<RET>" would print an error:

	fish: Expected end of the statement, but found a parse_token_type_t::tokenizer_error

Our tokenizer converts "(" into a special error token, hence this message.
Fix two cases by not reporting errors, but only if we allow parsing incomplete
input. I'm not really sure if this is necessary, but it's sufficient.

Fixes #7693
2021-02-09 22:19:42 +01:00
ridiculousfish
e423a58e24 Add a thread yield to topic monitor torture test
This speeds up the test by about 5 msec.
2021-02-08 14:06:47 -08:00
ridiculousfish
4b9a096cf2 builtins to sometimes not buffer when writing to a pipe
Prior to this change, if you pipe a builtin to another process, it would
be buffered. With this fix the builtin will write directly to the pipe if
safe (that is, if the other end of the pipe is owned by some external
process that has been launched).

Most builtins do not produce a lot of output so this is somewhat tricky to
reproduce, but it can be done like so:

     bash -c 'for i in {1..500}; do echo $i ; sleep .5; done' |
	   string match --regex '[02468]' |
	   cat

Here 'string match' is filtering out numbers which contain no even digits.
With this change, the numbers are printed as they come, instead of
buffering all the output.

Note that bcfc54fdaa fixed this for the case where the
builtin outputs to stdout directly. This fix extends it to all pipelines
that include only one fish internal process.
2021-02-08 14:22:02 -08:00
ridiculousfish
171d09288b Rename allow_buffering to piped_output_needs_buffering
This makes the variable's role clear. It controls whether output to a
pipe must be buffered to avoid deadlock.
2021-02-08 14:22:02 -08: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
Mahmoud Al-Qudsi
cb3ab80cab Use const_strlen in a few different places
This may slightly improve performance by allowing the compiler greater
visibility into what is happing on top of not executing at runtime in
some hot paths, but more importantly, it gets rid of magic constants in a
few different places.
2021-02-08 15:16:21 -06:00
Mahmoud Al-Qudsi
5d4c24bae1 Refactor color.h/color.cpp
* Use `uint8_t` instead of `unsigned char`
* Statically assert the sort order for `named_colors`
* Use constexpr for array lengths
2021-02-08 15:16:21 -06:00
Mahmoud Al-Qudsi
5fda1e05dc Statically assert the sort order of input_function_metadata_t 2021-02-08 15:16:20 -06:00
Mahmoud Al-Qudsi
2df16b53ff Use thread-local vectors for caching peeked events
These functions are called in the event queue hot path every time an
input event takes place. If we could guarantee a maximum length of
non-char (i.e. readline) events in the queue, we could use
`event_queue_peeker_t` with a fixed storage size of, e.g., 32 events,
but I'm not sure what a reasonable number would in fact be, so I'm just
changing these to use a thread-local vector that will re-use its
previous heap allocation in subsequent invocations rather than thrashing
the heap.
2021-02-08 15:16:20 -06:00
Mahmoud Al-Qudsi
2c1764fd45 Convert more event queue push_front loops to insert_front 2021-02-08 15:16:20 -06:00
Mahmoud Al-Qudsi
5c014e129a Reduce input latency searching for readline function mappings
The lookups are executed on all input events, so they are worth
optimizing.

Cache the list of names, use binary search to get a function code from a
name, and stop enumerating mappings after `has_function` and `has_command`
have been determined.
2021-02-08 15:16:20 -06:00
Ethel Morgan
6dd6a57c60 Saturate return value in builtin_set_query
builtin_set_query returns the number of missing variables. Because the
return value passed to the shell is an 8-bit unsigned integer, if the
number of missing variables is a multiple of 256, it would overflow to 0.

This commit saturates the return value at 255 if there are more than 255
missing variables.
2021-02-08 20:38:56 +01:00
Johannes Altmanninger
e40850ab89 Format fish_tests.cpp 2021-02-08 07:31:33 +01:00
ridiculousfish
50a7798041 Elimiate static variables inside builtin_test
builtin_test stashes some variables in statics, to support
the `test -t` expression. However this will cause conflicts with
concurrent execution, where we may want to run two `test` expressions at
once. Do the grunt work of threading the data into all places it needs
to go.
2021-02-07 17:41:36 -08:00
ridiculousfish
40d8e7e983 Correct the sense of a test for builtin stdin fds
fish isn't quite sure what to do if the user specifies an fd redirection
for builtins. For example `source <&5` could potentially just read from
an arbitrary file descriptor internal to fish, like the history file.

fish has some lame code that tries to detect these, but got the sense
wrong. Fix it so that fd redirections for builtins are restricted to
range 0 through 2.
2021-02-07 16:21:33 -08:00
ridiculousfish
17707065b8 Remove the io_pipe_t parameter from exec_internal_builtin_proc
This parameter describes if stdin has a pipe, but that can be easily
inferred from the io_chain. Remove it in the interest of parsimony.
2021-02-07 16:03:58 -08:00
Fabian Homborg
b3626d48e7 Highlight keywords differently
This introduces a new variable $fish_color_keyword that will be used
to highlight keywords. If it's not defined, we fall back on
$fish_color_command as before.

An issue here is that most of our keywords have this weird duality of
also being builtins *if* executed without an argument or with
`--help`.

This means that e.g.

    if

is highlighted as a command until you start typing

    if t

and then it turns keyword.
2021-02-07 21:18:51 +01:00