Instead of passing CWD verbatim from the Windows host with backslashes
and all, we now rewrite it into a more POSIX-happy format featuring
forward slashes which means `std::path::Path` operations now work within
WASI with Windows-style paths.
Release Notes:
- N/A
### Background
Zed extensions use WASI to access the file-system. They only have
read-write access to one specific folder called their work dir. But
extensions do need to be able to *refer* to other arbitrary files on the
user's machine. For instance, extensions need to be able to look up
existing binaries on the user's `PATH`, and request that Zed invoke them
as language servers. Similarly, extensions can create paths to files in
the user's project, and use them as arguments in commands that Zed
should run. For these reasons, we pass *real* paths back and forth
between the host and extensions; we don't try to abstract over the
file-system with some virtualization scheme.
On Windows, this results in a bit of mismatch, because `wasi-libc` uses
*unix-like* path conventions (and thus, so does the Rust standard
library when compiling to WASI).
### Change 1 - Fixing `current_dir`
In order to keep the extension API minimal, extensions use the standard
library function`env::current_dir()` to query the location of their
"work" directory. Previously, when initializing extensions, we used the
`env::set_current_dir` function to set their work directory, but on
Windows, where absolute paths typically begin with a drive letter, like
`C:`, the [`wasi-libc` implementation of
`chdir`](d1793637d8/libc-bottom-half/sources/chdir.c (L21))
was prepending an extra forward slash to the path, which caused
`current_dir()` to return an invalid path.
See https://github.com/bytecodealliance/wasmtime/issues/10415
In this PR, I've switched our extension initialization function to
*bypass* wasi-libc's `chdir` function, and instead write directly to
wasi-libc's private, internal state. This is a bit of a hack, but it
causes the `current_dir()` function to do what we want on Windows
without any changes to extensions' source code.
### Change 2 - Working around WASI's relative path handling
Once `current_dir` was fixed (giving us correct absolute paths on
Windows), @kubkon and I discovered that without the spurious leading `/`
character, windows absolute paths were no longer accepted by Rust's
`std::fs` APIs, because they were now recognized as relative paths, and
were being appended to the working directory.
We first tried to override the `__wasilibc_find_abspath` function in
`wasi-libc` to make it recognize windows absolute paths as being
absolute, but that functionality is difficult to override. Eventually
@kubkon realized that we could prevent WASI-libc's CWD handling from
being linked into the WASM file by overriding the `chdir` function.
wasi-libc is designed so that if you don't use their `chdir` function,
then all paths will be interpreted as relative to `/`. This makes
absolute paths behave correctly. Then, in order to make *relative* paths
work again, we simply add a preopen for `.`. Relative paths will match
that.
### Next Steps
This is a change to `zed-extension-api`, so we do need to update every
Zed extension to use the new version, in order for them to work on
windows.
Release Notes:
- N/A
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
This PR adds support for capabilities for the extension process API.
In order to use the process API, an extension must declare which
commands it wants to use, with arguments:
```toml
[[capabilities]]
kind = "process:exec"
command = "echo"
args = ["hello!"]
```
A `*` can be used to denote a single wildcard in the argument list:
```toml
[[capabilities]]
kind = "process:exec"
command = "echo"
args = ["*"]
```
And `**` can be used to denote a wildcard for the remaining arguments:
```toml
[[capabilities]]
kind = "process:exec"
command = "ls"
args = ["-a", "**"]
```
Release Notes:
- N/A
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This PR forks a new version of the `zed_extension_api` in preparation
for new changes.
Release Notes:
- N/A
---------
Co-authored-by: Max <max@zed.dev>
This PR updates the `zed_extension_api` to v0.1.0 for the extensions
that live in this repo.
The changes in that version of additive, so none of the extensions need
to change their usage in order to upgrade.
Release Notes:
- N/A
This PR updates the `extension` crate's tests to use a dedicated test
extension for its tests instead of the real Gleam extension.
As the Gleam extension continues to evolve, it makes it less suitable to
use as a test fixture:
1. For a while now, the test has failed locally due to me having `gleam`
on my $PATH, which causes the extension's `get_language_server_command`
to go down a separate codepath.
2. With the addition of the `indexed_docs_providers` the test was
hanging indefinitely.
While these problems are likely solvable, it seems reasonable to have a
dedicated extension to use as a test fixture. That way we can do
whatever we need to exercise our test criteria.
The `test-extension` is a fork of the Gleam extension with some
additional functionality removed.
Release Notes:
- N/A