This PR extracts Haskell support into an extension and removes the
built-in Haskell support from Zed.
I tested out the extension locally in a Nix shell using `nix-shell -p
ghc haskell-language-server` to confirm the language server still
operated as expected:
<img width="341" alt="Screenshot 2024-03-26 at 11 26 26 AM"
src="https://github.com/zed-industries/zed/assets/1486634/df16fd38-4046-4a45-ac9f-c2b85bffe5c0">
Release Notes:
- Removed built-in support for Haskell, in favor of making it available
as an extension. The Haskell extension will be suggested for download
when you open a `.hs` file.
This pull request introduces a new `InlineCompletionProvider` trait,
which enables making `Editor` copilot-agnostic and lets us push all the
copilot functionality into the `copilot_ui` module. Long-term, I would
like to merge `copilot` and `copilot_ui`, but right now `project`
depends on `copilot`, which makes this impossible.
The reason for adding this new trait is so that we can experiment with
other inline completion providers and swap them at runtime using config
settings.
Please, note also that we renamed some of the existing copilot actions
to be more agnostic (see release notes below). We still kept the old
actions bound for backwards-compatibility, but we should probably remove
them at some later version.
Also, as a drive-by, we added new methods to the `Global` trait that let
you read or mutate a global directly, e.g.:
```rs
MyGlobal::update(cx, |global, cx| {
});
```
Release Notes:
- Renamed the `copilot::Suggest` action to
`editor::ShowInlineCompletion`
- Renamed the `copilot::NextSuggestion` action to
`editor::NextInlineCompletion`
- Renamed the `copilot::PreviousSuggestion` action to
`editor::PreviousInlineCompletion`
- Renamed the `editor::AcceptPartialCopilotSuggestion` action to
`editor::AcceptPartialInlineCompletion`
---------
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Kyle <kylek@zed.dev>
Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
This uses the language server settings added in #9293 to allow users to
specify the binary path and arguments with which to start up `gopls`.
Example user settings for `gopls`:
```json
{
"lsp": {
"gopls": {
"binary": {
"path": "/Users/thorstenball/tmp/gopls",
"arguments": ["-debug=0.0.0.0:8080"]
},
}
}
}
```
Constraints:
* Right now this only allows ABSOLUTE paths.
Release Notes:
- Added ability to specify `gopls` binary `path` (must be absolute) and
`arguments` in user settings. Example: `{"lsp": {"gopls": {"binary":
{"path": "/my/abs/path/gopls", "arguments": ["-debug=0.0.0.0:8080"]
}}}}`
There is also `.C` and `.H` (capital), but I can't imagine they are very
popular and I'd be worried clashing with C.
Release Notes:
- Added more path suffixes recognized as C++
This allows the workspace configuration settings to be passed to the
elixir-ls LSP via lsp settings.
This following example settings disable dialyzer in the LSP:
```
"lsp": {
"elixir-ls": {
"settings": {
"dialyzerEnabled": false
}
}
}
```
It follows the same pattern used in
[#8568](https://github.com/zed-industries/zed/pull/8568) and resolves
[#4260](https://github.com/zed-industries/zed/issues/4260).
Zed's language server logs show the settings are being sent to the
language server:
```
Received client configuration via workspace/configuration
%{"dialyzerEnabled" => false}
Registering for workspace/didChangeConfiguration notifications
Starting build with MIX_ENV: test MIX_TARGET: host
client/registerCapability succeeded
Registering for workspace/didChangeWatchedFiles notifications
client/registerCapability succeeded
Received workspace/didChangeConfiguration
Received client configuration via workspace/didChangeConfiguration
%{"dialyzerEnabled" => false}
```
Release Notes:
- Added workspace configuration settings support for elixir-ls language
server. Those can now be configured by setting `{"lsp": {"elixir-ls": {
"settings: { "your-settings-here": "here"} } }` in Zed settings.
[#4260](https://github.com/zed-industries/zed/issues/4260).
We're doing it. Svelte support is moving into an extension. This PR
fixes some issues that came up along the way.
Notes
* extensions need to be able to retrieve the path the `node` binary
installed by Zed
* previously we were silently swallowing any errors that occurred while
loading a grammar
* npm commands ran by extensions weren't run in the right directory
* Tree-sitter's WASM stdlib didn't support a C function (`strncmp`)
needed by the Svelte parser's external scanner
* the way that LSP installation status was reported was unnecessarily
complex
Release Notes:
- Removed built-in support for the Svelte and Gleam languages, because
full support for those languages is now available via extensions. These
extensions will be suggested for download when you open a `.svelte` or
`.gleam` file.
---------
Co-authored-by: Marshall <marshall@zed.dev>
This upgrades to vscode-eslint 2.4.4 to support flat configs, in
multiple configuration files, ending in `.js`, `.cjs`, `.mjs`.
We changed the code to not use the GitHub release because we actually
don't need the artifacts of the release, we just need the source code,
which we compile anyway.
Fixes#7271.
Release Notes:
- Added support for ESLint flat config files.
([#7271](https://github.com/zed-industries/zed/issues/7271)).
Co-authored-by: Kristján Oddsson <koddsson@gmail.com>
This PR also introduces built-in tasks for Rust and Elixir. Note that
this is not a precedent for future PRs to include tasks for more
languages; we simply want to find the rough edges with tasks & language
integrations before proceeding to task contexts provided by extensions.
As is, we'll load tasks for all loaded languages, so in order to get
Elixir tasks, you have to open an Elixir buffer first. I think it sort
of makes sense (though it's not ideal), as in the future where
extensions do provide their own tasks.json, we'd like to limit the # of
tasks surfaced to the user to make them as relevant to the project at
hand as possible.
Release Notes:
- Added built-in tasks for Rust and Elixir files.
Our goal is to extract Svelte support into an extension, since we've
seen problems with the Tree-sitter Svelte parser crashing due to bugs in
the external scanner. In order to do this, we need a couple more
capabilities in LSP extensions:
* [x] `initialization_options` - programmatically controlling the JSON
initialization params sent to the language server
* [x] `prettier_plugins` - statically specifying a list of prettier
plugins that apply for a given language.
* [x] `npm_install_package`
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This variable is experimental, as I expect it to be superseded by
whatever the extensions can provide (once we get them)
Release Notes:
- Added experimental ZED_PACKAGE task variable which contains name of
the current crate in Rust files.
---------
Co-authored-by: Kirill <kirill@zed.dev>
Closes https://github.com/zed-industries/zed/issues/9458
When flying in a plane being totally offline, I've discovered that my
Rust projects do not have any LSP support and rust-analyzer disappeared
out of `~/Library/Application Support/Zed/languages/rust-analyzer/`
directory.
Looking at the
[bad.log](https://github.com/zed-industries/zed/files/14627508/bad.log),
it appears that `get_language_server_command` tries to find a newer LSP
server version and fails on
80bc6c8cc8/crates/language/src/language.rs (L339)
bailing out of all installation related-methods up to here:
80bc6c8cc8/crates/project/src/project.rs (L2916)
where the code thinks that the binary installation process had failed,
cleans the existing directory and tries to install the language server
again:
```log
[2024-03-17T15:14:13+02:00 WARN isahc::handler] request completed with error: failed to resolve host name
[2024-03-17T15:14:13+02:00 ERROR project] failed to start language server "rust-analyzer": error fetching latest release
[2024-03-17T15:14:13+02:00 ERROR project] server stderr: Some("")
[2024-03-17T15:14:13+02:00 INFO project] retrying installation of language server "rust-analyzer" in 1s
[2024-03-17T15:14:13+02:00 ERROR util] crates/lsp/src/lsp.rs:720: oneshot canceled
[2024-03-17T15:14:14+02:00 INFO project] About to spawn test binary
[2024-03-17T15:14:14+02:00 WARN project] test binary failed to launch
[2024-03-17T15:14:14+02:00 WARN project] test binary check failed
[2024-03-17T15:14:14+02:00 INFO project] beginning to reinstall server
[2024-03-17T15:14:14+02:00 INFO language::language_registry] deleting server container
[2024-03-17T15:14:14+02:00 INFO language::language_registry] starting language server "rust-analyzer", path: "/Users/someonetoignore/work/other/local_test", id: 2
[2024-03-17T15:14:14+02:00 INFO language] fetching latest version of language server "rust-analyzer"
[2024-03-17T15:14:14+02:00 WARN isahc::handler] request completed with error: failed to resolve host name
[2024-03-17T15:14:14+02:00 ERROR project] failed to start language server "rust-analyzer": error fetching latest release
[2024-03-17T15:14:14+02:00 ERROR project] server stderr: Some("")
[2024-03-17T15:14:14+02:00 INFO project] retrying installation of language server "rust-analyzer" in 1s
[2024-03-17T15:14:15+02:00 ERROR util] crates/languages/src/rust.rs:335: no cached binary
[2024-03-17T15:14:15+02:00 INFO project] About to spawn test binary
............
```
The PR extracts away all binary fetching-related code into a single
method that does not fail the entire `get_language_server_command` and
allows it to recover and reuse the existing binary:
[good.log](https://github.com/zed-industries/zed/files/14627507/good.log)
```log
[2024-03-17T15:12:24+02:00 INFO language::language_registry] starting language server "rust-analyzer", path: "/Users/someonetoignore/work/other/local_test", id: 1
[2024-03-17T15:12:24+02:00 INFO language] fetching latest version of language server "rust-analyzer"
[2024-03-17T15:12:24+02:00 WARN isahc::handler] request completed with error: failed to resolve host name
[2024-03-17T15:12:24+02:00 INFO language] failed to fetch newest version of language server LanguageServerName("rust-analyzer"). falling back to using "/Users/someonetoignore/Library/Application Support/Zed/languages/rust-analyzer/rust-analyzer-2024-03-11"
[2024-03-17T15:12:24+02:00 INFO lsp] starting language server. binary path: "/Users/someonetoignore/Library/Application Support/Zed/languages/rust-analyzer/rust-analyzer-2024-03-11", working directory: "/Users/someonetoignore/work/other/local_test", args: []
```
Release Notes:
- Fixed language servers erased from the disk when project is opened
offline
Fixes: https://github.com/zed-industries/zed/issues/9234
This doesn't address `vue` as it has a slightly different install code,
but it should be fairly simple to add - I'll add it in in a follow-up.
This PR will allow all (except `vue`) node-based language servers to
update. It is mostly just throwing in a method into the `NodeRuntime`
trait that is used for checking if a package doesn't exist locally, or
is out of date, by checking the version against what's newest, and
installing. If any parsing of the `package.json` data fails along the
way, it assumes something has gone awry on the users system, logs the
error, and then proceeds with trying to install the package, so that
users don't get stuck on version if their package has some bad data.
Outside of adding this method, it just adds that check in all of the
language server's individual `fetch_server_binary` methods.
Release Notes:
- Added updating for node-based language servers
([#9234](https://github.com/zed-industries/zed/issues/9234)).
This fixes#9292 by adding a section to the language server settings
that allows users to specify the binary path and arguments with which to
start up a language server.
Example user settings for `rust-analyzer`:
```json
{
"lsp": {
"rust-analyzer": {
"binary": {
"path": "/Users/thorstenball/tmp/rust-analyzer-aarch64-apple-darwin",
"arguments": ["--no-log-buffering"]
}
}
}
}
```
Constraints:
* Right now this only allows ABSOLUTE paths.
* This is only used by `rust-analyzer` integration right now, but the
setting can be used for other language servers. We just need to update
the adapters to also respect that setting.
Release Notes:
- Added ability to specify `rust-analyzer` binary `path` (must be
absolute) and `arguments` in user settings. Example: `{"lsp":
{"rust-analyzer": {"binary": {"path": "/my/abs/path/rust-analyzer",
"arguments": ["--no-log-buffering"] }}}}`
([#9292](https://github.com/zed-industries/zed/issues/9292)).
Co-authored-by: Ricard Mallafre <rikitzzz@gmail.com>
This fixes#9213 by pinning ESLint to `2.2.20-Insiders` which is the
last known version to work well with Zed.
Once this fix is out, we can take a closer look at upgrading to 2.4.x or
even 3.x once that's out of prerelease.
Release Notes:
- Fixed ESLint integration being broken after Mar 7 2024 due to ESLint
3.0.1 alpha release being pushed.
([#9213](https://github.com/zed-industries/zed/issues/9213)).
This fixes https://github.com/zed-industries/zed/issues/9069 by
1. reverting https://github.com/zed-industries/zed/issues/7819
2. fixing completion filtering with regards to word boudaries
For (2) see explanation in commit message:
> Previously, this would only split words on upper-lower boundaries or
> on `_`/`-`.
>
> The result was that we would filter out completions too aggressively.
> The filter works by taking a suggested completion, say `foo_bar_lol`,
split
> it up into words - `foo`, `bar, `lol` - and check whether any of the
words
> start with the same characters as what the user already typed: `fo`,
or `bar`,
> ...
>
> In the case of Ruby, though, `:` wasn't considered a word boundary. If
the
> LSP would return `:foobar` when the user typed `:foo`, we'd check if
there are
> any completions that match `foo` (because that's the current word) but
> we'd compare against `foobar`, not `:` or `:foobar`.
>
> With this change, we get more match candidates and thus more
completions in Ruby.
With that we can do (1) because we don't need these characters as word
characters anymore to trigger completions.
Release Notes:
- Fixed word boundaries in Ruby by restoring old behavior (`@`, `:`, ...
are no longer considered word characters)
([#9069](https://github.com/zed-industries/zed/issues/9069))
- Fixed completions being filtered out when they happened at word
boundaries on special characters (e.g. `:`)
---------
Co-authored-by: Max <max@zed.dev>
See https://zed.dev/channel/gpui-536
Fixes https://github.com/zed-industries/zed/issues/9010
Fixes https://github.com/zed-industries/zed/issues/8883
Fixes https://github.com/zed-industries/zed/issues/8640
Fixes https://github.com/zed-industries/zed/issues/8598
Fixes https://github.com/zed-industries/zed/issues/8579
Fixes https://github.com/zed-industries/zed/issues/8363
Fixes https://github.com/zed-industries/zed/issues/8207
### Problem
After transitioning Zed to GPUI 2, we started noticing that interacting
with the mouse on many UI elements would lead to a pretty annoying
flicker. The main issue with the old approach was that hover state was
calculated based on the previous frame. That is, when computing whether
a given element was hovered in the current frame, we would use
information about the same element in the previous frame.
However, inspecting the previous frame tells us very little about what
should be hovered in the current frame, as elements in the current frame
may have changed significantly.
### Solution
This pull request's main contribution is the introduction of a new
`after_layout` phase when redrawing the window. The key idea is that
we'll give every element a chance to register a hitbox (see
`ElementContext::insert_hitbox`) before painting anything. Then, during
the `paint` phase, elements can determine whether they're the topmost
and draw their hover state accordingly.
We are also removing the ability to give an arbitrary z-index to
elements. Instead, we will follow the much simpler painter's algorithm.
That is, an element that gets painted after will be drawn on top of an
element that got painted earlier. Elements can still escape their
current "stacking context" by using the new `ElementContext::defer_draw`
method (see `Overlay` for an example). Elements drawn using this method
will still be logically considered as being children of their original
parent (for keybinding, focus and cache invalidation purposes) but their
layout and paint passes will be deferred until the currently-drawn
element is done.
With these changes we also reworked geometry batching within the
`Scene`. The new approach uses an AABB tree to determine geometry
occlusion, which allows the GPU to render non-overlapping geometry in
parallel.
### Performance
Performance is slightly better than on `main` even though this new
approach is more correct and we're maintaining an extra data structure
(the AABB tree).
![before_after](https://github.com/zed-industries/zed/assets/482957/c8120b07-1dbd-4776-834a-d040e569a71e)
Release Notes:
- Fixed a bug that was causing popovers to flicker.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Thorsten <thorsten@zed.dev>
I'm using Yarn Plug'n'Play.
In this case, by default, eslint cannot find the path, so configuration
like `"eslint.nodePath": ".yarn/sdks"` is required.
So, I want to add this!
Release Notes:
- Added eslint config nodePath
In this PR, we've added two new methods that LSP extensions can call:
* `shell_env()`, for retrieving the environment variables set in the
user's default shell in the worktree
* `which(command)`, for looking up paths to an executable (accounting
for the user's shell env in the worktree)
To test this out, we moved the `uiua` language support into an
extension. We went ahead and removed the built-in support, since this
language is extremely obscure. Sorry @mikayla-maki. To continue coding
in Uiua in Zed, for now you can `Add Dev Extension` from the extensions
pane, and select the `extensions/uiua` directory in the Zed repo. Very
soon, we'll support publishing these extensions so that you'll be able
to just install it normally.
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
This PR moves the Clippy configuration up to the workspace level.
We're using the [`lints`
table](https://doc.rust-lang.org/cargo/reference/workspaces.html#the-lints-table)
to configure the Clippy ruleset in the workspace's `Cargo.toml`.
Each crate in the workspace now has the following in their own
`Cargo.toml` to inherit the lints from the workspace:
```toml
[lints]
workspace = true
```
This allows for configuring rust-analyzer to show Clippy lints in the
editor by using the following configuration in your Zed `settings.json`:
```json
{
"lsp": {
"rust-analyzer": {
"initialization_options": {
"check": {
"command": "clippy"
}
}
}
}
```
Release Notes:
- N/A
This PR supplements tasks with additional environment variables; ideally
we'll be able to write a task like:
`cargo test -p $ZED_CURRENT_PACKAGE -- $ZED_CURRENT_FUNCTION`
- [x] Flesh out multibuffer interactions
- [x] Add ZED_SYMBOL detection based on tree-sitter queries
- [ ] Add release note and demo
- [x] Figure out a solution for rerun dilemma - should `task: rerun`
reevaluate contexts for tasks?
This PR introduced the following variables:
- ZED_COLUMN - current line column
- ZED_ROW - current line row
and the following, which are available for buffers with associated
files:
- ZED_WORKTREE_ROOT - absolute path to the root of the current worktree.
- ZED_FILE - absolute path to the file
- ZED_SYMBOL - currently selected symbol; should match the last symbol
shown in a symbol breadcrumb (e.g. `mod tests > fn test_task_contexts`
should be equal to ZED_SYMBOL of `test_task_contexts`). Note that this
isn't necessarily a test function or a function at all.
Also, you can use them in `cwd` field of definitions (note though that
we're using https://docs.rs/subst/latest/subst/#features for that, so
don't expect a full shell functionality to work); the syntax should
match up with your typical Unix shell.
Release Notes:
- Added task contexts, which are additional environment variables set by
Zed for task execution; task content is dependent on the state of the
editor at the time the task is spawned.
---------
Co-authored-by: Anthony <anthonyeid7@protonmail.com>
This PR adds **internal** ability to run arbitrary language servers via
WebAssembly extensions. The functionality isn't exposed yet - we're just
landing this in this early state because there have been a lot of
changes to the `LspAdapter` trait, and other language server logic.
## Next steps
* Currently, wasm extensions can only define how to *install* and run a
language server, they can't yet implement the other LSP adapter methods,
such as formatting completion labels and workspace symbols.
* We don't have an automatic way to install or develop these types of
extensions
* We don't have a way to package these types of extensions in our
extensions repo, to make them available via our extensions API.
* The Rust extension API crate, `zed-extension-api` has not yet been
published to crates.io, because we still consider the API a work in
progress.
Release Notes:
- N/A
---------
Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This practice makes it difficult to locate todo!s in my code when I'm
working. Let's take out the bang if we want to keep doing this.
Release Notes:
- N/A
Follow-up to and fix for #8537.
Turns out that if you set `rules: []` it doesn't mean "no matchers", but
it means "no rules". So let's not set a default here.
Release Notes:
- N/A, see #8537
Co-authored-by: Conrad <conrad@zed.dev>
This fixes#8533 by allowing users to specify the settings that are
passed to ESLint on workspace initialization.
Example Zed `settings.json` to enable `fixAll` for eslint when
saving/formatting, but only for the `import/order` rule:
```json
{
"languages": {
"JavaScript": {
"code_actions_on_format": {
"source.fixAll.eslint": true
}
}
},
"lsp": {
"eslint": {
"settings": {
"codeActionOnSave": {
"rules": ["import/order"]
}
}
},
}
}
```
The possible settings are described in the README of `vscode-eslint`
here:
https://github.com/Microsoft/vscode-eslint?tab=readme-ov-file#settings-options
- `eslint.codeActionsOnSave.enable` (default: `true`, config key in Zed:
`lsp.eslint.settings.codeActionOnSave.enable`)
- `eslint.codeActionsOnSave.mode` (default: not set by Zed, config key
in Zed: `lsp.eslint.settings.codeActionOnSave.mode`)
- `eslint.codeActionsOnSave.rules` (default: `[]`, config key in Zed:
`lsp.eslint.settings.codeActionOnSave.rules`)
Yes, in the readme it's plural: `codeActionsOnSave`, but since
`eslint-vscode` we're using this old release:
https://github.com/microsoft/vscode-eslint/releases/tag/release%2F2.2.20-Insider
We use the singular version:
https://github.com/microsoft/vscode-eslint/blob/release/2.2.20-Insider/server/src/eslintServer.ts#L461
Our schema looks like this:
```json
{
"lsp": {
"eslint": {
"settings": {
"codeActionOnSave": {
"enable": true,
"rules": ["import/order"],
"mode": "all"
}
}
},
}
}
```
We should probably fix this and upgrade to the newest version of ESLint.
Release Notes:
- Added ability for users to configure settings for ESLint's
`codeActionOnSave`, e.g. specifying `rules` that should be respected
when also using `"code_actions_on_format": {"source.fixAll.eslint":
true}`. These settings can be passed to ESLint as part of the `"lsp"`
part of the Zed settings. Example: `{"lsp": {"eslint": {"settings":
{"codeActionOnSave": { "rules": ["import/order"] }}}}}`
([#8533](https://github.com/zed-industries/zed/issues/8533)).
Demo:
https://github.com/zed-industries/zed/assets/1185253/5c0cf900-9acb-4a70-b89d-49b6eeb6f0e4
This PR does two things to fix
https://github.com/zed-industries/zed/issues/4325:
1. It changes the way `code_actions_on_format` works to send the
possibly configured code actions to _all_ (and not just the primary)
languages servers. That means configured code actions can now be sent to
ESLint, tailwind, ... and other language servers.
2. It enables `codeActionsOnSave` by default for ESLint. That does
**not** mean that by default we will run something on save, but only
that we enable it for ESLint.
Users can then configure their Zed to run the `eslint` code action on
format. Example, for JavaScript:
```json
{
"languages": {
"JavaScript": {
"code_actions_on_format": {
"source.fixAll.eslint": true
}
},
}
}
```
Release Notes:
- Added ability to run ESLint fixes when formatting a buffer. Code
actions configured in
[`code_actions_on_format`](https://zed.dev/docs/configuring-zed#code-actions-on-format)
are now being sent to _all_ language servers connected to a buffer, not
just the primary one. So if a user now sets `"code_actions_on_format": {
"source.fixAll.eslint": true }` in their Zed settings, the
`source.fixAll.eslint` code action will be sent to ESLint, which is not
a primary language server. Since the formatter (prettier, or external
commands, or another language server, ...) still runs, it's important
that these code actions and the formatter don't clash.
([#4325](https://github.com/zed-industries/zed/issues/4325)).
Demo:
https://github.com/zed-industries/zed/assets/1185253/9ef03ad5-1f5c-4d46-b72a-eef611e32f39