Compare commits

..

466 Commits

Author SHA1 Message Date
Antonio Scandurra
bfa12d92ef Remove assistant_tooling crate
Co-Authored-By: Nathan <nathan@zed.dev>
2024-07-27 15:20:39 +02:00
Antonio Scandurra
f6b8fad275 Remove tool calling from protobuf
Co-Authored-By: Nathan <nathan@zed.dev>
2024-07-27 15:19:39 +02:00
Antonio Scandurra
14b26034d8 Add debugging info when a symbol is not found
Co-Authored-By: Nathan <nathan@zed.dev>
2024-07-27 15:03:09 +02:00
Antonio Scandurra
70e895a8c7 Fix regression that caused Anthropic custom models to error (#15329)
/cc: @bennetbo 

Release Notes:

- N/A

Co-authored-by: Nathan <nathan@zed.dev>
2024-07-27 14:45:18 +02:00
Matin Aniss
4bd935b409 gpui: Add support for animated images (#13809)
This PR adds support for animated images. The image requires a id for it
to actually animate across frames.

Currently it only has support for `GIF`, I tried adding decoding a
animated `WebP` into frames but it seems to error. This issue in the
image crate seems to document this
https://github.com/image-rs/image/issues/2263.

Not sure if this is the best way or the desired way for animated images
to work in GPUI but I would really like support for animated images.
Open to feedback.

Example Video:


https://github.com/zed-industries/zed/assets/76515905/011f790f-d070-499b-96c9-bbff141fb002



Closes https://github.com/zed-industries/zed/issues/9993

Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Nathan <nathan@zed.dev>
2024-07-27 14:05:37 +02:00
Marshall Bowers
c0df1e1846 Run clippy for Windows (#15318)
This PR fixes running clippy on Windows, as it broke in #13223.

We can't run shell scripts on Windows, so we need to use something else.

Release Notes:

- N/A
2024-07-26 21:38:34 -04:00
rimuy
e9d0768e3c Suppress unused parameter warning on remote/ssh_session.rs (#15315)
This was probably an oversight from
https://github.com/zed-industries/zed/pull/15129.


![image](https://github.com/user-attachments/assets/5867e307-f581-4b40-8492-2fb80e87c18c)

Release Notes:

- N/A
2024-07-26 21:11:28 -04:00
Marshall Bowers
380a99038b live_kit_server: Re-remove protocol submodule (#15317)
This PR re-removes the `protocol` submodule from `live_kit_server`,
since it was incorrectly added back in #15313.

Release Notes:

- N/A
2024-07-26 21:10:56 -04:00
apricotbucket28
88653c4e3e linux: Respect window_min_size property (#15314)
https://github.com/zed-industries/zed/pull/13126 added the
`window_min_size` property for window creation, but it was only
implemented for macOS. This PR implements the property on Linux as well.

Release Notes:

- N/A
2024-07-26 18:02:31 -07:00
Calin Martinconi
3751f67730 fix: Typos (#15313)
Fixed typos in the code base according with output from `codespell`
tool.

Release Notes:

- N/A
2024-07-26 17:52:37 -07:00
张小白
6af385c09e windows: Fix some weird IME window panic (#15286)
Previously, we used messages greater than `WM_USER` to pass information
between `WindowsPlatform` and `WindowsWindow`. For example, to close a
window, we handled it as follows:
1. The window sends a message with `WM_USER + 2` to `WindowsPlatform`.
2. `WindowsPlatform`, upon receiving this message, casts the `lparam` to
`HWND` and closes the window.

According to Microsoft's documentation, it is safe to use values between
`WM_USER` and `0xBFFF` as messages. However, certain versions of
Microsoft's IME use `WM_USER + 2` for UNKNOWN purposes. This causes step
2 to be erroneously triggered. The IME window's `lparam` value could be
arbitrary, leading to an attempt to close an arbitrary `HWND` and
resulting in errors.

It is quite surprising that Microsoft indicates using `WM_USER + 2` is
safe, yet Microsoft itself breaks this convention. I mean, well done
Microsoft!

This PR addresses the issue by using the `wparam` with a specific random
value for validation purpose when sending the aforementioned message.
Before `WindowsPlatform` attempts to close the window, it will first
verify the `wparam` value.

Special thanks to @shenjackyuanjie for helping me on this.


Co-authored-by: shenjackyuanjie <3695888@qq.com>


Release Notes:

- Fixed weird panic when IME window is closing(#15185, #12563).

---------

Co-authored-by: shenjack <3695888@qq.com>
2024-07-26 17:40:55 -07:00
张小白
e6cd1cf22b windows: Remove Send and Sync implementation of DirectWrite (#15263)
This PR uses the `AgileReference` provided by the `windows-rs` crate to
correctly implement `Send` and `Sync` for `DirectWrite`.

Release Notes:

- N/A
2024-07-26 16:46:06 -07:00
Mikayla Maki
a1bd7a1297 Feature/fallback fonts (#15306)
Supersedes https://github.com/zed-industries/zed/pull/12090

fixes #5180
fixes #5055

See original PR for an example of the feature at work.

This PR changes the settings interface to be backwards compatible, and
adds the `ui_font_fallbacks`, `buffer_font_fallbacks`, and
`terminal.font_fallbacks` settings.

Release Notes:

- Added support for font fallbacks via three new settings:
`ui_font_fallbacks`, `buffer_font_fallbacks`, and
`terminal.font_fallbacks`.(#5180, #5055).

---------

Co-authored-by: Junkui Zhang <364772080@qq.com>
2024-07-26 16:42:21 -07:00
Conrad Irwin
3e31955b7f SSH remote ui (#15129)
Still TODO:
* [x] hide this UI unless you have some ssh projects in settings
* [x] add the "open folder" flow with the new open picker
* [ ] integrate with recent projects / workspace restoration

Release Notes:

- N/A
2024-07-26 16:45:44 -06:00
Conrad Irwin
be86852f95 Allow binding to motions in insert mode (#15308)
Release Notes:

- vim: Allow binding motions in insert mode
2024-07-26 16:33:31 -06:00
Marshall Bowers
bde02a350e settings_ui: Add line number settings controls (#15310)
This PR adds settings controls for the line numbers and relative line
numbers settings.

Release Notes:

- N/A
2024-07-26 18:31:45 -04:00
renovate[bot]
4c9311ba40 Update Rust crate palette to v0.7.6 (#15307)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [palette](https://togithub.com/Ogeon/palette) | workspace.dependencies
| patch | `0.7.5` -> `0.7.6` |

---

### Release Notes

<details>
<summary>Ogeon/palette (palette)</summary>

###
[`v0.7.6`](https://togithub.com/Ogeon/palette/blob/HEAD/CHANGELOG.md#Version-076---2024-04-28)

[Compare
Source](https://togithub.com/Ogeon/palette/compare/0.7.5...0.7.6)

- \[[#&#8203;390](https://togithub.com/Ogeon/palette/issues/390)]\[390]:
Add `From` implementations for changing `Rgb` component types between
`u8`, `f32` and `f64`.
- \[[#&#8203;342](https://togithub.com/Ogeon/palette/issues/342)]\[342]:
Implement CAM16. Closes
\[[#&#8203;199](https://togithub.com/Ogeon/palette/issues/199)]\[199].
- \[[#&#8203;386](https://togithub.com/Ogeon/palette/issues/386)]\[386]:
Fix angle conversion from `f32` to `u8`. Closes
\[[#&#8203;385](https://togithub.com/Ogeon/palette/issues/385)]\[385].
- \[[#&#8203;384](https://togithub.com/Ogeon/palette/issues/384)]\[384]:
Add traits for color schemes from traditional color theory.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 18:20:59 -04:00
Conrad Irwin
c8bc49fa18 vim: Fix count in visual indent (#15296)
Co-Authored-By: tobbe@tlundberg.com

Release Notes:

- vim: Added {count} for `>`/`<` in visual mode
2024-07-26 16:03:41 -06:00
Marshall Bowers
bcd972fbb4 Upgrade dashmap to v6 (#15305)
This PR upgrades `dashmap` to v6.0.1.

Release Notes:

- N/A
2024-07-26 17:58:37 -04:00
Marshall Bowers
e423f03ba6 Upgrade base64 to v0.22 (#15304)
This PR upgrades the `base64` dependency to v0.22.

Supersedes #15300.

Release Notes:

- N/A
2024-07-26 17:40:38 -04:00
Marshall Bowers
03ebbcbef6 live_kit_server: Replace jwt with jsonwebtoken (#15302)
This PR replaces `live_kit_server`'s usage of `jwt` with `jsonwebtoken`.

`jwt` hasn't been updated in 2 years and seems unmaintained.

`jsonwebtoken` has significantly more downloads and appears to be a
healthier crate overall.

Release Notes:

- N/A
2024-07-26 17:20:01 -04:00
Marshall Bowers
27f97ba762 settings_ui: Add font ligature settings controls (#15301)
This PR adds settings controls for changing whether ligatures are
enabled for the UI and buffer fonts.

Release Notes:

- N/A
2024-07-26 17:06:14 -04:00
Vitaly Slobodin
769ae8b101 ruby: Adjust language servers languages (#15297)
Hi. This is a small pull request that changes the "language" field to
the "languages" field
because the `language` field is deprecated.
Additionally, allow the Ruby LSP to run in `*.erb` files.

Release Notes:

- N/A
2024-07-26 15:58:50 -04:00
renovate[bot]
d27fef7b2c Update Python to v3.12.4 (#15136)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [python](https://togithub.com/containerbase/python-prebuild) |
dependencies | patch | `3.12.1` -> `3.12.4` |

---

### Release Notes

<details>
<summary>containerbase/python-prebuild (python)</summary>

###
[`v3.12.4`](https://togithub.com/containerbase/python-prebuild/releases/tag/3.12.4)

[Compare
Source](https://togithub.com/containerbase/python-prebuild/compare/3.12.3...3.12.4)

##### Bug Fixes

-   **deps:** update dependency python to v3.12.4

###
[`v3.12.3`](https://togithub.com/containerbase/python-prebuild/releases/tag/3.12.3)

[Compare
Source](https://togithub.com/containerbase/python-prebuild/compare/3.12.2...3.12.3)

##### Bug Fixes

-   **deps:** update dependency python to v3.12.3

###
[`v3.12.2`](https://togithub.com/containerbase/python-prebuild/releases/tag/3.12.2)

[Compare
Source](https://togithub.com/containerbase/python-prebuild/compare/3.12.1...3.12.2)

##### Bug Fixes

-   **deps:** update dependency python to v3.12.2

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 15:27:46 -04:00
renovate[bot]
f4bbbe69b4 Update Rust crate waker-fn to v1.2.0 (#15289)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [waker-fn](https://togithub.com/smol-rs/waker-fn) | dependencies |
minor | `1.1.0` -> `1.2.0` |

---

### Release Notes

<details>
<summary>smol-rs/waker-fn (waker-fn)</summary>

###
[`v1.2.0`](https://togithub.com/smol-rs/waker-fn/blob/HEAD/CHANGELOG.md#Version-120)

[Compare
Source](https://togithub.com/smol-rs/waker-fn/compare/v1.1.1...v1.2.0)

-   Add a new `portable-atomic` feature that allows for the usage of the
`portable-atomic` crate to implement `waker-fn`.
([#&#8203;10](https://togithub.com/smol-rs/waker-fn/issues/10))

###
[`v1.1.1`](https://togithub.com/smol-rs/waker-fn/blob/HEAD/CHANGELOG.md#Version-111)

[Compare
Source](https://togithub.com/smol-rs/waker-fn/compare/v1.1.0...v1.1.1)

- Reimplement using 100% safe code.
([#&#8203;7](https://togithub.com/smol-rs/waker-fn/issues/7))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-26 13:05:29 -04:00
Marshall Bowers
c937a2fcdd ui: Add functions for generating textual representations of key bindings (#15287)
This PR adds some helper functions in the `ui` crate that can be used to
get textural representations of keystrokes or key bindings.

Release Notes:

- N/A
2024-07-26 12:52:59 -04:00
Nate Butler
a5279cc48a Tool bar: Remove tool grouping for clarity (#15285)
This PR makes the spacing between items in the tool bar (quick action
bar) consistent vs grouped by type. The idea was to add clarity to the
types of tools, but we haven't built this system out enough for these
groupings to be recognizable. So for now, let's make the spacing
consistent.

Before:
![CleanShot 2024-07-26 at 11 58
22@2x](https://github.com/user-attachments/assets/9135fcce-fcf8-4bdf-a71b-6d6c7e5b3f63)


After:

![CleanShot 2024-07-26 at 11 57
02@2x](https://github.com/user-attachments/assets/0aceb981-01b6-466f-8d7e-97b564d014f9)

Release Notes:

- N/A
2024-07-26 12:36:49 -04:00
CharlesChen0823
4d56252bae linux: Allow skipping "Unsupported GPU" warning (#15271)
I just want using Zed in virtual machine, current implement must read
code and set env `ZED_ALLOW_EMULATED_GPU` then can work.

Release Notes:

- N/A
2024-07-26 10:26:14 -06:00
Thorsten Ball
0360cda543 tasks: Use environment variables from project (#15266)
This fixes #12125 and addresses what's described in here:

-
https://github.com/zed-industries/zed/issues/4977#issuecomment-2162094388

Before the changes in this PR, when running tasks, they inherited the
Zed process environment, but that might not be the process environment
that you'd get if you `cd` into a project directory.

We already ran into that problem with language servers and we fixed it
by loading the shell environment in the context of a projects root
directory and then passing that to the language servers when starting
them (or when looking for their binaries).

What the change here does is to add the behavior for tasks too: we use
the project-environment as the base environment with which to spawn
tasks. Everything else still works the same, except that the base env is
different.

Release Notes:

- Improved the environment-variable detection when running tasks so that
tasks can now access environment variables as if the task had been
spawned in a terminal that `cd`ed into a project directory. That means
environment variables set by `direnv`/`asdf`/`mise` and other tools are
now picked up.
([#12125](https://github.com/zed-industries/zed/issues/12125)).

Demo:


https://github.com/user-attachments/assets/8bfcc98f-0f9b-4439-b0d9-298aef1a3efe
2024-07-26 18:19:53 +02:00
Danilo Leal
5e04753d1c Add note about used context in the model selector (#15235)
When pressing <kbd>control</kbd> + <kbd>enter</kbd>, the AI-powered
inline transformation input displays an icon button and a token count,
which should show roughly the same numbers you'd see on your assistant
panel. At a first glance, though, the token count not being zero can be
confusing, where you'd wonder where that's coming from. That's because
the inline input uses whatever piece of context and/or information of
the currently selected assistant tab to suggest more accurate edits.

So, this PR introduces an informative piece of text to the
`ModelSelector` menu, on the inline transformation input, which delivers
exactly this bit of info, aimed at clarifying the connection between
these two methods of interacting with LLMs.

I've also took the opportunity to change the icon button's icon to one
that's a bit easier to see, still representing the affordance of "click
to configure something".

Release Notes:

- Add note about how inline edits consume context from the assistant
panel to clarify interaction with LLMs.

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-26 12:48:06 -03:00
renovate[bot]
71312e5692 Update Rust crate log to v0.4.22 (#15283)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [log](https://togithub.com/rust-lang/log) | workspace.dependencies |
patch | `0.4.21` -> `0.4.22` |

---

### Release Notes

<details>
<summary>rust-lang/log (log)</summary>

###
[`v0.4.22`](https://togithub.com/rust-lang/log/blob/HEAD/CHANGELOG.md#0422---2024-06-27)

[Compare
Source](https://togithub.com/rust-lang/log/compare/0.4.21...0.4.22)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 11:27:00 -04:00
Nate Butler
05825e9804 Add Markdown Preview Toggle (#15215)
Add a "Preview Markdown" button to the quick action bar when in a
markdown editor.

While it isn't my favorite, I went with the basic eye icon to be a bit
more generic so we can extend this control to allow opening other
previews such as SVGs like @jansol mentioned.

![CleanShot 2024-07-26 at 11 02
16@2x](https://github.com/user-attachments/assets/415963ce-d19e-432d-b8c2-37e7c6e52683)


https://github.com/user-attachments/assets/5980272c-eab9-4f69-86b6-0c593c25b525

---

Release Notes:

- Added a button to preview Markdown files in the toolbar.
`Option|Alt+Click` will open the preview to the side.
2024-07-26 11:08:42 -04:00
renovate[bot]
73d682c010 Update Rust crate oo7 to v0.3.3 (#15281)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [oo7](https://togithub.com/bilelmoussaoui/oo7) | dependencies | patch
| `0.3.0` -> `0.3.3` |

---

### Release Notes

<details>
<summary>bilelmoussaoui/oo7 (oo7)</summary>

###
[`v0.3.3`](https://togithub.com/bilelmoussaoui/oo7/releases/tag/0.3.3)

[Compare
Source](https://togithub.com/bilelmoussaoui/oo7/compare/0.3.2...0.3.3)

Bilal Elmoussaoui:

-   client/item: Force tuple usage when serializing
-   client: Use async UnixStream

###
[`v0.3.2`](https://togithub.com/bilelmoussaoui/oo7/releases/tag/0.3.2)

[Compare
Source](https://togithub.com/bilelmoussaoui/oo7/compare/0.3.1...0.3.2)

Kévin Commaille:

- [client: Fix compile issue with tracing
feature](8720514d56)
- [client: Do not create features for optional deps already behind a
feature](c4cad3dbd4)
-   Various clippy fixes

###
[`v0.3.1`](https://togithub.com/bilelmoussaoui/oo7/releases/tag/0.3.1)

[Compare
Source](https://togithub.com/bilelmoussaoui/oo7/compare/0.3.0...0.3.1)

Daiki Ueno:

- [portal: Support migration from legacy keyring
format](0e4d787372)

Dhanuka Warusadura:

- [portal: Add rekeying support for
oo7::portal::Keyring](96dd3c4292)

Felix Häcker:

- [service: Use correct signal name for
CollectionDeleted](19499a6499)
- [service: Add signals for collection
create/delete/change](c4e68b8e76)
- [collection: Add path to public
api](7effc007d4)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 11:08:17 -04:00
Antonio Scandurra
e59e47fe7f Revert "Avoid buffering line content to compute indent guides" (#15282)
Reverts zed-industries/zed#15167

Release Notes:

- N/A
2024-07-26 11:05:24 -04:00
Marshall Bowers
4abf7f058e Upgrade env_logger to v0.11 (#15278)
This PR upgrades `env_logger` to v0.11.

There were some breaking changes in the style API. I followed the
[migration
guide](73bb418802/CHANGELOG.md (migration-guide))
to update the usage.

Visually there shouldn't be any changes:

### Before

<img width="1068" alt="Screenshot 2024-07-26 at 10 20 07 AM"
src="https://github.com/user-attachments/assets/9abdbba2-5a34-46df-a62b-3d6c2d9d1137">

### After

<img width="1061" alt="Screenshot 2024-07-26 at 10 37 35 AM"
src="https://github.com/user-attachments/assets/c81bc3cc-1738-43f7-ba19-4c4be058427f">

Release Notes:

- N/A
2024-07-26 10:48:07 -04:00
renovate[bot]
f980e40993 Update Rust crate semver to v1.0.23 (#15277)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [semver](https://togithub.com/dtolnay/semver) | workspace.dependencies
| patch | `1.0.18` -> `1.0.23` |

---

### Release Notes

<details>
<summary>dtolnay/semver (semver)</summary>

### [`v1.0.23`](https://togithub.com/dtolnay/semver/releases/tag/1.0.23)

[Compare
Source](https://togithub.com/dtolnay/semver/compare/1.0.22...1.0.23)

- Resolve unexpected_cfgs warning
([#&#8203;318](https://togithub.com/dtolnay/semver/issues/318))

### [`v1.0.22`](https://togithub.com/dtolnay/semver/releases/tag/1.0.22)

[Compare
Source](https://togithub.com/dtolnay/semver/compare/1.0.21...1.0.22)

-   Fix unused_imports warnings when compiled by rustc 1.78

### [`v1.0.21`](https://togithub.com/dtolnay/semver/releases/tag/1.0.21)

[Compare
Source](https://togithub.com/dtolnay/semver/compare/1.0.20...1.0.21)

- Update proc-macro2 to fix caching issue when using a rustc-wrapper
such as sccache

### [`v1.0.20`](https://togithub.com/dtolnay/semver/releases/tag/1.0.20)

[Compare
Source](https://togithub.com/dtolnay/semver/compare/1.0.19...1.0.20)

- Add a method for comparing versions by precedence
([#&#8203;305](https://togithub.com/dtolnay/semver/issues/305))

### [`v1.0.19`](https://togithub.com/dtolnay/semver/releases/tag/1.0.19)

[Compare
Source](https://togithub.com/dtolnay/semver/compare/1.0.18...1.0.19)

- Improve test coverage
([#&#8203;299](https://togithub.com/dtolnay/semver/issues/299), thanks
[@&#8203;CXWorks](https://togithub.com/CXWorks))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 10:36:41 -04:00
renovate[bot]
57b2cb6f60 Update Rust crate backtrace to v0.3.73 (#15275)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [backtrace](https://togithub.com/rust-lang/backtrace-rs) |
dependencies | patch | `0.3.69` -> `0.3.73` |
| [backtrace](https://togithub.com/rust-lang/backtrace-rs) |
dev-dependencies | patch | `0.3.69` -> `0.3.73` |

---

### Release Notes

<details>
<summary>rust-lang/backtrace-rs (backtrace)</summary>

###
[`v0.3.73`](https://togithub.com/rust-lang/backtrace-rs/releases/tag/0.3.73)

[Compare
Source](https://togithub.com/rust-lang/backtrace-rs/compare/0.3.72...0.3.73)

This basically just is bugfixes so that backtrace works on Windows 7
again.

#### What's Changed

- Fix signature of resolve_legacy for Windows 7 target by
[@&#8203;aapanfilovv](https://togithub.com/aapanfilovv) in
[https://github.com/rust-lang/backtrace-rs/pull/631](https://togithub.com/rust-lang/backtrace-rs/pull/631)
- Update some comments by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/630](https://togithub.com/rust-lang/backtrace-rs/pull/630)
- Update object to 0.36.0. by
[@&#8203;afranchuk](https://togithub.com/afranchuk) in
[https://github.com/rust-lang/backtrace-rs/pull/633](https://togithub.com/rust-lang/backtrace-rs/pull/633)

#### New Contributors

- [@&#8203;aapanfilovv](https://togithub.com/aapanfilovv) made their
first contribution in
[https://github.com/rust-lang/backtrace-rs/pull/631](https://togithub.com/rust-lang/backtrace-rs/pull/631)
- [@&#8203;afranchuk](https://togithub.com/afranchuk) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/633](https://togithub.com/rust-lang/backtrace-rs/pull/633)

**Full Changelog**:
https://github.com/rust-lang/backtrace-rs/compare/0.3.72...0.3.73

###
[`v0.3.72`](https://togithub.com/rust-lang/backtrace-rs/releases/tag/0.3.72)

[Compare
Source](https://togithub.com/rust-lang/backtrace-rs/compare/0.3.71...0.3.72)

This release removes a lot of dead code. Some feature flags that haven't
done anything in a long time are gone. If you depend on those features,
Cargo's resolver will not update you to 0.3.72.

If your code runs on Windows, or you want it to run on visionOS,
however, you should probably update to this version. It contains a
number of fixes for both OS. It also uses the latest version of a number
of dependencies.

#### What's Changed

- Revert "Use rustc from stage0 instead of stage0-sysroot (rust-lang/ba…
by [@&#8203;Nilstrieb](https://togithub.com/Nilstrieb) in
[https://github.com/rust-lang/backtrace-rs/pull/603](https://togithub.com/rust-lang/backtrace-rs/pull/603)
- Remove dead code by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/605](https://togithub.com/rust-lang/backtrace-rs/pull/605)
- Fix CI and remove rustc-serialize by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/596](https://togithub.com/rust-lang/backtrace-rs/pull/596)
- Use correct base address and update comment by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/604](https://togithub.com/rust-lang/backtrace-rs/pull/604)
- Windows AArch64: Break out of tracing when no longer making progress
by [@&#8203;dpaoliello](https://togithub.com/dpaoliello) in
[https://github.com/rust-lang/backtrace-rs/pull/610](https://togithub.com/rust-lang/backtrace-rs/pull/610)
- Remove obsolete rustc-serialize references by
[@&#8203;atouchet](https://togithub.com/atouchet) in
[https://github.com/rust-lang/backtrace-rs/pull/614](https://togithub.com/rust-lang/backtrace-rs/pull/614)
- Update `object` and `addr2line` dependencies by
[@&#8203;a1phyr](https://togithub.com/a1phyr) in
[https://github.com/rust-lang/backtrace-rs/pull/612](https://togithub.com/rust-lang/backtrace-rs/pull/612)
- Fix tests for rust 1.79 by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/rust-lang/backtrace-rs/pull/621](https://togithub.com/rust-lang/backtrace-rs/pull/621)
- Remove unused `libbacktrace` and `gimli-symbolize` features by
[@&#8203;Enselic](https://togithub.com/Enselic) in
[https://github.com/rust-lang/backtrace-rs/pull/615](https://togithub.com/rust-lang/backtrace-rs/pull/615)
- remove some instances of dead_code by
[@&#8203;klensy](https://togithub.com/klensy) in
[https://github.com/rust-lang/backtrace-rs/pull/619](https://togithub.com/rust-lang/backtrace-rs/pull/619)
- Reduce panics in dbghelp by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/608](https://togithub.com/rust-lang/backtrace-rs/pull/608)
- Add Apple visionOS support by
[@&#8203;QuentinPerez](https://togithub.com/QuentinPerez) in
[https://github.com/rust-lang/backtrace-rs/pull/613](https://togithub.com/rust-lang/backtrace-rs/pull/613)
- Update cc crate to v1.0.97 by
[@&#8203;jfgoog](https://togithub.com/jfgoog) in
[https://github.com/rust-lang/backtrace-rs/pull/623](https://togithub.com/rust-lang/backtrace-rs/pull/623)
- chore: add docs for the global re-entrant lock by
[@&#8203;Gankra](https://togithub.com/Gankra) in
[https://github.com/rust-lang/backtrace-rs/pull/609](https://togithub.com/rust-lang/backtrace-rs/pull/609)
- Test with lld-compatible args by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/rust-lang/backtrace-rs/pull/627](https://togithub.com/rust-lang/backtrace-rs/pull/627)
- Bump rustc-demangle version by
[@&#8203;michaelwoerister](https://togithub.com/michaelwoerister) in
[https://github.com/rust-lang/backtrace-rs/pull/624](https://togithub.com/rust-lang/backtrace-rs/pull/624)
- cleanup dead_code around cpp_demangle feature by
[@&#8203;klensy](https://togithub.com/klensy) in
[https://github.com/rust-lang/backtrace-rs/pull/622](https://togithub.com/rust-lang/backtrace-rs/pull/622)
- Cut backtrace 0.3.72 by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/rust-lang/backtrace-rs/pull/628](https://togithub.com/rust-lang/backtrace-rs/pull/628)

#### New Contributors

- [@&#8203;Enselic](https://togithub.com/Enselic) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/615](https://togithub.com/rust-lang/backtrace-rs/pull/615)
- [@&#8203;QuentinPerez](https://togithub.com/QuentinPerez) made their
first contribution in
[https://github.com/rust-lang/backtrace-rs/pull/613](https://togithub.com/rust-lang/backtrace-rs/pull/613)
- [@&#8203;Gankra](https://togithub.com/Gankra) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/609](https://togithub.com/rust-lang/backtrace-rs/pull/609)

**Full Changelog**:
https://github.com/rust-lang/backtrace-rs/compare/0.3.71...0.3.72

###
[`v0.3.71`](https://togithub.com/rust-lang/backtrace-rs/releases/tag/0.3.71)

[Compare
Source](https://togithub.com/rust-lang/backtrace-rs/compare/0.3.70...0.3.71)

This is mostly CI changes, with a very mild bump to our effective cc
crate version recorded, and a small modification to a previous changeset
to allow backtrace to run at its current checked-in MSRV on Windows.
Sorry about that! We will be getting 0.3.70 yanked shortly.

#### What's Changed

- Make sgx functions exist with cfg(miri) by
[@&#8203;saethlin](https://togithub.com/saethlin) in
[https://github.com/rust-lang/backtrace-rs/pull/591](https://togithub.com/rust-lang/backtrace-rs/pull/591)
- Update version of cc crate by
[@&#8203;jfgoog](https://togithub.com/jfgoog) in
[https://github.com/rust-lang/backtrace-rs/pull/592](https://togithub.com/rust-lang/backtrace-rs/pull/592)
- Pull back MSRV on Windows by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/rust-lang/backtrace-rs/pull/598](https://togithub.com/rust-lang/backtrace-rs/pull/598)
- Force frame pointers on all i686 tests by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/rust-lang/backtrace-rs/pull/601](https://togithub.com/rust-lang/backtrace-rs/pull/601)
- Use rustc from stage0 instead of stage0-sysroot by
[@&#8203;Nilstrieb](https://togithub.com/Nilstrieb) in
[https://github.com/rust-lang/backtrace-rs/pull/602](https://togithub.com/rust-lang/backtrace-rs/pull/602)
- Cut backtrace 0.3.71 by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/rust-lang/backtrace-rs/pull/599](https://togithub.com/rust-lang/backtrace-rs/pull/599)

#### New Contributors

- [@&#8203;jfgoog](https://togithub.com/jfgoog) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/592](https://togithub.com/rust-lang/backtrace-rs/pull/592)
- [@&#8203;Nilstrieb](https://togithub.com/Nilstrieb) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/602](https://togithub.com/rust-lang/backtrace-rs/pull/602)

**Full Changelog**:
https://github.com/rust-lang/backtrace-rs/compare/0.3.70...0.3.71

###
[`v0.3.70`](https://togithub.com/rust-lang/backtrace-rs/releases/tag/0.3.70)

[Compare
Source](https://togithub.com/rust-lang/backtrace-rs/compare/0.3.69...0.3.70)

#### New API

- A `BacktraceFrame` can now have `resolve(&mut self)` called on it
thanks to [@&#8203;fraillt](https://togithub.com/fraillt) in
[https://github.com/rust-lang/backtrace-rs/pull/526](https://togithub.com/rust-lang/backtrace-rs/pull/526)

#### Platform Support

We added support for new platforms in this release!

- Thanks to [@&#8203;bzEq](https://togithub.com/bzEq) in
[https://github.com/rust-lang/backtrace-rs/pull/508](https://togithub.com/rust-lang/backtrace-rs/pull/508)
we now have AIX support!
- Thanks to [@&#8203;sthibaul](https://togithub.com/sthibaul) in
[https://github.com/rust-lang/backtrace-rs/pull/567](https://togithub.com/rust-lang/backtrace-rs/pull/567)
we now have GNU/Hurd support!
- Thanks to [@&#8203;dpaoliello](https://togithub.com/dpaoliello) in
[https://github.com/rust-lang/backtrace-rs/pull/587](https://togithub.com/rust-lang/backtrace-rs/pull/587)
we now support "emulation-compatible" AArch64 Windows (aka arm64ec)

##### Windows

- Rewrite msvc backtrace support to be much faster on 64-bit platforms
by [@&#8203;wesleywiser](https://togithub.com/wesleywiser) in
[https://github.com/rust-lang/backtrace-rs/pull/569](https://togithub.com/rust-lang/backtrace-rs/pull/569)
- Fix i686-pc-windows-gnu missing dbghelp module by
[@&#8203;wesleywiser](https://togithub.com/wesleywiser) in
[https://github.com/rust-lang/backtrace-rs/pull/571](https://togithub.com/rust-lang/backtrace-rs/pull/571)
- Fix build errors on `thumbv7a-*-windows-msvc` targets by
[@&#8203;kleisauke](https://togithub.com/kleisauke) in
[https://github.com/rust-lang/backtrace-rs/pull/573](https://togithub.com/rust-lang/backtrace-rs/pull/573)
- Fix panic in backtrace symbolication on win7 by
[@&#8203;roblabla](https://togithub.com/roblabla) in
[https://github.com/rust-lang/backtrace-rs/pull/578](https://togithub.com/rust-lang/backtrace-rs/pull/578)
- remove few unused windows ffi fn by
[@&#8203;klensy](https://togithub.com/klensy) in
[https://github.com/rust-lang/backtrace-rs/pull/576](https://togithub.com/rust-lang/backtrace-rs/pull/576)
- Make dbghelp look for PDBs next to their exe/dll. by
[@&#8203;michaelwoerister](https://togithub.com/michaelwoerister) in
[https://github.com/rust-lang/backtrace-rs/pull/584](https://togithub.com/rust-lang/backtrace-rs/pull/584)
- Revert 32-bit dbghelp to a version WINE (presumably) likes by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/588](https://togithub.com/rust-lang/backtrace-rs/pull/588)
- Update for Win10+ by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/589](https://togithub.com/rust-lang/backtrace-rs/pull/589)

##### SGX

Thanks to

- Adjust frame IP in SGX relative to image base by
[@&#8203;mzohreva](https://togithub.com/mzohreva) in
[https://github.com/rust-lang/backtrace-rs/pull/566](https://togithub.com/rust-lang/backtrace-rs/pull/566)

#### Internals

We did a bunch more work on our CI and internal cleanups

- Modularise CI workflow and validate outputs for binary size checks. by
[@&#8203;detly](https://togithub.com/detly) in
[https://github.com/rust-lang/backtrace-rs/pull/549](https://togithub.com/rust-lang/backtrace-rs/pull/549)
- Commit Cargo.lock by [@&#8203;bjorn3](https://togithub.com/bjorn3) in
[https://github.com/rust-lang/backtrace-rs/pull/562](https://togithub.com/rust-lang/backtrace-rs/pull/562)
- Enable calling build.rs externally v2 by
[@&#8203;pitaj](https://togithub.com/pitaj) in
[https://github.com/rust-lang/backtrace-rs/pull/568](https://togithub.com/rust-lang/backtrace-rs/pull/568)
- Upgrade to 2021 ed and inline panics by
[@&#8203;nyurik](https://togithub.com/nyurik) in
[https://github.com/rust-lang/backtrace-rs/pull/538](https://togithub.com/rust-lang/backtrace-rs/pull/538)
- Fix deny(unused) of an unused import with SGX + Miri by
[@&#8203;saethlin](https://togithub.com/saethlin) in
[https://github.com/rust-lang/backtrace-rs/pull/581](https://togithub.com/rust-lang/backtrace-rs/pull/581)
- Fix unused_imports warning on latest nightly by
[@&#8203;ChrisDenton](https://togithub.com/ChrisDenton) in
[https://github.com/rust-lang/backtrace-rs/pull/575](https://togithub.com/rust-lang/backtrace-rs/pull/575)
- Fix CI by [@&#8203;saethlin](https://togithub.com/saethlin) in
[https://github.com/rust-lang/backtrace-rs/pull/582](https://togithub.com/rust-lang/backtrace-rs/pull/582)
- Use `addr_of!` by
[@&#8203;GrigorenkoPV](https://togithub.com/GrigorenkoPV) in
[https://github.com/rust-lang/backtrace-rs/pull/585](https://togithub.com/rust-lang/backtrace-rs/pull/585)
- Write down MSRV policy by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/rust-lang/backtrace-rs/pull/561](https://togithub.com/rust-lang/backtrace-rs/pull/561)
- Apply clippy::uninlined_format_args fixes by
[@&#8203;nyurik](https://togithub.com/nyurik) in
[https://github.com/rust-lang/backtrace-rs/pull/486](https://togithub.com/rust-lang/backtrace-rs/pull/486)
- ignore clippy lints in `symbolize/gimli/stash.rs` by
[@&#8203;onur-ozkan](https://togithub.com/onur-ozkan) in
[https://github.com/rust-lang/backtrace-rs/pull/586](https://togithub.com/rust-lang/backtrace-rs/pull/586)

#### New Contributors

- [@&#8203;nyurik](https://togithub.com/nyurik) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/538](https://togithub.com/rust-lang/backtrace-rs/pull/538)
- [@&#8203;bzEq](https://togithub.com/bzEq) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/508](https://togithub.com/rust-lang/backtrace-rs/pull/508)
- [@&#8203;bjorn3](https://togithub.com/bjorn3) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/562](https://togithub.com/rust-lang/backtrace-rs/pull/562)
- [@&#8203;sthibaul](https://togithub.com/sthibaul) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/567](https://togithub.com/rust-lang/backtrace-rs/pull/567)
- [@&#8203;mzohreva](https://togithub.com/mzohreva) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/566](https://togithub.com/rust-lang/backtrace-rs/pull/566)
- [@&#8203;wesleywiser](https://togithub.com/wesleywiser) made their
first contribution in
[https://github.com/rust-lang/backtrace-rs/pull/569](https://togithub.com/rust-lang/backtrace-rs/pull/569)
- [@&#8203;kleisauke](https://togithub.com/kleisauke) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/573](https://togithub.com/rust-lang/backtrace-rs/pull/573)
- [@&#8203;roblabla](https://togithub.com/roblabla) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/578](https://togithub.com/rust-lang/backtrace-rs/pull/578)
- [@&#8203;michaelwoerister](https://togithub.com/michaelwoerister) made
their first contribution in
[https://github.com/rust-lang/backtrace-rs/pull/584](https://togithub.com/rust-lang/backtrace-rs/pull/584)
- [@&#8203;dpaoliello](https://togithub.com/dpaoliello) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/587](https://togithub.com/rust-lang/backtrace-rs/pull/587)
- [@&#8203;GrigorenkoPV](https://togithub.com/GrigorenkoPV) made their
first contribution in
[https://github.com/rust-lang/backtrace-rs/pull/585](https://togithub.com/rust-lang/backtrace-rs/pull/585)
- [@&#8203;fraillt](https://togithub.com/fraillt) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/526](https://togithub.com/rust-lang/backtrace-rs/pull/526)
- [@&#8203;onur-ozkan](https://togithub.com/onur-ozkan) made their first
contribution in
[https://github.com/rust-lang/backtrace-rs/pull/586](https://togithub.com/rust-lang/backtrace-rs/pull/586)

**Full Changelog**:
https://github.com/rust-lang/backtrace-rs/compare/0.3.69...0.3.70

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 09:43:39 -04:00
renovate[bot]
af014a2530 Update Rust crate cargo_toml to v0.20.4 (#15276)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [cargo_toml](https://lib.rs/cargo_toml)
([source](https://gitlab.com/lib.rs/cargo_toml)) |
workspace.dependencies | patch | `0.20.2` -> `0.20.4` |

---

### Release Notes

<details>
<summary>lib.rs/cargo_toml (cargo_toml)</summary>

###
[`v0.20.4`](https://gitlab.com/lib.rs/cargo_toml/compare/v0.20.3...v0.20.4)

[Compare
Source](https://gitlab.com/lib.rs/cargo_toml/compare/v0.20.3...v0.20.4)

###
[`v0.20.3`](https://gitlab.com/lib.rs/cargo_toml/compare/v0.20.2...v0.20.3)

[Compare
Source](https://gitlab.com/lib.rs/cargo_toml/compare/v0.20.2...v0.20.3)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 09:40:57 -04:00
Kirill Bulatov
243fb3562c Auto fold directories in the project panel by default (#15273) 2024-07-26 15:26:20 +03:00
Kirill Bulatov
e830865eb1 Return an empty measurement instead of panicking (#15269)
Follow-up of https://github.com/zed-industries/zed/pull/15256

Returns zero size for no items to render.

Incorrect worktree state made the uniform list to have 0 items to
render, so
```Rust
let mut items = (self.render_items)(item_ix..item_ix + 1, cx);
let mut item_to_measure = items.pop().unwrap();
```
panicked as the first line returned an empty array despite a
single-element range provided.


Release Notes:

- N/A
2024-07-26 14:21:09 +03:00
CharlesChen0823
7aa6f4788d regression: Fix a panic when removing git-containing worktree from the project panel (#15256)
Follow-up of #14989

Opening a project with git metadata and clicking "Remove from Project" will panic:
![image](https://github.com/user-attachments/assets/ba00dc55-d299-4edc-9a1f-01e92f0dd9ca)

Release Notes:

- N/A
2024-07-26 14:20:59 +03:00
Thorsten Ball
18daf17d0e refactoring: Use helper instead of adjusting selection manually (#15262)
I added `newest_adjusted` recently and now just bumped into the old code
that didn't use it.

Release Notes:

- N/A
2024-07-26 11:12:33 +02:00
Joseph T. Lyons
856d9632e4 Add repl events (#15259)
Release Notes:

- N/A

---------

Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
2024-07-26 03:31:41 -04:00
Marshall Bowers
745d2e4d3b collab: Extract contributor endpoints to their own module (#15251)
This PR extracts the contributor endpoints to their own module for
organizational purposes.

Release Notes:

- N/A
2024-07-25 23:02:32 -04:00
Marshall Bowers
50dbab0747 collab: Add renovate[bot] to the GET /contributor endpoint (#15250)
This PR adds the `renovate[bot]` user to the `GET /contributor` endpoint
so that it passes the CLA check.

I patched this temporarily by adding a case into the `zed.dev` endpoint
the fronts this one, but I think long-term it will be better for collab
to be the source of truth.

Release Notes:

- N/A
2024-07-25 22:52:59 -04:00
renovate[bot]
70c22cbdd6 Update Rust crate indoc to v2 (#15247)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [indoc](https://togithub.com/dtolnay/indoc) | workspace.dependencies |
major | `1` -> `2` |

---

### Release Notes

<details>
<summary>dtolnay/indoc (indoc)</summary>

### [`v2.0.5`](https://togithub.com/dtolnay/indoc/releases/tag/2.0.5)

[Compare
Source](https://togithub.com/dtolnay/indoc/compare/2.0.4...2.0.5)

- Documentation improvements
([#&#8203;62](https://togithub.com/dtolnay/indoc/issues/62), thanks
[@&#8203;ilyagr](https://togithub.com/ilyagr))

### [`v2.0.4`](https://togithub.com/dtolnay/indoc/releases/tag/2.0.4)

[Compare
Source](https://togithub.com/dtolnay/indoc/compare/2.0.3...2.0.4)

- Fix handling of \r\n ending on first line
([#&#8203;61](https://togithub.com/dtolnay/indoc/issues/61), thanks
[@&#8203;PizzasBear](https://togithub.com/PizzasBear))

### [`v2.0.3`](https://togithub.com/dtolnay/indoc/releases/tag/2.0.3)

[Compare
Source](https://togithub.com/dtolnay/indoc/compare/2.0.2...2.0.3)

-   Documentation improvements

### [`v2.0.2`](https://togithub.com/dtolnay/indoc/releases/tag/2.0.2)

[Compare
Source](https://togithub.com/dtolnay/indoc/compare/2.0.1...2.0.2)

-   Add `no-alloc` category to crates.io metadata

### [`v2.0.1`](https://togithub.com/dtolnay/indoc/releases/tag/2.0.1)

[Compare
Source](https://togithub.com/dtolnay/indoc/compare/2.0.0...2.0.1)

-   Set html_root_url attribute

### [`v2.0.0`](https://togithub.com/dtolnay/indoc/releases/tag/2.0.0)

[Compare
Source](https://togithub.com/dtolnay/indoc/compare/1.0.9...2.0.0)

- Change handling of final newline at zero levels of indentation
([#&#8203;55](https://togithub.com/dtolnay/indoc/issues/55))
- Add [`concatdoc!`](https://docs.rs/indoc/2/indoc/macro.concatdoc.html)
macro ([#&#8203;56](https://togithub.com/dtolnay/indoc/issues/56))
-   Raise oldest supported rustc to 1.56

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 21:59:17 -04:00
Marshall Bowers
9621005851 Organize workspace Cargo.toml (#15244)
This PR does a bit of organization of the workspace `Cargo.toml`.

Release Notes:

- N/A
2024-07-25 21:52:53 -04:00
Marshall Bowers
05003ed4c5 Hoist strum to workspace level (#15243)
This PR hoists `strum` up to a workspace dependency.

Release Notes:

- N/A
2024-07-25 21:30:48 -04:00
renovate[bot]
2c610c0e57 Update Rust crate ctor to v0.2.8 (#15242)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [ctor](https://togithub.com/mmastrac/rust-ctor) |
workspace.dependencies | patch | `0.2.6` -> `0.2.8` |

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 21:26:51 -04:00
Marshall Bowers
479ffbbd51 ui: Make Label respect the ui_font_weight setting (#15241)
This PR makes the `Label` component respect the `ui_font_weight`
setting, by default.

An explicit font weight can still be set via the `weight` method, which
will override the `ui_font_weight` for that `Label`.

<img width="1566" alt="Screenshot 2024-07-25 at 8 55 16 PM"
src="https://github.com/user-attachments/assets/2751e29c-c76e-4685-8564-604b3b77f603">

Release Notes:

- Updated UI labels to respect the `ui_font_weight` setting
([#15234](https://github.com/zed-industries/zed/issues/15234)).
2024-07-25 21:08:28 -04:00
Marshall Bowers
fe23504eba uiua: Upgrade zed_extension_api to v0.0.6 (#15240)
This PR upgrades the Uiua extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-25 20:43:15 -04:00
Marshall Bowers
95d82f88de ui: Make custom rows in ContextMenus use a normal cursor (#15239)
This PR makes custom rows in `ContextMenu`s use a regular cursor instead
of a pointer.

Even though custom rows were marked as not selectable, we would still
pass a click handler to them, causing the `ListItem` to show a pointer
cursor.

Release Notes:

- N/A
2024-07-25 20:16:53 -04:00
Peter Tripp
4000b0a02c Restore linux ctrl-d functionality (#15238)
- Restore `ctrl-d` functionality accidentally removed
- Remove duplicate `ctrl-d` keymap in `Editor` context (dead)
2024-07-25 20:11:47 -04:00
Marshall Bowers
02c43a5bf2 Add missing workspace lints (#15237)
This PR adds the missing workspace lint configuration for the following
crates that were missing it:

- `google_ai`
- `open_ai`
- `tab_switcher`

Release Notes:

- N/A
2024-07-25 19:52:24 -04:00
Marshall Bowers
f2060ccbe0 xtask: Add command for checking packages conform to certain standards (#15236)
This PR adds a new `xtask` command for checking that packages conform to
certain standards.

Still a work-in-progress, but right now it checks:

- If `[lints] workspace = true` is set
- If packages are using non-workspace dependencies

Release Notes:

- N/A
2024-07-25 19:20:08 -04:00
Kyle Kelley
13693ff80f docs: Embed video directly, copying formatting from blog (#15229)
Quick doc fix for formatting and display. 


![image](https://github.com/user-attachments/assets/5f869516-74d0-417a-bbeb-4b65f1961b12)

Release Notes:

- N/A
2024-07-25 16:05:04 -07:00
Piotr Osiewicz
ec5886a078 rust: Add static items to the outline (#15225)
Fixes #15208
Release Notes:

- Outline panel for Rust files now includes static items.
2024-07-26 00:52:42 +02:00
Kirill Bulatov
10c9e337cf Fix more gutter close button alignment issues (#15233)
Follow-up of https://github.com/zed-industries/zed/pull/15178

* shows proper cursor on hovering a block that's over a git hunk
* show gutter buttons better when git hunks are on the same line
* show deleted hunks' gutter buttons better when git blame info is shown
in the gutter

Release Notes:

- N/A
2024-07-26 01:42:25 +03:00
Marshall Bowers
1da6a12bb4 Upgrade scrypt to v0.11 (#15228)
This PR upgrades `scrypt` to v0.11.

There were some API changes that impacted our usage just in the tests.

Supersedes #15224.

Release Notes:

- N/A
2024-07-25 17:45:24 -04:00
Kyle Kelley
cc1d3f0a35 docs: Update REPL docs with images, cell mode, and kernel debugging (#15226)
Just a few doc tweaks.

Release Notes:

- N/A
2024-07-25 14:26:14 -07:00
renovate[bot]
22118f15e9 Update Rust crate sha2 to v0.10.8 (#15223)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [sha2](https://togithub.com/RustCrypto/hashes) |
workspace.dependencies | patch | `0.10.7` -> `0.10.8` |

---

### Release Notes

<details>
<summary>RustCrypto/hashes (sha2)</summary>

###
[`v0.10.8`](https://togithub.com/RustCrypto/hashes/compare/sha2-v0.10.7...sha2-v0.10.8)

[Compare
Source](https://togithub.com/RustCrypto/hashes/compare/sha2-v0.10.7...sha2-v0.10.8)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 17:21:24 -04:00
Piotr Osiewicz
0d5de88c4b chore: Bump Rust version to 1.80 (#15186)
Release Notes:

- N/A
2024-07-25 22:48:42 +02:00
Marshall Bowers
f291677d40 Upgrade async-tungstenite to v0.23 (#15220)
This PR upgrades `async-tungstenite` to v0.23.

This is so we can get the CVE fix in `tungstenite` v0.20.1.

Now that #15219 is done, upgrading to v0.23 no longer breaks
authentication with collab.

Release Notes:

- N/A
2024-07-25 16:11:01 -04:00
Marshall Bowers
9d736fe80c Upgrade async-tungstenite to v17 and update usage accordingly (#15219)
This PR upgrades `async-tungstenite` to v17.0.3.

We previously attempted upgrading `async-tungstenite` in #15039, but
broke authentication with collab in the process.

Upon further investigation, I determined that the root cause is due to
this change in `tungstenite` v0.17.0:

> Overhaul of the client's request generation process. Now the users are
able to pass the constructed `http::Request` "as is" to
`tungstenite-rs`, letting the library to check the correctness of the
request and specifying their own headers (including its own key if
necessary). No changes for those ones who used the client in a normal
way by connecting using a URL/URI (most common use-case).

We _were_ relying on passing an `http::Request` directly to
`tungstenite`, meaning we did not benefit from the changes to the common
path (of passing a URL/URI).

This meant that—due to changes in `tungstenite`—we were now missing the
`Sec-WebSocket-Key` header that `tungstenite` would otherwise set for
us.

Since we were only passing a custom `http::Request` to set headers, our
approach has been adjusted to construct the initial WebSocket request
using `tungstenite`'s `IntoClientRequest::into_client_request` and then
modifying the request to set our additional desired headers.

Release Notes:

- N/A
2024-07-25 15:53:22 -04:00
张小白
f3ad754396 linux: Fix wrong names reported by all_font_names (#14865)
The names suggested by `buffer_font_family` are reported by
`all_font_names`. Therefore, `all_font_names` should report family names
rather than postscript names.

close #14854 

Release Notes:

- N/A
2024-07-25 11:53:22 -07:00
Piotr Osiewicz
86456ce379 chore: Fix clippy violations from Cargo.toml (#15216)
/cc @maxdeviant 
Release Notes:

- N/A
2024-07-25 20:22:01 +02:00
Marshall Bowers
d755d29577 extension: Upgrade wasmtime to v21 (#15210)
This PR upgrades the version of `wasmtime` and `wasmtime-wasi` in use to
v21.0.1.

We have to skip v20 because Tree-sitter also skipped it.

Here are the changes that had to be made:

### v19 -> v20

After upgrading the `wasmtime` packages to v20, I also had to run `cargo
update -p mach2` to pull in
[v0.4.2](https://github.com/JohnTitor/mach2/releases/tag/0.4.2) to fix
some compile errors.

There were a few minor API changes in `wasmtime-wasi` from
https://github.com/bytecodealliance/wasmtime/pull/8228 that we needed to
account for.

### v20 -> v21

Since there isn't a Tree-sitter version that depends on `wasmtime@v20`,
we're jumping straight to v21.

The published version of Tree-sitter (v0.22.6) still depends on
`wasmtime@v19`, but there was a commit
(7f4a57817d)
later that month that upgrades the `wasmtime` dependency to v21.

We're patching Tree-sitter to that commit so we can get the new
`wasmtime` version.

The main change in v21 is that imports generated by `bindgen!` are no
longer automatically trapped
(https://github.com/bytecodealliance/wasmtime/pull/8310), so we need to
add `trappable_imports: true` to our `bindgen!` calls.

Release Notes:

- N/A
2024-07-25 13:56:40 -04:00
Nathaniel
ab3c9f0678 windows: Allow horizontal scroll with shift + scroll (#14147)
Release Notes:

- Horizontally scroll when holding down the Shift key and using the
scroll wheel


https://github.com/zed-industries/zed/assets/95680272/e6480f9c-0f6a-4f47-b700-a3657a75716f
2024-07-25 10:44:35 -07:00
张小白
201db23b58 windows: Fix titlebar rendering on Windows 10 (#14656)
As we discussed in #14190, we agreed to open a new PR.

Release Notes:

- N/A
2024-07-25 10:43:25 -07:00
张小白
beb8fbdf7f windows: Remove unnecessary Send and Sync implementations (#14659)
After a update to `windows-rs 0.57`, these two implementations are no
longer needed.

Release Notes:

- N/A
2024-07-25 10:42:36 -07:00
张小白
d2501e8886 windows: Bump windows-rs version (#14719)
Release Notes:

- N/A
2024-07-25 10:41:59 -07:00
张小白
82d6ad4616 Make CosmicTextSystem Linux-only (#14728)
Since `WindowsDispatcher` requires a minimum Windows version of Windows
10 Fall Creators Update (10.0.16299), and the `alacritty_terminal`
dependency relies on conPTY, an API introduced in the same version,
additionally, `DirectWriteTextSystem` also relies on Windows 10 Fall
Creators Update (10.0.16299), so it seems reasonable to make
`CosmicTextSystem` Linux-only. And we can use `DirectWriteTextSystem` on
the Windows platform exclusively. I hope this approach makes sense.

Release Notes:

- N/A
2024-07-25 10:40:49 -07:00
张小白
a60b3b9389 windows: Stop beeping (#14872)
Close #14857 

Release Notes:

- N/A
2024-07-25 10:26:36 -07:00
Fernando Tagawa
06863144c6 x11: Add keyboard layout hot plugging (#15059)
Now it is possible to change keyboard layouts with `setxkbmap` without
having to restart zed.
 
Release Notes:

- x11: Support for keyboard layout hot plugging.
2024-07-25 10:25:34 -07:00
Harsh Narayan Jha
b7c6f3e98e linux: Update TryExec value in desktop file (#15149)
Release Notes:

- Fixed ([#15148](https://github.com/zed-industries/zed/issues/15148)).
2024-07-25 10:16:23 -06:00
Thorsten Ball
7146087b44 zed: Mark restored buffers as conflicted if file changed on disk between store & restore (#15207)
Previously, we've only marked restored buffers as dirty. This PR changes
that behavior in case the buffer has been associated with a file and
that file has changed on disk since the last time Zed stored its
contents.

Example timeline:

1. User edits file in Zed, buffer is dirty
2. User quites Zed with `cmd-q`
3. User changes file on disk: `echo foobar >> file.txt` or `git checkout
file.txt`
4. User starts Zed
5. File/buffer are now marked as having a conflict (yellow icon)

Release Notes:

- Unsaved files that are restored when Zed starts are now marked as
having a conflict if they have been changed on disk since the last time
they were stored.

Demo:



https://github.com/user-attachments/assets/6098b485-b325-49b7-b694-fd2fc60cce64
2024-07-25 18:04:47 +02:00
Marshall Bowers
6d3eaa055f renovate: Fix wasmtime package prefix 2024-07-25 11:45:14 -04:00
Marshall Bowers
f31c55a76f zig: Bump to v0.1.5 (#15203)
This PR bumps the Zig extension to v0.1.5.

Changes:

- #15197

Release Notes:

- N/A
2024-07-25 11:36:50 -04:00
Marshall Bowers
97750529fe renovate: Fix selector for wasmtime group (#15202)
This PR fixes the package name selector for the `wasmtime` group.

Release Notes:

- N/A
2024-07-25 11:30:31 -04:00
Uberlicious
cd9dd5ccf7 zig: Add Windows support (#15197)
Release Notes:

- N/A

Currently Windows environments do not have a `shell_env`. This causes
the Zig extension to error when trying to call `worktree.shell_env()`
since extensions api isn't yet on `0.0.7` and thus not using wasm-host
`0.0.7` we need to only call for the shell env only on non-windows
systems. 0.0.7 and onward at the moment return a Result from
`shell_env()`. The binary path is also slightly different on windows.

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-25 11:30:02 -04:00
Marshall Bowers
3ce864e69e renovate: Group wasmtime updates (#15199)
This PR updates the Renovate config to group `wasmtime` crates together
(e.g., `wasmtime` and `wasmtime-wasi`).

Release Notes:

- N/A
2024-07-25 11:21:51 -04:00
Marshall Bowers
9eeb564c5c danger: Upgrade danger to v12 (#15194)
This PR upgrades `danger` to v12.

Release Notes:

- N/A
2024-07-25 11:07:04 -04:00
Conrad Irwin
847bd35bd9 vim remap 2 (#15193)
Release Notes:

- N/A
2024-07-25 09:00:53 -06:00
renovate[bot]
b8e5ddf456 Update actions/checkout action to v4 (#15189)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://togithub.com/actions/checkout) | action |
major | `v2` -> `v4` |

---

### Release Notes

<details>
<summary>actions/checkout (actions/checkout)</summary>

###
[`v4`](https://togithub.com/actions/checkout/blob/HEAD/CHANGELOG.md#v417)

[Compare Source](https://togithub.com/actions/checkout/compare/v3...v4)

- Bump the minor-npm-dependencies group across 1 directory with 4
updates by [@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/actions/checkout/pull/1739](https://togithub.com/actions/checkout/pull/1739)
- Bump actions/checkout from 3 to 4 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/actions/checkout/pull/1697](https://togithub.com/actions/checkout/pull/1697)
- Check out other refs/\* by commit by
[@&#8203;orhantoy](https://togithub.com/orhantoy) in
[https://github.com/actions/checkout/pull/1774](https://togithub.com/actions/checkout/pull/1774)
- Pin actions/checkout's own workflows to a known, good, stable version.
by [@&#8203;jww3](https://togithub.com/jww3) in
[https://github.com/actions/checkout/pull/1776](https://togithub.com/actions/checkout/pull/1776)

###
[`v3`](https://togithub.com/actions/checkout/blob/HEAD/CHANGELOG.md#v360)

[Compare Source](https://togithub.com/actions/checkout/compare/v2...v3)

- [Fix: Mark test scripts with Bash'isms to be run via
Bash](https://togithub.com/actions/checkout/pull/1377)
- [Add option to fetch tags even if fetch-depth >
0](https://togithub.com/actions/checkout/pull/579)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 09:48:15 -04:00
Peter Tripp
6998c03c59 Document git permalinks (GitHub, Gitlab, Bitbucket, SourceHut, Codeberg, etc) (#15113)
- Docs: Added "Copy Permalink to Line" and "Open Permalink to Line"
2024-07-25 09:39:57 -04:00
Antonio Scandurra
8631180e43 Avoid buffering line content to compute indent guides (#15167)
Release Notes:

- Improved performance when computing indent guides for buffers with
extremely long lines.

---------

Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Bennet <bennet@zed.dev>
Co-authored-by: Thorsten <thorsten@zed.dev>
2024-07-25 15:21:50 +02:00
renovate[bot]
cd9a42e8da Pin dependencies (#15188)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[2428392/gh-truncate-string-action](https://togithub.com/2428392/gh-truncate-string-action)
| action | pinDigest | -> `67b1b81` |
| [actions/checkout](https://togithub.com/actions/checkout) | action |
pinDigest | -> `692973e` |
| [actions/checkout](https://togithub.com/actions/checkout) | action |
pinDigest | -> `ee0669b` |
| [actions/setup-node](https://togithub.com/actions/setup-node) | action
| pinDigest | -> `1e60f62` |
| [actions/setup-python](https://togithub.com/actions/setup-python) |
action | pinDigest | -> `39cd149` |
|
[actions/upload-artifact](https://togithub.com/actions/upload-artifact)
| action | pinDigest | -> `0b2256b` |
|
[cloudflare/wrangler-action](https://togithub.com/cloudflare/wrangler-action)
| action | pinDigest | -> `f84a562` |
|
[dcarbone/install-jq-action](https://togithub.com/dcarbone/install-jq-action)
| action | pinDigest | -> `8867ddb` |
|
[peaceiris/actions-mdbook](https://togithub.com/peaceiris/actions-mdbook)
| action | pinDigest | -> `ee69d23` |
| [rui314/setup-mold](https://togithub.com/rui314/setup-mold) | action |
pinDigest | -> `2e332a0` |
|
[softprops/action-gh-release](https://togithub.com/softprops/action-gh-release)
| action | pinDigest | -> `de2c0eb` |
| [swatinem/rust-cache](https://togithub.com/swatinem/rust-cache) |
action | pinDigest | -> `23bce25` |
|
[tsickert/discord-webhook](https://togithub.com/tsickert/discord-webhook)
| action | pinDigest | -> `c840d45` |

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 09:19:05 -04:00
Marshall Bowers
3246a932ca renovate: Pin GitHub Action versions with SHAs (#15184)
This PR updates the Renovate config to pin all GitHub Action versions to
SHAs.

From the Renovate docs:

> The [GitHub Docs, using third-party
actions](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions)
recommend that you pin third-party GitHub Actions to a full-length
commit SHA.
>
> We recommend pinning all Actions. That's why the
helpers:pinGitHubActionDigests preset pins all GitHub Actions.
>
> For an in-depth explanation why you should pin your Github Actions,
read the [Palo Alto Networks blog post about the GitHub Actions
worm](https://www.paloaltonetworks.com/blog/prisma-cloud/github-actions-worm-dependencies/).

Release Notes:

- N/A
2024-07-25 09:02:48 -04:00
Marshall Bowers
8ba392bba6 purescript: Upgrade zed_extension_api to v0.0.6 (#15181)
This PR upgrades the PureScript extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-25 08:55:16 -04:00
Kirill Bulatov
856a8ef5e8 Layout gutter hunk diff close button (X) better (#15178)
Closes https://github.com/zed-industries/zed/issues/15164

* Deleted hunk
Before:

![before_top](https://github.com/user-attachments/assets/27c72ee5-719f-4787-b222-4f597840936a)

After:

![after_top](https://github.com/user-attachments/assets/58095b21-698d-4778-8412-b680d5253e2c)

* Modified hunk
Before:

![before_down](https://github.com/user-attachments/assets/3fffb73b-7101-493c-b63b-15c3ccaf5362)

After:

![after_down](https://github.com/user-attachments/assets/f07a05ed-1260-4e2a-9388-c9cb93020d78)

* Added hunk
Before:

![before_mid](https://github.com/user-attachments/assets/0dd3f0f9-51e8-449a-bdd7-4c3ba5cd7791)

After:

![after_mid](https://github.com/user-attachments/assets/92f749bd-2d95-4650-8334-1d5c38c6aeb6)

Release Notes:

- N/A
2024-07-25 15:50:57 +03:00
renovate[bot]
6dd9ce1376 Update Rust crate smallvec to v1.13.2 (#15179)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [smallvec](https://togithub.com/servo/rust-smallvec) |
workspace.dependencies | minor | `1.11.1` -> `1.13.2` |

---

### Release Notes

<details>
<summary>servo/rust-smallvec (smallvec)</summary>

###
[`v1.13.2`](https://togithub.com/servo/rust-smallvec/releases/tag/v1.13.2)

[Compare
Source](https://togithub.com/servo/rust-smallvec/compare/v1.13.1...v1.13.2)

#### What's Changed

- Add more tests for UB by
[@&#8203;workingjubilee](https://togithub.com/workingjubilee) in
[https://github.com/servo/rust-smallvec/pull/346](https://togithub.com/servo/rust-smallvec/pull/346)
- Fix UB on out-of-bounds insert() by
[@&#8203;mbrubeck](https://togithub.com/mbrubeck) in
[https://github.com/servo/rust-smallvec/pull/345](https://togithub.com/servo/rust-smallvec/pull/345)

**Full Changelog**:
https://github.com/servo/rust-smallvec/compare/v1.13.1...v1.13.2

###
[`v1.13.1`](https://togithub.com/servo/rust-smallvec/releases/tag/v1.13.1)

[Compare
Source](https://togithub.com/servo/rust-smallvec/compare/v1.13.0...v1.13.1)

- Remove the optional `get-size` feature, to avoid a cyclic dependency
([#&#8203;335](https://togithub.com/servo/rust-smallvec/issues/335)).

**Full Changelog**:
https://github.com/servo/rust-smallvec/compare/v1.13.0...v1.13.1

###
[`v1.13.0`](https://togithub.com/servo/rust-smallvec/releases/tag/v1.13.0)

[Compare
Source](https://togithub.com/servo/rust-smallvec/compare/v1.12.0...v1.13.0)

#### What's Changed

- Impl get_size::GetSize (behind feature flag) by
[@&#8203;amandasaurus](https://togithub.com/amandasaurus) in
[https://github.com/servo/rust-smallvec/pull/335](https://togithub.com/servo/rust-smallvec/pull/335)

**Full Changelog**:
https://github.com/servo/rust-smallvec/compare/v1.12.0...v1.13.0

###
[`v1.12.0`](https://togithub.com/servo/rust-smallvec/releases/tag/v1.12.0)

[Compare
Source](https://togithub.com/servo/rust-smallvec/compare/v1.11.2...v1.12.0)

#### What's Changed

- Add `from_const_with_len_unchecked` by
[@&#8203;Expyron](https://togithub.com/Expyron) in
[https://github.com/servo/rust-smallvec/pull/329](https://togithub.com/servo/rust-smallvec/pull/329)

#### New Contributors

- [@&#8203;Expyron](https://togithub.com/Expyron) made their first
contribution in
[https://github.com/servo/rust-smallvec/pull/329](https://togithub.com/servo/rust-smallvec/pull/329)

**Full Changelog**:
https://github.com/servo/rust-smallvec/compare/v1.11.2...v1.12.0

###
[`v1.11.2`](https://togithub.com/servo/rust-smallvec/releases/tag/v1.11.2)

[Compare
Source](https://togithub.com/servo/rust-smallvec/compare/v1.11.1...v1.11.2)

#### What's Changed

- Automated testing improvements by
[@&#8203;waywardmonkeys](https://togithub.com/waywardmonkeys) in
[https://github.com/servo/rust-smallvec/pull/322](https://togithub.com/servo/rust-smallvec/pull/322)
and
[https://github.com/servo/rust-smallvec/pull/326](https://togithub.com/servo/rust-smallvec/pull/326)
- fix: don't special-case `doc` for `feature = "const_generics"` by
[@&#8203;mkroening](https://togithub.com/mkroening) in
[https://github.com/servo/rust-smallvec/pull/328](https://togithub.com/servo/rust-smallvec/pull/328)
- Code cleanup by [@&#8203;emilio](https://togithub.com/emilio) in
[https://github.com/servo/rust-smallvec/pull/316](https://togithub.com/servo/rust-smallvec/pull/316)
and [@&#8203;waywardmonkeys](https://togithub.com/waywardmonkeys) in
[https://github.com/servo/rust-smallvec/pull/323](https://togithub.com/servo/rust-smallvec/pull/323)
- Minor tweaks to doc formatting. by
[@&#8203;waywardmonkeys](https://togithub.com/waywardmonkeys) in
[https://github.com/servo/rust-smallvec/pull/318](https://togithub.com/servo/rust-smallvec/pull/318)

#### New Contributors

- [@&#8203;mkroening](https://togithub.com/mkroening) made their first
contribution in
[https://github.com/servo/rust-smallvec/pull/328](https://togithub.com/servo/rust-smallvec/pull/328)

**Full Changelog**:
https://github.com/servo/rust-smallvec/compare/v1.11.1...v1.11.2

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 08:48:56 -04:00
Marshall Bowers
fbbea7ab01 prisma: Upgrade zed_extension_api to v0.0.6 (#15180)
This PR upgrades the Prisma extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-25 08:46:17 -04:00
Marshall Bowers
aded3dfb05 emmet: Upgrade zed_extension_api to v0.0.6 (#15177)
This PR upgrades the Emmet extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-25 08:34:45 -04:00
Marshall Bowers
3053f98652 csharp: Upgrade zed_extension_api to v0.0.6 (#15175)
This PR upgrades the C# extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-25 08:26:04 -04:00
Peter Tripp
ebd407deb6 Fix broken link in initial settings (#15119)
Fixes #15114
2024-07-25 08:25:27 -04:00
Marshall Bowers
5e44f5fa44 terraform: Bump to v0.0.4 (#15174)
This PR bumps the Terraform extension to v0.0.4.

Changes:

- #10937
- #15171

Release Notes:

- N/A
2024-07-25 08:22:28 -04:00
Marshall Bowers
a07122d78f deno: Bump to v0.0.2 (#15173)
This PR bumps the Deno extension to v0.0.2.

Changes:

- #14410

Release Notes:

- N/A
2024-07-25 08:19:43 -04:00
Marshall Bowers
6a079cbdc3 astro: Bump to v0.1.0 (#15172)
This PR bumps the Astro extension to v0.1.0.

Changes:

- #14849
- #15010
- #15011

Release Notes:

- N/A
2024-07-25 08:16:28 -04:00
Marshall Bowers
c7e2d5bd89 terraform: Make downloaded language server binary executable (#15171)
This PR updates the Terraform extension to make the downloaded language
server binary executable.

Resolves #14502.

Release Notes:

- N/A
2024-07-25 08:08:38 -04:00
renovate[bot]
6bff8ecb73 Update Rust crate heed to v0.20.3 (#15169)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [heed](https://togithub.com/Kerollmops/heed) | workspace.dependencies
| patch | `0.20.1` -> `0.20.3` |

---

### Release Notes

<details>
<summary>Kerollmops/heed (heed)</summary>

###
[`v0.20.3`](https://togithub.com/meilisearch/heed/releases/tag/v0.20.3):
🛁

[Compare
Source](https://togithub.com/Kerollmops/heed/compare/v0.20.2...v0.20.3)

<p align="center"><img width="280px"
src="https://raw.githubusercontent.com/meilisearch/heed/main/assets/heed-pigeon-logo.png"></a></p>
<h1 align="center" >heed</h1>

##### What's Changed
* Update dependencies by
@&#8203;irevoi[https://github.com/meilisearch/heed/pull/265](https://togithub.com/meilisearch/heed/pull/265)ll/265

###
[`v0.20.2`](https://togithub.com/meilisearch/heed/releases/tag/v0.20.2):
🛁

[Compare
Source](https://togithub.com/Kerollmops/heed/compare/v0.20.1...v0.20.2)

<p align="center"><img width="280px"
src="https://raw.githubusercontent.com/meilisearch/heed/main/assets/heed-pigeon-logo.png"></a></p>
<h1 align="center" >heed</h1>

##### What's Changed
* Introduce the `longer-keys` feature which sets `-DMDB_MAXKEYSIZE=0` by
@&#8203;tpund[https://github.com/meilisearch/heed/pull/263](https://togithub.com/meilisearch/heed/pull/263)ll/263
* Bump the internal LMDB version to v0.9.33 by
@&#8203;Kerollmo[https://github.com/meilisearch/heed/pull/264](https://togithub.com/meilisearch/heed/pull/264)ll/264

##### New Contributors
* @&#8203;tpunder made their first
contributi[https://github.com/meilisearch/heed/pull/263](https://togithub.com/meilisearch/heed/pull/263)ll/263

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 07:55:15 -04:00
Thorsten Ball
e2113e4895 repl: Add ability to evaluate Markdown code blocks (#15100)
This adds the ability to evaluate TypeScript and Python code blocks in
Markdown files.

cc @rgbkrk 

Demo:


https://github.com/user-attachments/assets/55352de5-68f3-4aef-920a-78ca205651ba



Release Notes:

- N/A

---------

Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Antonio <antonio@zed.dev>
2024-07-25 12:11:19 +02:00
renovate[bot]
b56e4ff2af Update Rust crate any_vec to 0.14 (#15147)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [any_vec](https://togithub.com/tower120/any_vec) |
workspace.dependencies | minor | `0.13` -> `0.14` |

---

### Release Notes

<details>
<summary>tower120/any_vec (any_vec)</summary>

###
[`v0.14.0`](https://togithub.com/tower120/any_vec/blob/HEAD/CHANGELOG.md#0140)

[Compare
Source](https://togithub.com/tower120/any_vec/compare/v0.13.0...v0.14.0)

##### Added

-   Now library `no_std` friendly.

##### Removed

- Helpers `any_value::move_out`, `any_value::move_out_w_size` removed as
redundant.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 12:38:09 +03:00
Marshall Bowers
88f68101d4 renovate: Separate major versions into multiple PRs (#15146)
This PR updates the Renovate config to split major versions changes into
multiple PRs.

This way we only have to deal with one set of breaking changes at a time
instead of jumping across multiple major versions.

Release Notes:

- N/A
2024-07-24 23:48:53 -04:00
renovate[bot]
d852a32ef1 Update Rust crate async-broadcast to v0.7.1 (#15142)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [async-broadcast](https://togithub.com/smol-rs/async-broadcast) |
dependencies | patch | `0.7.0` -> `0.7.1` |

---

### Release Notes

<details>
<summary>smol-rs/async-broadcast (async-broadcast)</summary>

###
[`v0.7.1`](https://togithub.com/smol-rs/async-broadcast/blob/HEAD/CHANGELOG.md#Version-071)

[Compare
Source](https://togithub.com/smol-rs/async-broadcast/compare/0.7.0...v0.7.1)

- Add a `poll_recv()` method to the `Receiver` type. This allows for
`Receiver`
to be used in `poll`-based contexts.
([#&#8203;56](https://togithub.com/smol-rs/async-broadcast/issues/56))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-24 23:34:49 -04:00
renovate[bot]
b53c3b84e2 Update Rust crate async-compat to v0.2.4 (#15143)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [async-compat](https://togithub.com/smol-rs/async-compat) |
dependencies | patch | `0.2.1` -> `0.2.4` |

---

### Release Notes

<details>
<summary>smol-rs/async-compat (async-compat)</summary>

###
[`v0.2.4`](https://togithub.com/smol-rs/async-compat/blob/HEAD/CHANGELOG.md#Version-024)

[Compare
Source](https://togithub.com/smol-rs/async-compat/compare/v0.2.3...v0.2.4)

- Derive `Clone` for `Compat`.
([#&#8203;27](https://togithub.com/smol-rs/async-compat/issues/27))
- Rather than spawning our own `tokio` runtime all of the time, reuse an
existing runtime if possible.
([#&#8203;30](https://togithub.com/smol-rs/async-compat/issues/30))

###
[`v0.2.3`](https://togithub.com/smol-rs/async-compat/blob/HEAD/CHANGELOG.md#Version-023)

[Compare
Source](https://togithub.com/smol-rs/async-compat/compare/v0.2.2...v0.2.3)

- Enter the `tokio` context while dropping wrapped `tokio` types.
([#&#8203;22](https://togithub.com/smol-rs/async-compat/issues/22))

###
[`v0.2.2`](https://togithub.com/smol-rs/async-compat/blob/HEAD/CHANGELOG.md#Version-022)

[Compare
Source](https://togithub.com/smol-rs/async-compat/compare/v0.2.1...v0.2.2)

- Add `smol-rs` logo to the docs.
([#&#8203;19](https://togithub.com/smol-rs/async-compat/issues/19))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-24 23:33:02 -04:00
renovate[bot]
3d6b07d78c Update Rust crate derive_more to v0.99.18 (#15144)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [derive_more](https://togithub.com/JelteF/derive_more) |
workspace.dependencies | patch | `0.99.17` -> `0.99.18` |

---

### Release Notes

<details>
<summary>JelteF/derive_more (derive_more)</summary>

###
[`v0.99.18`](https://togithub.com/JelteF/derive_more/compare/v0.99.17...v0.99.18)

[Compare
Source](https://togithub.com/JelteF/derive_more/compare/v0.99.17...v0.99.18)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

Release Notes:

- N/A

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-24 23:31:40 -04:00
Marshall Bowers
4c0d0ad4f4 renovate: Add release notes to PR footer (#15145)
This PR updates the Renovate config to place the "Release Notes" section
in the PR body footer.

Also removed the `cla-signed` label, because the CLA bot just removes
it.

Release Notes:

- N/A
2024-07-24 23:18:33 -04:00
renovate[bot]
55575ca830 Update Rust crate aho-corasick to v1.1.3 (#15137)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [aho-corasick](https://togithub.com/BurntSushi/aho-corasick) |
workspace.dependencies | patch | `1.1.1` -> `1.1.3` |

---

### Release Notes

<details>
<summary>BurntSushi/aho-corasick (aho-corasick)</summary>

###
[`v1.1.3`](https://togithub.com/BurntSushi/aho-corasick/compare/1.1.2...1.1.3)

[Compare
Source](https://togithub.com/BurntSushi/aho-corasick/compare/1.1.2...1.1.3)

###
[`v1.1.2`](https://togithub.com/BurntSushi/aho-corasick/compare/1.1.1...1.1.2)

[Compare
Source](https://togithub.com/BurntSushi/aho-corasick/compare/1.1.1...1.1.2)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 3pm on Wednesday" in timezone
America/New_York, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/zed-industries/zed).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MzguMCIsInVwZGF0ZWRJblZlciI6IjM3LjQzOC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJjbGEtc2lnbmVkIl19-->

Release Notes:

- N/A

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-24 23:01:55 -04:00
Marshall Bowers
ea44af4a85 Upgrade anyhow to v1.0.86 (#15140)
This PR upgrades `anyhow` to v1.0.86.

Release Notes:

- N/A
2024-07-24 22:54:02 -04:00
Marshall Bowers
5865c5e80f Update Renovate config (#15141)
This PR applies some further updates to the Renovate config.

We add the https://github.com/zed-industries/zed/labels/cla-signed label
to the PRs so that check passes.

Also seeing if we can add a "Release Notes" sections to Renovate PRs.

Release Notes:

- N/A
2024-07-24 22:51:51 -04:00
renovate[bot]
51f8013616 Configure Renovate (#15132)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

Welcome to [Renovate](https://togithub.com/renovatebot/renovate)! This
is an onboarding PR to help you understand and configure settings before
regular Pull Requests begin.

🚦 To activate Renovate, merge this Pull Request. To disable Renovate,
simply close this Pull Request unmerged.



---
### Detected Package Files

 * `Cargo.toml` (cargo)
 * `crates/activity_indicator/Cargo.toml` (cargo)
 * `crates/anthropic/Cargo.toml` (cargo)
 * `crates/assets/Cargo.toml` (cargo)
 * `crates/assistant/Cargo.toml` (cargo)
 * `crates/assistant_slash_command/Cargo.toml` (cargo)
 * `crates/assistant_tooling/Cargo.toml` (cargo)
 * `crates/audio/Cargo.toml` (cargo)
 * `crates/auto_update/Cargo.toml` (cargo)
 * `crates/breadcrumbs/Cargo.toml` (cargo)
 * `crates/call/Cargo.toml` (cargo)
 * `crates/channel/Cargo.toml` (cargo)
 * `crates/cli/Cargo.toml` (cargo)
 * `crates/client/Cargo.toml` (cargo)
 * `crates/clock/Cargo.toml` (cargo)
 * `crates/collab/Cargo.toml` (cargo)
 * `crates/collab_ui/Cargo.toml` (cargo)
 * `crates/collections/Cargo.toml` (cargo)
 * `crates/command_palette/Cargo.toml` (cargo)
 * `crates/command_palette_hooks/Cargo.toml` (cargo)
 * `crates/completion/Cargo.toml` (cargo)
 * `crates/copilot/Cargo.toml` (cargo)
 * `crates/db/Cargo.toml` (cargo)
 * `crates/dev_server_projects/Cargo.toml` (cargo)
 * `crates/diagnostics/Cargo.toml` (cargo)
 * `crates/editor/Cargo.toml` (cargo)
 * `crates/extension/Cargo.toml` (cargo)
 * `crates/extension_api/Cargo.toml` (cargo)
 * `crates/extension_cli/Cargo.toml` (cargo)
 * `crates/extensions_ui/Cargo.toml` (cargo)
 * `crates/feature_flags/Cargo.toml` (cargo)
 * `crates/feedback/Cargo.toml` (cargo)
 * `crates/file_finder/Cargo.toml` (cargo)
 * `crates/file_icons/Cargo.toml` (cargo)
 * `crates/fs/Cargo.toml` (cargo)
 * `crates/fsevent/Cargo.toml` (cargo)
 * `crates/fuzzy/Cargo.toml` (cargo)
 * `crates/git/Cargo.toml` (cargo)
 * `crates/git_hosting_providers/Cargo.toml` (cargo)
 * `crates/go_to_line/Cargo.toml` (cargo)
 * `crates/google_ai/Cargo.toml` (cargo)
 * `crates/gpui/Cargo.toml` (cargo)
 * `crates/gpui_macros/Cargo.toml` (cargo)
 * `crates/headless/Cargo.toml` (cargo)
 * `crates/html_to_markdown/Cargo.toml` (cargo)
 * `crates/http_client/Cargo.toml` (cargo)
 * `crates/image_viewer/Cargo.toml` (cargo)
 * `crates/indexed_docs/Cargo.toml` (cargo)
 * `crates/inline_completion_button/Cargo.toml` (cargo)
 * `crates/install_cli/Cargo.toml` (cargo)
 * `crates/journal/Cargo.toml` (cargo)
 * `crates/language/Cargo.toml` (cargo)
 * `crates/language_model/Cargo.toml` (cargo)
 * `crates/language_selector/Cargo.toml` (cargo)
 * `crates/language_tools/Cargo.toml` (cargo)
 * `crates/languages/Cargo.toml` (cargo)
 * `crates/live_kit_client/Cargo.toml` (cargo)
 * `crates/live_kit_server/Cargo.toml` (cargo)
 * `crates/lsp/Cargo.toml` (cargo)
 * `crates/markdown/Cargo.toml` (cargo)
 * `crates/markdown_preview/Cargo.toml` (cargo)
 * `crates/media/Cargo.toml` (cargo)
 * `crates/menu/Cargo.toml` (cargo)
 * `crates/multi_buffer/Cargo.toml` (cargo)
 * `crates/node_runtime/Cargo.toml` (cargo)
 * `crates/notifications/Cargo.toml` (cargo)
 * `crates/ollama/Cargo.toml` (cargo)
 * `crates/open_ai/Cargo.toml` (cargo)
 * `crates/outline/Cargo.toml` (cargo)
 * `crates/outline_panel/Cargo.toml` (cargo)
 * `crates/paths/Cargo.toml` (cargo)
 * `crates/picker/Cargo.toml` (cargo)
 * `crates/prettier/Cargo.toml` (cargo)
 * `crates/project/Cargo.toml` (cargo)
 * `crates/project_panel/Cargo.toml` (cargo)
 * `crates/project_symbols/Cargo.toml` (cargo)
 * `crates/proto/Cargo.toml` (cargo)
 * `crates/quick_action_bar/Cargo.toml` (cargo)
 * `crates/recent_projects/Cargo.toml` (cargo)
 * `crates/refineable/Cargo.toml` (cargo)
 * `crates/refineable/derive_refineable/Cargo.toml` (cargo)
 * `crates/release_channel/Cargo.toml` (cargo)
 * `crates/remote/Cargo.toml` (cargo)
 * `crates/remote_server/Cargo.toml` (cargo)
 * `crates/repl/Cargo.toml` (cargo)
 * `crates/rich_text/Cargo.toml` (cargo)
 * `crates/rope/Cargo.toml` (cargo)
 * `crates/rpc/Cargo.toml` (cargo)
 * `crates/search/Cargo.toml` (cargo)
 * `crates/semantic_index/Cargo.toml` (cargo)
 * `crates/semantic_version/Cargo.toml` (cargo)
 * `crates/session/Cargo.toml` (cargo)
 * `crates/settings/Cargo.toml` (cargo)
 * `crates/settings_ui/Cargo.toml` (cargo)
 * `crates/snippet/Cargo.toml` (cargo)
 * `crates/snippet_provider/Cargo.toml` (cargo)
 * `crates/sqlez/Cargo.toml` (cargo)
 * `crates/sqlez_macros/Cargo.toml` (cargo)
 * `crates/story/Cargo.toml` (cargo)
 * `crates/storybook/Cargo.toml` (cargo)
 * `crates/sum_tree/Cargo.toml` (cargo)
 * `crates/supermaven/Cargo.toml` (cargo)
 * `crates/supermaven_api/Cargo.toml` (cargo)
 * `crates/tab_switcher/Cargo.toml` (cargo)
 * `crates/task/Cargo.toml` (cargo)
 * `crates/tasks_ui/Cargo.toml` (cargo)
 * `crates/telemetry_events/Cargo.toml` (cargo)
 * `crates/terminal/Cargo.toml` (cargo)
 * `crates/terminal_view/Cargo.toml` (cargo)
 * `crates/text/Cargo.toml` (cargo)
 * `crates/theme/Cargo.toml` (cargo)
 * `crates/theme_importer/Cargo.toml` (cargo)
 * `crates/theme_selector/Cargo.toml` (cargo)
 * `crates/time_format/Cargo.toml` (cargo)
 * `crates/title_bar/Cargo.toml` (cargo)
 * `crates/ui/Cargo.toml` (cargo)
 * `crates/ui_input/Cargo.toml` (cargo)
 * `crates/util/Cargo.toml` (cargo)
 * `crates/vcs_menu/Cargo.toml` (cargo)
 * `crates/vim/Cargo.toml` (cargo)
 * `crates/welcome/Cargo.toml` (cargo)
 * `crates/workspace/Cargo.toml` (cargo)
 * `crates/worktree/Cargo.toml` (cargo)
 * `crates/zed/Cargo.toml` (cargo)
 * `crates/zed_actions/Cargo.toml` (cargo)
 * `extensions/astro/Cargo.toml` (cargo)
 * `extensions/clojure/Cargo.toml` (cargo)
 * `extensions/csharp/Cargo.toml` (cargo)
 * `extensions/dart/Cargo.toml` (cargo)
 * `extensions/deno/Cargo.toml` (cargo)
 * `extensions/elixir/Cargo.toml` (cargo)
 * `extensions/elm/Cargo.toml` (cargo)
 * `extensions/emmet/Cargo.toml` (cargo)
 * `extensions/erlang/Cargo.toml` (cargo)
 * `extensions/gleam/Cargo.toml` (cargo)
 * `extensions/glsl/Cargo.toml` (cargo)
 * `extensions/haskell/Cargo.toml` (cargo)
 * `extensions/html/Cargo.toml` (cargo)
 * `extensions/lua/Cargo.toml` (cargo)
 * `extensions/ocaml/Cargo.toml` (cargo)
 * `extensions/php/Cargo.toml` (cargo)
 * `extensions/prisma/Cargo.toml` (cargo)
 * `extensions/purescript/Cargo.toml` (cargo)
 * `extensions/ruby/Cargo.toml` (cargo)
 * `extensions/ruff/Cargo.toml` (cargo)
 * `extensions/snippets/Cargo.toml` (cargo)
 * `extensions/svelte/Cargo.toml` (cargo)
 * `extensions/terraform/Cargo.toml` (cargo)
 * `extensions/test-extension/Cargo.toml` (cargo)
 * `extensions/toml/Cargo.toml` (cargo)
 * `extensions/uiua/Cargo.toml` (cargo)
 * `extensions/vue/Cargo.toml` (cargo)
 * `extensions/zig/Cargo.toml` (cargo)
 * `tooling/xtask/Cargo.toml` (cargo)
 * `compose.yml` (docker-compose)
 * `Dockerfile` (dockerfile)
 * `.github/actions/run_tests/action.yml` (github-actions)
 * `.github/workflows/bump_patch_version.yml` (github-actions)
 * `.github/workflows/ci.yml` (github-actions)
 * `.github/workflows/danger.yml` (github-actions)
 * `.github/workflows/deploy_cloudflare.yml` (github-actions)
 * `.github/workflows/deploy_collab.yml` (github-actions)
 * `.github/workflows/publish_extension_cli.yml` (github-actions)
 * `.github/workflows/randomized_tests.yml` (github-actions)
 * `.github/workflows/release_actions.yml` (github-actions)
 * `.github/workflows/release_nightly.yml` (github-actions)
* `.github/workflows/update_all_top_ranking_issues.yml` (github-actions)
* `.github/workflows/update_weekly_top_ranking_issues.yml`
(github-actions)
 * `script/danger/package.json` (npm)
 * `script/update_top_ranking_issues/pyproject.toml` (pep621)
* `script/update_top_ranking_issues/requirements.txt` (pip_requirements)
 * `script/update_top_ranking_issues/pyproject.toml` (poetry)
 * `crates/live_kit_client/LiveKitBridge/Package.swift` (swift)

### Configuration Summary

Based on the default config's presets, Renovate will:

  - Start dependency updates only once this onboarding PR is merged
  - Show all Merge Confidence badges for pull requests.
  - Enable Renovate Dependency Dashboard creation.
- Use semantic commit type `fix` for dependencies and `chore` for all
others if semantic commits are in use.
- Ignore `node_modules`, `bower_components`, `vendor` and various
test/tests directories.
  - Group known monorepo packages together.
  - Use curated list of recommended non-monorepo package groupings.
  - Apply crowd-sourced package replacement rules.
  - Apply crowd-sourced workarounds for known problems with packages.
  - Disable semantic prefixes for commit messages and PR titles.
  - Run Renovate on following schedule: after 3pm on Wednesday

🔡 Do you want to change how Renovate upgrades your dependencies? Add
your custom config to `renovate.json` in this branch. Renovate will
update the Pull Request description the next time it runs.

---

### What to Expect

With your current configuration, Renovate will create 144 Pull Requests:

<details>
<summary>Update Python to v3.12.4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/python-3.x`
  - Merge into: `main`
- Upgrade [python](https://togithub.com/containerbase/python-prebuild)
to `3.12.4`


</details>

<details>
<summary>Update Rust crate aho-corasick to v1.1.3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/aho-corasick-1.x-lockfile`
  - Merge into: `main`
- Upgrade [aho-corasick](https://togithub.com/BurntSushi/aho-corasick)
to `1.1.3`


</details>

<details>
<summary>Update Rust crate anyhow to v1.0.86</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/anyhow-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [anyhow](https://togithub.com/dtolnay/anyhow) to `1.0.86`


</details>

<details>
<summary>Update Rust crate async-broadcast to v0.7.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-broadcast-0.x-lockfile`
  - Merge into: `main`
- Upgrade
[async-broadcast](https://togithub.com/smol-rs/async-broadcast) to
`0.7.1`


</details>

<details>
<summary>Update Rust crate async-compat to v0.2.4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-compat-0.x-lockfile`
  - Merge into: `main`
- Upgrade [async-compat](https://togithub.com/smol-rs/async-compat) to
`0.2.4`


</details>

<details>
<summary>Update Rust crate async-compression to v0.4.12</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-compression-0.x-lockfile`
  - Merge into: `main`
- Upgrade
[async-compression](https://togithub.com/Nullus157/async-compression) to
`0.4.12`


</details>

<details>
<summary>Update Rust crate async-task to v4.7.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-task-4.x-lockfile`
  - Merge into: `main`
- Upgrade [async-task](https://togithub.com/smol-rs/async-task) to
`4.7.1`


</details>

<details>
<summary>Update Rust crate async-trait to v0.1.81</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-trait-0.x-lockfile`
  - Merge into: `main`
- Upgrade [async-trait](https://togithub.com/dtolnay/async-trait) to
`0.1.81`


</details>

<details>
<summary>Update Rust crate backtrace to v0.3.73</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/backtrace-0.x-lockfile`
  - Merge into: `main`
- Upgrade [backtrace](https://togithub.com/rust-lang/backtrace-rs) to
`0.3.73`


</details>

<details>
<summary>Update Rust crate cargo_toml to v0.20.4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/cargo_toml-0.x-lockfile`
  - Merge into: `main`
- Upgrade [cargo_toml](https://gitlab.com/lib.rs/cargo_toml) to `0.20.4`


</details>

<details>
<summary>Update Rust crate core-graphics to v0.23.2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/core-graphics-0.x-lockfile`
  - Merge into: `main`
- Upgrade [core-graphics](https://togithub.com/servo/core-foundation-rs)
to `0.23.2`


</details>

<details>
<summary>Update Rust crate ctor to v0.2.8</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/ctor-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [ctor](https://togithub.com/mmastrac/rust-ctor) to `0.2.8`


</details>

<details>
<summary>Update Rust crate derive_more to v0.99.18</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/derive_more-0.x-lockfile`
  - Merge into: `main`
- Upgrade [derive_more](https://togithub.com/JelteF/derive_more) to
`0.99.18`


</details>

<details>
<summary>Update Rust crate embed-resource to v2.4.3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/embed-resource-2.x-lockfile`
  - Merge into: `main`
- Upgrade
[embed-resource](https://togithub.com/nabijaczleweli/rust-embed-resource)
to `2.4.3`


</details>

<details>
<summary>Update Rust crate emojis to v0.6.3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/emojis-0.x-lockfile`
  - Merge into: `main`
- Upgrade [emojis](https://togithub.com/rossmacarthur/emojis) to `0.6.3`


</details>

<details>
<summary>Update Rust crate etagere to v0.2.13</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/etagere-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [etagere](https://togithub.com/nical/etagere) to `0.2.13`


</details>

<details>
<summary>Update Rust crate futures to v0.3.30</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/rust-futures-monorepo`
  - Merge into: `main`
- Upgrade [futures](https://togithub.com/rust-lang/futures-rs) to
`0.3.30`


</details>

<details>
<summary>Update Rust crate heed to v0.20.3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/heed-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [heed](https://togithub.com/Kerollmops/heed) to `0.20.3`


</details>

<details>
<summary>Update Rust crate image to v0.25.2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/image-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [image](https://togithub.com/image-rs/image) to `0.25.2`


</details>

<details>
<summary>Update Rust crate ipc-channel to v0.18.2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/ipc-channel-0.x-lockfile`
  - Merge into: `main`
- Upgrade [ipc-channel](https://togithub.com/servo/ipc-channel) to
`0.18.2`


</details>

<details>
<summary>Update Rust crate libc to v0.2.155</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/libc-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [libc](https://togithub.com/rust-lang/libc) to `0.2.155`


</details>

<details>
<summary>Update Rust crate linkme to v0.3.27</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/linkme-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [linkme](https://togithub.com/dtolnay/linkme) to `0.3.27`


</details>

<details>
<summary>Update Rust crate log to v0.4.22</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/log-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [log](https://togithub.com/rust-lang/log) to `0.4.22`


</details>

<details>
<summary>Update Rust crate mimalloc to v0.1.43</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/mimalloc-0.x-lockfile`
  - Merge into: `main`
- Upgrade [mimalloc](https://togithub.com/purpleprotocol/mimalloc_rust)
to `0.1.43`


</details>

<details>
<summary>Update Rust crate oo7 to v0.3.3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/oo7-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [oo7](https://togithub.com/bilelmoussaoui/oo7) to `0.3.3`


</details>

<details>
<summary>Update Rust crate ordered-float to v2.10.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/ordered-float-2.x-lockfile`
  - Merge into: `main`
- Upgrade [ordered-float](https://togithub.com/reem/rust-ordered-float)
to `2.10.1`


</details>

<details>
<summary>Update Rust crate palette to v0.7.6</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/palette-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [palette](https://togithub.com/Ogeon/palette) to `0.7.6`


</details>

<details>
<summary>Update Rust crate parking_lot to v0.12.3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/parking_lot-0.x-lockfile`
  - Merge into: `main`
- Upgrade [parking_lot](https://togithub.com/Amanieu/parking_lot) to
`0.12.3`


</details>

<details>
<summary>Update Rust crate proc-macro2 to v1.0.86</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/proc-macro2-1.x-lockfile`
  - Merge into: `main`
- Upgrade [proc-macro2](https://togithub.com/dtolnay/proc-macro2) to
`1.0.86`


</details>

<details>
<summary>Update Rust crate prometheus to v0.13.4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/prometheus-0.x-lockfile`
  - Merge into: `main`
- Upgrade [prometheus](https://togithub.com/tikv/rust-prometheus) to
`0.13.4`


</details>

<details>
<summary>Update Rust crate quote to v1.0.36</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/quote-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [quote](https://togithub.com/dtolnay/quote) to `1.0.36`


</details>

<details>
<summary>Update Rust crate raw-window-handle to v0.6.2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/raw-window-handle-0.x-lockfile`
  - Merge into: `main`
- Upgrade
[raw-window-handle](https://togithub.com/rust-windowing/raw-window-handle)
to `0.6.2`


</details>

<details>
<summary>Update Rust crate rustc-demangle to v0.1.24</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/rustc-demangle-0.x-lockfile`
  - Merge into: `main`
- Upgrade
[rustc-demangle](https://togithub.com/rust-lang/rustc-demangle) to
`0.1.24`


</details>

<details>
<summary>Update Rust crate schemars to v0.8.21</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/schemars-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [schemars](https://togithub.com/GREsau/schemars) to `0.8.21`


</details>

<details>
<summary>Update Rust crate sea-orm to v0.12.15</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/sea-orm-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [sea-orm](https://togithub.com/SeaQL/sea-orm) to `0.12.15`


</details>

<details>
<summary>Update Rust crate semver to v1.0.23</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/semver-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [semver](https://togithub.com/dtolnay/semver) to `1.0.23`


</details>

<details>
<summary>Update Rust crate serde_json to v1.0.120</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/serde_json-1.x-lockfile`
  - Merge into: `main`
- Upgrade [serde_json](https://togithub.com/serde-rs/json) to `1.0.120`


</details>

<details>
<summary>Update Rust crate serde_repr to v0.1.19</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/serde_repr-0.x-lockfile`
  - Merge into: `main`
- Upgrade [serde_repr](https://togithub.com/dtolnay/serde-repr) to
`0.1.19`


</details>

<details>
<summary>Update Rust crate sha2 to v0.10.8</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/sha2-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [sha2](https://togithub.com/RustCrypto/hashes) to `0.10.8`


</details>

<details>
<summary>Update Rust crate slotmap to v1.0.7</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/slotmap-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [slotmap](https://togithub.com/orlp/slotmap) to `1.0.7`


</details>

<details>
<summary>Update Rust crate sqlformat to v0.2.4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/sqlformat-0.x-lockfile`
  - Merge into: `main`
- Upgrade [sqlformat](https://togithub.com/shssoichiro/sqlformat-rs) to
`0.2.4`


</details>

<details>
<summary>Update Rust crate sysinfo to v0.30.13</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/sysinfo-0.x-lockfile`
  - Merge into: `main`
- Upgrade [sysinfo](https://togithub.com/GuillaumeGomez/sysinfo) to
`0.30.13`


</details>

<details>
<summary>Update Rust crate thiserror to v1.0.63</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/thiserror-1.x-lockfile`
  - Merge into: `main`
- Upgrade [thiserror](https://togithub.com/dtolnay/thiserror) to
`1.0.63`


</details>

<details>
<summary>Update Rust crate thread_local to v1.1.8</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/thread_local-1.x-lockfile`
  - Merge into: `main`
- Upgrade [thread_local](https://togithub.com/Amanieu/thread_local-rs)
to `1.1.8`


</details>

<details>
<summary>Update Rust crate toml to v0.8.15</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/toml-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [toml](https://togithub.com/toml-rs/toml) to `0.8.15`


</details>

<details>
<summary>Update Rust crate url to v2.5.2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/url-2.x-lockfile`
  - Merge into: `main`
  - Upgrade [url](https://togithub.com/servo/rust-url) to `2.5.2`


</details>

<details>
<summary>Update Rust crate wayland-backend to v0.3.6</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wayland-backend-0.x-lockfile`
  - Merge into: `main`
- Upgrade [wayland-backend](https://togithub.com/smithay/wayland-rs) to
`0.3.6`


</details>

<details>
<summary>Update Rust crate wayland-client to v0.31.5</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wayland-client-0.x-lockfile`
  - Merge into: `main`
- Upgrade [wayland-client](https://togithub.com/smithay/wayland-rs) to
`0.31.5`


</details>

<details>
<summary>Update Rust crate wayland-cursor to v0.31.5</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wayland-cursor-0.x-lockfile`
  - Merge into: `main`
- Upgrade [wayland-cursor](https://togithub.com/smithay/wayland-rs) to
`0.31.5`


</details>

<details>
<summary>Update Rust crate which to v6.0.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/which-6.x-lockfile`
  - Merge into: `main`
  - Upgrade [which](https://togithub.com/harryfei/which-rs) to `6.0.1`


</details>

<details>
<summary>Update Rust crate x11rb to v0.13.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/x11rb-0.x-lockfile`
  - Merge into: `main`
  - Upgrade [x11rb](https://togithub.com/psychon/x11rb) to `0.13.1`


</details>

<details>
<summary>Update Rust crate zed_extension_api to 0.0.6</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/zed_extension_api-0.x`
  - Merge into: `main`
- Upgrade [zed_extension_api](https://togithub.com/zed-industries/zed)
to `0.0.6`


</details>

<details>
<summary>Update serde monorepo to v1.0.204</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/serde-monorepo`
  - Merge into: `main`
  - Upgrade [serde](https://togithub.com/serde-rs/serde) to `1.0.204`
- Upgrade [serde_derive](https://togithub.com/serde-rs/serde) to
`1.0.204`


</details>

<details>
<summary>Update 2428392/gh-truncate-string-action action to
v1.4.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/2428392-gh-truncate-string-action-1.x`
  - Merge into: `main`
- Upgrade
[2428392/gh-truncate-string-action](https://togithub.com/2428392/gh-truncate-string-action)
to `v1.4.0`


</details>

<details>
<summary>Update Rust crate alacritty_terminal to 0.24</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/alacritty_terminal-0.x`
  - Merge into: `main`
- Upgrade [alacritty_terminal](https://togithub.com/alacritty/alacritty)
to `0.24`


</details>

<details>
<summary>Update Rust crate any_vec to 0.14</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/any_vec-0.x`
  - Merge into: `main`
  - Upgrade [any_vec](https://togithub.com/tower120/any_vec) to `0.14`


</details>

<details>
<summary>Update Rust crate async-recursion to v1.1.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-recursion-1.x-lockfile`
  - Merge into: `main`
- Upgrade [async-recursion](https://togithub.com/dcchut/async-recursion)
to `1.1.1`


</details>

<details>
<summary>Update Rust crate async-tungstenite to 0.27</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-tungstenite-0.x`
  - Merge into: `main`
- Upgrade
[async-tungstenite](https://togithub.com/sdroege/async-tungstenite) to
`0.27`


</details>

<details>
<summary>Update Rust crate axum to 0.7</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/axum-0.x`
  - Merge into: `main`
  - Upgrade [axum](https://togithub.com/tokio-rs/axum) to `0.7`


</details>

<details>
<summary>Update Rust crate axum-extra to 0.9</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/axum-extra-0.x`
  - Merge into: `main`
  - Upgrade [axum-extra](https://togithub.com/tokio-rs/axum) to `0.9`


</details>

<details>
<summary>Update Rust crate base64 to 0.22</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/base64-0.x`
  - Merge into: `main`
- Upgrade [base64](https://togithub.com/marshallpierce/rust-base64) to
`0.22`


</details>

<details>
<summary>Update Rust crate bindgen to 0.69.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/bindgen-0.x`
  - Merge into: `main`
- Upgrade [bindgen](https://togithub.com/rust-lang/rust-bindgen) to
`0.69.0`


</details>

<details>
<summary>Update Rust crate bytemuck to v1.16.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/bytemuck-1.x-lockfile`
  - Merge into: `main`
- Upgrade [bytemuck](https://togithub.com/Lokathor/bytemuck) to `1.16.1`


</details>

<details>
<summary>Update Rust crate calloop to 0.14.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/calloop-0.x`
  - Merge into: `main`
  - Upgrade [calloop](https://togithub.com/Smithay/calloop) to `0.14.0`


</details>

<details>
<summary>Update Rust crate cap-std to v3.2.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/cap-std-3.x-lockfile`
  - Merge into: `main`
- Upgrade [cap-std](https://togithub.com/bytecodealliance/cap-std) to
`3.2.0`


</details>

<details>
<summary>Update Rust crate clap to v4.5.10</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/clap-4.x-lockfile`
  - Merge into: `main`
  - Upgrade [clap](https://togithub.com/clap-rs/clap) to `4.5.10`


</details>

<details>
<summary>Update Rust crate clickhouse to 0.12.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/clickhouse-0.x`
  - Merge into: `main`
- Upgrade [clickhouse](https://togithub.com/loyd/clickhouse.rs) to
`0.12.0`


</details>

<details>
<summary>Update Rust crate env_logger to 0.11</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/env_logger-0.x`
  - Merge into: `main`
- Upgrade [env_logger](https://togithub.com/rust-cli/env_logger) to
`0.11`


</details>

<details>
<summary>Update Rust crate fork to 0.2.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/fork-0.x`
  - Merge into: `main`
  - Upgrade [fork](https://togithub.com/immortal/fork) to `0.2.0`


</details>

<details>
<summary>Update Rust crate http to v1.1.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/http-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [http](https://togithub.com/hyperium/http) to `1.1.0`


</details>

<details>
<summary>Update Rust crate itertools to v0.13.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/itertools-0.x`
  - Merge into: `main`
- Upgrade [itertools](https://togithub.com/rust-itertools/itertools) to
`0.13`
- Upgrade [itertools](https://togithub.com/rust-itertools/itertools) to
`0.13.0`


</details>

<details>
<summary>Update Rust crate lazy_static to v1.5.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/lazy_static-1.x-lockfile`
  - Merge into: `main`
- Upgrade
[lazy_static](https://togithub.com/rust-lang-nursery/lazy-static.rs) to
`1.5.0`


</details>

<details>
<summary>Update Rust crate libsqlite3-sys to 0.30</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/libsqlite3-sys-0.x`
  - Merge into: `main`
- Upgrade [libsqlite3-sys](https://togithub.com/rusqlite/rusqlite) to
`0.30`


</details>

<details>
<summary>Update Rust crate nix to 0.29</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/nix-0.x`
  - Merge into: `main`
  - Upgrade [nix](https://togithub.com/nix-rust/nix) to `0.29`


</details>

<details>
<summary>Update Rust crate pulldown-cmark to 0.11.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/pulldown-cmark-0.x`
  - Merge into: `main`
- Upgrade
[pulldown-cmark](https://togithub.com/raphlinus/pulldown-cmark) to
`0.11.0`


</details>

<details>
<summary>Update Rust crate rayon to v1.10.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/rayon-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [rayon](https://togithub.com/rayon-rs/rayon) to `1.10.0`


</details>

<details>
<summary>Update Rust crate reqwest to 0.12</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/reqwest-0.x`
  - Merge into: `main`
- Upgrade [reqwest](https://togithub.com/seanmonstar/reqwest) to `0.12`


</details>

<details>
<summary>Update Rust crate resvg to 0.42.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/resvg-0.x`
  - Merge into: `main`
  - Upgrade [resvg](https://togithub.com/RazrFalcon/resvg) to `0.42.0`


</details>

<details>
<summary>Update Rust crate rodio to 0.19.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/rodio-0.x`
  - Merge into: `main`
  - Upgrade [rodio](https://togithub.com/RustAudio/rodio) to `0.19.0`


</details>

<details>
<summary>Update Rust crate runtimelib to 0.13</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/runtimelib-0.x`
  - Merge into: `main`
  - Upgrade runtimelib to `0.13`


</details>

<details>
<summary>Update Rust crate rusqlite to 0.32.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/rusqlite-0.x`
  - Merge into: `main`
- Upgrade [rusqlite](https://togithub.com/rusqlite/rusqlite) to `0.32.0`


</details>

<details>
<summary>Update Rust crate rust-embed to v8.5.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/rust-embed-8.x-lockfile`
  - Merge into: `main`
- Upgrade [rust-embed](https://togithub.com/pyros2097/rust-embed) to
`8.5.0`


</details>

<details>
<summary>Update Rust crate scrypt to 0.11</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/scrypt-0.x`
  - Merge into: `main`
- Upgrade [scrypt](https://togithub.com/RustCrypto/password-hashes) to
`0.11`


</details>

<details>
<summary>Update Rust crate serde_json_lenient to 0.2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/serde_json_lenient-0.x`
  - Merge into: `main`
- Upgrade
[serde_json_lenient](https://togithub.com/google/serde_json_lenient) to
`0.2`


</details>

<details>
<summary>Update Rust crate smallvec to v1.13.2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/smallvec-1.x-lockfile`
  - Merge into: `main`
- Upgrade [smallvec](https://togithub.com/servo/rust-smallvec) to
`1.13.2`


</details>

<details>
<summary>Update Rust crate sqlx to 0.8</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/sqlx-0.x`
  - Merge into: `main`
  - Upgrade [sqlx](https://togithub.com/launchbadge/sqlx) to `0.8`


</details>

<details>
<summary>Update Rust crate strum to 0.26.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/strum-monorepo`
  - Merge into: `main`
  - Upgrade [strum](https://togithub.com/Peternator7/strum) to `0.26.0`


</details>

<details>
<summary>Update Rust crate subtle to v2.6.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/subtle-2.x-lockfile`
  - Merge into: `main`
- Upgrade [subtle](https://togithub.com/dalek-cryptography/subtle) to
`2.6.1`


</details>

<details>
<summary>Update Rust crate taffy to 0.5.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/taffy-0.x`
  - Merge into: `main`
  - Upgrade [taffy](https://togithub.com/DioxusLabs/taffy) to `0.5.0`


</details>

<details>
<summary>Update Rust crate tempfile to v3.10.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tempfile-3.x-lockfile`
  - Merge into: `main`
- Upgrade [tempfile](https://togithub.com/Stebalien/tempfile) to
`3.10.1`


</details>

<details>
<summary>Update Rust crate tiny_http to 0.12</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tiny_http-0.x`
  - Merge into: `main`
- Upgrade [tiny_http](https://togithub.com/tiny-http/tiny-http) to
`0.12`


</details>

<details>
<summary>Update Rust crate tokio to v1.39.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tokio-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [tokio](https://togithub.com/tokio-rs/tokio) to `1.39.1`


</details>

<details>
<summary>Update Rust crate tower-http to 0.5.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tower-http-0.x`
  - Merge into: `main`
- Upgrade [tower-http](https://togithub.com/tower-rs/tower-http) to
`0.5.0`


</details>

<details>
<summary>Update Rust crate tree-sitter-embedded-template to
0.21.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tree-sitter-embedded-template-0.x`
  - Merge into: `main`
- Upgrade
[tree-sitter-embedded-template](https://togithub.com/tree-sitter/tree-sitter-embedded-template)
to `0.21.0`


</details>

<details>
<summary>Update Rust crate unicode-segmentation to v1.11.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/unicode-segmentation-1.x-lockfile`
  - Merge into: `main`
- Upgrade
[unicode-segmentation](https://togithub.com/unicode-rs/unicode-segmentation)
to `1.11.0`


</details>

<details>
<summary>Update Rust crate unindent to 0.2.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/unindent-0.x`
  - Merge into: `main`
  - Upgrade [unindent](https://togithub.com/dtolnay/indoc) to `0.2.0`


</details>

<details>
<summary>Update Rust crate usvg to 0.42.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/usvg-0.x`
  - Merge into: `main`
  - Upgrade [usvg](https://togithub.com/RazrFalcon/resvg) to `0.42.0`


</details>

<details>
<summary>Update Rust crate uuid to v1.10.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/uuid-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [uuid](https://togithub.com/uuid-rs/uuid) to `1.10.0`


</details>

<details>
<summary>Update Rust crate waker-fn to v1.2.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/waker-fn-1.x-lockfile`
  - Merge into: `main`
  - Upgrade [waker-fn](https://togithub.com/smol-rs/waker-fn) to `1.2.0`


</details>

<details>
<summary>Update Rust crate wasm-encoder to 0.214</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wasm-encoder-0.x`
  - Merge into: `main`
- Upgrade
[wasm-encoder](https://togithub.com/bytecodealliance/wasm-tools) to
`0.214`


</details>

<details>
<summary>Update Rust crate wasmparser to 0.214</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wasmparser-0.x`
  - Merge into: `main`
- Upgrade [wasmparser](https://togithub.com/bytecodealliance/wasm-tools)
to `0.214`


</details>

<details>
<summary>Update Rust crate wayland-protocols to 0.32.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wayland-protocols-0.x`
  - Merge into: `main`
- Upgrade [wayland-protocols](https://togithub.com/smithay/wayland-rs)
to `0.32.0`


</details>

<details>
<summary>Update Rust crate wayland-protocols-plasma to 0.3.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wayland-protocols-plasma-0.x`
  - Merge into: `main`
- Upgrade
[wayland-protocols-plasma](https://togithub.com/smithay/wayland-rs) to
`0.3.0`


</details>

<details>
<summary>Update Rust crate windows to 0.58</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/windows-0.x`
  - Merge into: `main`
- Upgrade [windows](https://togithub.com/microsoft/windows-rs) to `0.58`


</details>

<details>
<summary>Update Rust crate windows-core to 0.58</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/windows-core-0.x`
  - Merge into: `main`
- Upgrade [windows-core](https://togithub.com/microsoft/windows-rs) to
`0.58`


</details>

<details>
<summary>Update Rust crate wit-bindgen to 0.28</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wit-bindgen-0.x`
  - Merge into: `main`
- Upgrade [wit-bindgen](https://togithub.com/bytecodealliance/wasi-rs)
to `0.28`


</details>

<details>
<summary>Update Rust crate wit-component to 0.214</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wit-component-0.x`
  - Merge into: `main`
- Upgrade
[wit-component](https://togithub.com/bytecodealliance/wasm-tools) to
`0.214`


</details>

<details>
<summary>Update Rust crate zstd to 0.13</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/zstd-0.x`
  - Merge into: `main`
  - Upgrade [zstd](https://togithub.com/gyscos/zstd-rs) to `0.13`


</details>

<details>
<summary>Update aws-sdk-rust monorepo</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/aws-sdk-rust-monorepo`
  - Merge into: `main`
- Upgrade [aws-config](https://togithub.com/smithy-lang/smithy-rs) to
`1.5.4`
- Upgrade [aws-sdk-s3](https://togithub.com/awslabs/aws-sdk-rust) to
`1.42.0`


</details>

<details>
<summary>Update dependency PyGithub to v1.59.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/pygithub-1.x`
  - Merge into: `main`
- Upgrade [PyGithub](https://togithub.com/pygithub/pygithub) to `1.59.1`


</details>

<details>
<summary>Update dependency livekit/client-sdk-swift to v1.1.6</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/livekit-client-sdk-swift-1.x`
  - Merge into: `main`
- Upgrade
[livekit/client-sdk-swift](https://togithub.com/livekit/client-sdk-swift)
to `1.1.6`


</details>

<details>
<summary>Update dependency mypy to v1.11.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/mypy-1.x`
  - Merge into: `main`
  - Upgrade [mypy](https://togithub.com/python/mypy) to `1.11.0`
  - Upgrade [mypy](https://togithub.com/python/mypy) to `==1.11.0`


</details>

<details>
<summary>Update dependency pytz to v2022.7.1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/pytz-2022.x`
  - Merge into: `main`
  - Upgrade pytz to `2022.7.1`
  - Upgrade pytz to `==2022.7.1`


</details>

<details>
<summary>Update dependency ruff to v0.5.4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/ruff-0.x`
  - Merge into: `main`
  - Upgrade [ruff](https://togithub.com/astral-sh/ruff) to `==0.5.4`


</details>

<details>
<summary>Update dependency typer to v0.12.3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/typer-0.x`
  - Merge into: `main`
  - Upgrade [typer](https://togithub.com/tiangolo/typer) to `0.12.3`
  - Upgrade [typer](https://togithub.com/tiangolo/typer) to `==0.12.3`


</details>

<details>
<summary>Update dependency types-pytz to v2023.4.0.20240130</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/types-pytz-2023.x`
  - Merge into: `main`
- Upgrade [types-pytz](https://togithub.com/python/typeshed) to
`2023.4.0.20240130`
- Upgrade [types-pytz](https://togithub.com/python/typeshed) to
`==2023.4.0.20240130`


</details>

<details>
<summary>Update docker/dockerfile Docker tag to v1.9</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/docker-dockerfile-1.x`
  - Merge into: `main`
  - Upgrade docker/dockerfile to `1.9`


</details>

<details>
<summary>Update tokio-prost monorepo to 0.13</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tokio-prost-monorepo`
  - Merge into: `main`
  - Upgrade [prost](https://togithub.com/tokio-rs/prost) to `0.13`
  - Upgrade [prost-build](https://togithub.com/tokio-rs/prost) to `0.13`
  - Upgrade [prost-types](https://togithub.com/tokio-rs/prost) to `0.13`


</details>

<details>
<summary>Update tsickert/discord-webhook action to v5.5.0</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tsickert-discord-webhook-5.x`
  - Merge into: `main`
- Upgrade
[tsickert/discord-webhook](https://togithub.com/tsickert/discord-webhook)
to `v5.5.0`


</details>

<details>
<summary>Update Rust crate async-fs to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-fs-2.x`
  - Merge into: `main`
  - Upgrade [async-fs](https://togithub.com/smol-rs/async-fs) to `2.0`


</details>

<details>
<summary>Update Rust crate async-recursion to v1</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/async-recursion-1.x`
  - Merge into: `main`
- Upgrade [async-recursion](https://togithub.com/dcchut/async-recursion)
to `1.0`


</details>

<details>
<summary>Update Rust crate dashmap to v6</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/dashmap-6.x`
  - Merge into: `main`
  - Upgrade [dashmap](https://togithub.com/xacrimon/dashmap) to `6.0`
  - Upgrade [dashmap](https://togithub.com/xacrimon/dashmap) to `6.0.0`


</details>

<details>
<summary>Update Rust crate dirs to v5</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/dirs-5.x`
  - Merge into: `main`
  - Upgrade [dirs](https://togithub.com/soc/dirs-rs) to `5.0`


</details>

<details>
<summary>Update Rust crate fsevent-sys to v4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/fsevent-sys-4.x`
  - Merge into: `main`
- Upgrade [fsevent-sys](https://togithub.com/octplane/fsevent-rust) to
`4.0.0`


</details>

<details>
<summary>Update Rust crate futures-lite to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/futures-lite-2.x`
  - Merge into: `main`
- Upgrade [futures-lite](https://togithub.com/smol-rs/futures-lite) to
`2.0`


</details>

<details>
<summary>Update Rust crate indexmap to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/indexmap-2.x`
  - Merge into: `main`
- Upgrade [indexmap](https://togithub.com/indexmap-rs/indexmap) to
`2.0.0`


</details>

<details>
<summary>Update Rust crate indoc to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/indoc-2.x`
  - Merge into: `main`
  - Upgrade [indoc](https://togithub.com/dtolnay/indoc) to `2`


</details>

<details>
<summary>Update Rust crate ordered-float to v4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/ordered-float-4.x`
  - Merge into: `main`
- Upgrade [ordered-float](https://togithub.com/reem/rust-ordered-float)
to `4.0.0`


</details>

<details>
<summary>Update Rust crate rustc-hash to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/rustc-hash-2.x`
  - Merge into: `main`
- Upgrade [rustc-hash](https://togithub.com/rust-lang/rustc-hash) to
`2.0`


</details>

<details>
<summary>Update Rust crate shellexpand to v3</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/shellexpand-3.x`
  - Merge into: `main`
- Upgrade [shellexpand](https://gitlab.com/ijackson/rust-shellexpand) to
`3.0.0`


</details>

<details>
<summary>Update Rust crate similar to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/similar-2.x`
  - Merge into: `main`
  - Upgrade [similar](https://togithub.com/mitsuhiko/similar) to `2.0`


</details>

<details>
<summary>Update Rust crate smol to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/smol-2.x`
  - Merge into: `main`
  - Upgrade [smol](https://togithub.com/smol-rs/smol) to `2.0`


</details>

<details>
<summary>Update Rust crate syn to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/syn-2.x`
  - Merge into: `main`
  - Upgrade [syn](https://togithub.com/dtolnay/syn) to `2.0`
  - Upgrade [syn](https://togithub.com/dtolnay/syn) to `2.0.0`


</details>

<details>
<summary>Update Rust crate wasmtime to v23</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wasmtime-23.x`
  - Merge into: `main`
- Upgrade [wasmtime](https://togithub.com/bytecodealliance/wasmtime) to
`23.0.0`


</details>

<details>
<summary>Update Rust crate wasmtime-wasi to v23</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/wasmtime-wasi-23.x`
  - Merge into: `main`
- Upgrade
[wasmtime-wasi](https://togithub.com/bytecodealliance/wasmtime) to
`23.0.0`


</details>

<details>
<summary>Update actions/checkout action to v4</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/actions-checkout-4.x`
  - Merge into: `main`
- Upgrade [actions/checkout](https://togithub.com/actions/checkout) to
`v4`


</details>

<details>
<summary>Update dependency PyGithub to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/pygithub-2.x`
  - Merge into: `main`
- Upgrade [PyGithub](https://togithub.com/pygithub/pygithub) to `2.3.0`


</details>

<details>
<summary>Update dependency danger to v12</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/danger-12.x`
  - Merge into: `main`
  - Upgrade [danger](https://togithub.com/danger/danger-js) to `12.3.3`


</details>

<details>
<summary>Update dependency livekit/client-sdk-swift to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/livekit-client-sdk-swift-2.x`
  - Merge into: `main`
- Upgrade
[livekit/client-sdk-swift](https://togithub.com/livekit/client-sdk-swift)
to `2.0.12`


</details>

<details>
<summary>Update dependency pytz to v2024</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/pytz-2024.x`
  - Merge into: `main`
  - Upgrade pytz to `2024.1`
  - Upgrade pytz to `==2024.1`


</details>

<details>
<summary>Update dependency types-pytz to v2024</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/types-pytz-2024.x`
  - Merge into: `main`
- Upgrade [types-pytz](https://togithub.com/python/typeshed) to
`2024.1.0.20240417`
- Upgrade [types-pytz](https://togithub.com/python/typeshed) to
`==2024.1.0.20240417`


</details>

<details>
<summary>Update postgres Docker tag to v16</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/postgres-16.x`
  - Merge into: `main`
  - Upgrade postgres to `16`


</details>

<details>
<summary>Update softprops/action-gh-release action to v2</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/softprops-action-gh-release-2.x`
  - Merge into: `main`
- Upgrade
[softprops/action-gh-release](https://togithub.com/softprops/action-gh-release)
to `v2`


</details>

<details>
<summary>Update tsickert/discord-webhook action to v6</summary>

  - Schedule: ["after 3pm on Wednesday"]
  - Branch name: `renovate/tsickert-discord-webhook-6.x`
  - Merge into: `main`
- Upgrade
[tsickert/discord-webhook](https://togithub.com/tsickert/discord-webhook)
to `v6.0.0`


</details>



🚸 Branch creation will be limited to maximum 2 per hour, so it doesn't
swamp any CI resources or overwhelm the project. See docs for
`prhourlylimit` for details.


---

 Got questions? Check out Renovate's
[Docs](https://docs.renovatebot.com/), particularly the Getting Started
section.
If you need any further assistance then you can also [request help
here](https://togithub.com/renovatebot/renovate/discussions).


---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/zed-industries/zed).


<!--renovate-config-hash:1752dbf5c31d5751ca59e575a43754358e807680713ab4daa60a32ec782882a0-->

Release Notes:

- N/A

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-24 22:32:58 -04:00
pantheraleo-7
b9570218b6 Remove !jupyter context for cmd-enter (ctrl-enter for linux) key binding (#15133)
Since zed has done away with `cmd-enter` binding for `repl::Run`
[#15026](https://github.com/zed-industries/zed/pull/15026), I think this
is no longer needed.

Release Notes:

- N/A
2024-07-24 19:02:24 -07:00
Marshall Bowers
fb4d77c008 Pin a specific version of typos in CI (#15128)
This PR makes it so we pin a specific version of `typos` in CI, rather
than just relying on whatever is already installed or what the latest
version is.

Release Notes:

- N/A
2024-07-24 19:03:07 -04:00
Max Brunsfeld
b14bb6bda4 Make git blame for SSH remote projects (#15106)
This also refactors the BufferStore + WorktreeStore interfaces to make
them cleaner, more fully encapsulating the RPC aspects of their
functionality.

Release Notes:

- N/A
2024-07-24 15:50:29 -07:00
Marshall Bowers
8501ae6a19 Make context and dropdown menus scrollable (#15127)
This PR makes context and dropdown menus scrollable, so that they don't
become totally unusable when they overflow the window.

Release Notes:

- N/A
2024-07-24 18:43:01 -04:00
Piotr Osiewicz
4e88a08ed4 chore: Some more dependency bumps (#15125)
Release Notes:

- N/A
2024-07-25 00:36:50 +02:00
Marshall Bowers
659f34bf21 settings_ui: Add UI and buffer font family controls (#15124)
This PR adds settings controls for changing the UI and buffer font
families.

Release Notes:

- N/A
2024-07-24 18:01:35 -04:00
Fernando Tagawa
001376fd6d cpp: Improve syntax highlighting (#13922)
* Added some missing operators, delimeters and keywords
* Highlight destructor, and operator overload as `@function`
* Moved `(field_identifier)` to the top, as it was highlighting methods
as `@property`

There are still some problems with something like `n1::n2::foo(...)`,
`foo` is not properly highlighted as a function

Release Notes:

- Improved C++ syntax highlighting
2024-07-25 00:55:21 +03:00
Marshall Bowers
298ca5ff1b Prefer .map for conditionals with else conditions (#15118)
This PR updates instances where we were using `.when_else` and
`.when_else_some` to use `.map` with a conditional inside.

This allows us to avoid reinventing Rust's syntax for conditionals and
(IMO) makes the code easier to read.

Release Notes:

- N/A
2024-07-24 17:09:07 -04:00
Kirill Bulatov
596ee58be8 Bump tree-sitter and related core language parser libraries (#14986)
Closes https://github.com/zed-industries/zed/issues/4565

To fix issues with code blocks' parsing in Markdown, a
tree-sitter-markdown library update is needed.
But `tree_sitter::language` is used in many places within core Zed,
which forced more library updates.

Release Notes:

- Updated tree-sitter parsers for core languages

---------

Co-authored-by: Max Brunsfeld <max@zed.dev>
Co-authored-by: Piotr Osiewicz <piotr@zed.dev>
2024-07-24 23:38:21 +03:00
Kirill Bulatov
fd4a4127eb Use proper names for sorting path entries (#15116)
Closes https://github.com/zed-industries/zed/issues/12470

Release Notes:

- Fixed project panel not showing properly file entries for directories
with dots in their names
([#12470](https://github.com/zed-industries/zed/issues/12470))
2024-07-24 23:36:13 +03:00
Marshall Bowers
0297a42735 Use US English spelling of "behavior" and "customize" (#15117)
This PR fixes some instances that weren't using US English spellings of
"behavior" and "customize".

Release Notes:

- N/A
2024-07-24 16:36:01 -04:00
Vitaly Slobodin
9c9a0bd24f lsp: Check if "Goto Definition" supported before request (#15111)
This is related to #15023 where we have the running Rubocop LSP that
provides diagnostics and formatting capabilities. Rubocop LSP sends its
capabilities
back to Zed without support for "textDocument/definition" request, Zed
actually does not check that and sends a request to Rubocop that results
in the server error "Unsupported method: textDocument/definition".

The fix here is related to
https://github.com/zed-industries/zed/pull/14666

Release Notes:

- N/A
2024-07-24 23:28:23 +03:00
Marshall Bowers
740c444089 settings_ui: Add theme settings controls (#15115)
This PR adds settings controls for the theme settings.

Release Notes:

- N/A
2024-07-24 16:25:52 -04:00
Piotr Osiewicz
325e6b9fef editor: Improve performance of buffer/project search (#15109)
Fixes #15102
Release Notes:

- Improved performance of project and buffer search when there are many
matches.
2024-07-24 21:04:07 +02:00
Danilo Leal
65c63defcc Ensure quick action bar icon buttons are a square (#15092)
As the title says! Also decreased a bit the gap between them so that's
consistent with other similar icon button stacks. I wish they could be
bigger buttons but the icons would need to be refined further for that,
as each has been drawn with a different dimension/bounding-box. Maybe in
the near future :)

---

Release Notes:

- N/A
2024-07-24 15:40:55 -03:00
Marshall Bowers
274e56b086 settings_ui: Add UI and buffer font weight controls (#15104)
This PR adds settings controls for the UI and buffer font weight
settings.

It also does some work around grouping the settings into related
sections.

Release Notes:

- N/A
2024-07-24 14:09:13 -04:00
Tom Anderson
7fb906d774 vim: Prevent overflowing integer when pushing count digit (#15079)
Minor bug where the command count overflows when enough digits are
entered. This swaps out simple multiplication/addition for their checked
counter parts, falling back to the previous value in case of overflow.

Release Notes:

- N/A
2024-07-24 11:54:59 -06:00
Conrad Irwin
d107d22c2d Fix cmd-alt-g b for git blame (#15103)
Broken by #14942 as the matching Pane binding for toggle regex now takes
precedence. cmd-alt-x still works for that.

Release Notes:

- N/A
2024-07-24 11:44:39 -06:00
Kyle Kelley
23dac9cfce docs: Show how to use the percent format to denote cells for the Zed REPL (#15099)
Release Notes:

- N/A
2024-07-24 10:31:25 -07:00
Joseph T Lyons
777ddefa73 Fix contributor-scraping code 2024-07-24 12:34:42 -04:00
Joseph T Lyons
77a2f2490e v0.147.x dev 2024-07-24 12:08:26 -04:00
Kyle Kelley
846fc67519 repl: Show executing status at the bottom of the outputs while waiting for execution to finish (#15096)
![image](https://github.com/user-attachments/assets/3b43f9d9-6456-42e2-a76a-43887d63309e)

Release Notes:

- N/A
2024-07-24 09:04:41 -07:00
Kyle Kelley
0843da0f81 repl: Incorporate moving down to next cell in jupytext mode (#15094)
`jupytext_snippets` now returns back both the jupytext snippets and the
`Point` of the next jupytext snippet.

Release Notes:

- N/A
2024-07-24 08:53:10 -07:00
Kyle Kelley
9e528dbb16 repl: Simplify error output formatting (#15088)
Release Notes:

- N/A
2024-07-24 08:38:04 -07:00
Conrad Irwin
c6d6c44810 Revert "Try blade#144 (#15036)" (#15095)
This reverts commit d034d73af9.

Release Notes:

- N/A
2024-07-24 09:36:59 -06:00
Marshall Bowers
9de6d318e9 feature_flags: Add support for flags that aren't auto-enabled for staff (#15093)
This PR adds support for defining feature flags that aren't auto-enabled
for Zed staff.

This will be useful in situations where we want to land a feature behind
a feature flag, but only want to ship it to certain staff members (e.g.,
the members currently working on it) initially.

Release Notes:

- N/A
2024-07-24 11:23:50 -04:00
Marshall Bowers
d540c95c81 settings_ui: Add prototype for settings controls (#15090)
This PR adds a prototype for controlling settings via the settings UI.

Still staff-shipped.

Release Notes:

- N/A
2024-07-24 10:36:27 -04:00
Peter Tripp
f7d6818c97 Sublime swap lines (#15089)
Improved SublimeText keymap (Mac & Linux).

- Add bind for MoveLineUp/Down (`ctrl-shift-up` on linux and `cmd-ctrl-up` on MacOS).

Co-authored-by: unixtensor <brandon@rhpidfyre.io>
2024-07-24 10:35:53 -04:00
Stanislav Alekseev
06d3dc010c Fix rendering issue with vtsls (#15087)
Before:
<img width="697" alt="Screenshot_2024-07-20_at_20 47 41"
src="https://github.com/user-attachments/assets/bc6db18e-77b9-400b-a917-2545269b7d1b">
After:
<img width="707" alt="Screenshot_2024-07-23_at_22 09 27"
src="https://github.com/user-attachments/assets/a0f6ebe5-fba0-4cc1-8d8b-b1982e2adf95">

Release Notes:

- Fixed multiline details provided by vtsls breaking rendering in
autocompletions
2024-07-24 17:30:44 +03:00
Kirill Bulatov
64b15d3a0e Display blocks over the git hunks (#15083)
Before:

![before](https://github.com/user-attachments/assets/614bbafd-f344-4c86-bd62-fff5f1ab143a)

After:

![after](https://github.com/user-attachments/assets/40a72a46-9fc4-4f94-9090-fb389f824a8d)


Release Notes:

- N/A
2024-07-24 07:23:20 -07:00
Piotr Osiewicz
23c5fc1b03 chore: Use explicit if let instead of for .. in option (#15086)
Fixes one clippy violation from 1.80 (that's due for release tomorrow).

Release Notes:

- N/A
2024-07-24 16:19:29 +02:00
Kirill Bulatov
c43eafbf9a Update the test code to newer realities (#15084)
Follow-up of https://github.com/zed-industries/zed/pull/14886

We do not require the branch to be up-to-date with `main` before
merging, and in 4 days some related test code got reworked so that there
were no conflicts and it slipped.

Release Notes:

- N/A
2024-07-24 16:51:18 +03:00
Danilo Leal
62a890fb7f Increase size of icon buttons within the inline editor (#15051)
This PR increases the size of the the icon buttons within the inline
editors, both within the buffer and on the terminal. I also added
properties to make sure they always render as a square, as well as
tweaking the stop icon SVG, adding an alternative sparkle icon that fit
the same grid as the close (14x14) icon, and adding a bit more right
padding on the buffer's case so it doesn't collide with the scrollbar.
End result is that they have a bit of an easier target space area and
normalized sizes.

---

Release Notes:

- N/A
2024-07-24 10:39:05 -03:00
Artur Rodrigues
5ad3c6b6dc inline_assistant: Respect tabs when selection first row is not indented (#14886)
When using the inline assistant with a language such as Go that uses
tabs, if the user selects a block of text that is correctly formatted
and where the first line has no indentation, the `suggested_line_indent`
variable ends up with `IndentSize { len: 0, kind: Space }`. That's
because `suggested_line_indent` current relies on
`BufferSnapshot::suggested_indents` suggestion for the first line on the
selection, but since it is already correctly indented, there are no
suggestions and `MultiBufferSnapshot::indent_size_for_line` is used
instead.


2d96bba61f/crates/assistant/src/inline_assistant.rs (L2124-L2128)

In this patch, we also take a look at the rest of the selection and
detect tabs. If one is encountered, we assume that tabs should always be
used. I suppose this isn't perfect, especially if the original file had
a mix of spaces and tabs, however it seems better than the status quo.

I considered using `BufferSnapshot::language_indent_size_at`, but I
imagine tabs should be preserved even when a specific language isn't
being used.

See screenshot below of the original prompt with this patch.

Tests:

* New unit test
* I've also manually tested with a few other cases: selection where all
lines are indented and file that only use spaces.

Release Notes:

- Fixed 'inline_assistant: tabs are overwritten with space characters
when first line in selection has no indentation'
([#14885](https://github.com/zed-industries/zed/issues/14885)).

<img width="942" alt="image"
src="https://github.com/user-attachments/assets/f2c5d7e9-e8bc-400b-bd6f-09e4a89d22c1">
2024-07-24 16:31:16 +03:00
schdaniel20
e004a573fd Improve project panel settings documentation (#15075)
Improved Project Panel Settings Documentation: The documentation for the
project panel settings has been enhanced for clarity and
comprehensiveness, providing better guidance and examples for users.
Default values have been aligned with project_panel_settings.rs.

Release Notes:

- N/A
2024-07-24 16:16:22 +03:00
Kirill Bulatov
babf8923ee Do not show signature help when editor is not focused (#15080)
Show the help again, if it was not dismissed and the editor regains
focus.

Release Notes:

- N/A
2024-07-24 14:37:35 +03:00
Kirill Bulatov
faf5ab7873 Fix a typo in the remote development docs (#15078)
Uses https://github.com/zed-industries/zed/pull/15015 

Release Notes:

- N/A
2024-07-24 13:53:49 +03:00
Danilo Leal
912b396e58 Adjust model selector popover design (#15056)
This PR mostly refines the model selector popover design by formatting
the models names' and adjusting spacing/alignment in the list-related
items. The list component changes could've been made in a separate PR
but it was also very practical to do it here as I was already
in-context. Either way, I'm happy to separate if that's better!

One thing I couldn't necessarily figure out, though, is why the order
changed (e.g., Anthropic at last ). I wonder if that was because of the
separator logic somehow? I'd love guidance here—new to Rust!

| Before | After |
|--------|--------|
| <img width="228" alt="Screenshot 2024-07-23 at 21 02 33"
src="https://github.com/user-attachments/assets/3372c6c9-08dc-4d71-9265-26f015e2dbc2">
| <img width="228" alt="Screenshot 2024-07-23 at 21 01 45"
src="https://github.com/user-attachments/assets/624cc7db-a3d9-48e3-99d7-c29829501130">
|

---

Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
Co-authored-by: Antonio <antonio@zed.dev>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
2024-07-24 12:24:54 +02:00
Nathan Sobo
87d93033d1 Support Jupytext-style line comments for REPL evaluation ranges (#15073)
This adds support for detecting line comments in the
[Jupytext](https://jupytext.readthedocs.io/) format. When line comments
such as `# %%` is present, invoking `repl: run` will evaluate the code
between these line comments as a unit.

/cc @rgbkrk 

```py
# %%
# This is my first block
print(1)
print(2)

# %%
# This is my second block
print(3)
```

Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Antonio <antonio@zed.dev>
Co-authored-by: Thorsten <thorsten@zed.dev>
Co-authored-by: Thorsten Ball <mrnugget@gmail.com>
2024-07-24 11:53:58 +02:00
Bennet Bo Fenner
af4b9805c9 assistant: Fix issues when configuring different providers (#15072)
Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
2024-07-24 11:21:31 +02:00
Thorsten Ball
ba6c36f370 repl: Fix repl-over-selection not being Vim-line-wise aware (#15068)
Release Notes:

- N/A
2024-07-24 10:06:38 +02:00
Thorsten Ball
7644605f0f docs: Fix default binding for REPL (#15065)
Release Notes:

- N/A
2024-07-24 09:50:23 +02:00
Conrad Irwin
b4a8f14a76 linux: Detect shift better (#15013)
Release Notes:

- linux: Fixed typing shortcuts like ctrl-/ on some systems
2024-07-23 21:05:11 -06:00
Marshall Bowers
c84da37030 rpc: Add support for OAEP-based encryption format (#15058)
This PR adds support for a new encryption format for exchanging access
tokens during the authentication flow.

The new format uses Optimal Asymmetric Encryption Padding (OAEP) instead
of PKCS#1 v1.5, which is known to be vulnerable to side-channel attacks.

**Note: We are not yet encrypting access tokens using the new format, as
this is a breaking change between the client and the server. This PR
only adds support for it, and makes it so the client and server can
decrypt either format moving forward.**

This required bumping the RSA key size from 1024 bits to 2048 bits. This
is necessary to be able to encode the access token into the ciphertext
when using OAEP.

This also follows OWASP recommendations:

> If ECC is not available and RSA must be used, then ensure that the key
is at least 2048 bits.
>
> —
[source](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms)

Release Notes:

- N/A
2024-07-23 21:25:25 -04:00
Marshall Bowers
edf7f6defe Upgrade rsa to v0.9.6 (#15055)
This PR upgrades the `rsa` crate to v0.9.6.

The version we were using was rather old, and for something
security-sensitive we should be using a recent version.

No behavioral changes have been made, just updates to account for
changes in the crate's API.

Release Notes:

- N/A
2024-07-23 20:11:48 -04:00
Marshall Bowers
1307a80e07 rpc: Add regression tests for encoding/decoding public keys (#15054)
This PR adds some tests to ensure we don't regress in our public key
encoding/decoding capabilities when making changes in this area.

Release Notes:

- N/A
2024-07-23 19:58:47 -04:00
Kyle Kelley
9d11a6ff78 repl: Detect Conda and Python environments with their own kernel specs (#15047)
Detect kernels in conda and python environments.

Release Notes:

- N/A
2024-07-23 15:23:24 -07:00
Marshall Bowers
6769e55ce0 Revert "chore: Bump async-tungstenite to 0.23 (and tungstenite to 0.20.1) (#15039)" (#15048)
This reverts commit 4d65f7eea3.

Reverting because it causes auth with collab to break.

Release Notes:

- N/A
2024-07-23 18:22:37 -04:00
Mikayla Maki
855048041d Update http crate name (#15041)
Release Notes:

- N/A
2024-07-23 15:01:05 -07:00
Marshall Bowers
d36ebc8c74 Add global Fs instance (#15044)
This PR adds a global `Fs` instance to the app context.

This will make it easier to access the filesystem in some cases instead
of having to thread it around.

Release Notes:

- N/A
2024-07-23 17:59:55 -04:00
Kyle Kelley
5062bf0b4d repl: Pad the table rows with a fraction of the line height (#15042)
Compute the final height using the number of rows and the constant
fraction.

Ensures we don't accidentally overlap lines below table output.

<img width="663" alt="image"
src="https://github.com/user-attachments/assets/fe24b08d-2271-4dcc-88c7-8702ba4c68b0">


Release Notes:

- N/A
2024-07-23 14:42:58 -07:00
Piotr Osiewicz
4d65f7eea3 chore: Bump async-tungstenite to 0.23 (and tungstenite to 0.20.1) (#15039)
Release Notes:

- N/A
2024-07-23 23:18:00 +02:00
Conrad Irwin
7ae305ac0d Make vim::test_remap less flaky on linux (#15040)
Release Notes:

- N/A
2024-07-23 15:16:45 -06:00
Piotr Osiewicz
ba4ff1df59 chore: Remove clap3 dependency by disabling default features of cbindgen (#15037)
cbindgen pulled that in, but we don't really need it (Plus it pulls in a
dep with an advisory)

Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-23 22:49:49 +02:00
Conrad Irwin
d034d73af9 Try blade#144 (#15036)
This pulls in https://github.com/kvark/blade#144 to see if it results in
fewer bad GPU configurations selected

Release Notes:

- linux: Improved graphics card detection
2024-07-23 14:37:22 -06:00
Max Brunsfeld
5f7881fc1e Improve ssh remote error handling and logging (#15035)
Release Notes:

- N/A
2024-07-23 13:29:56 -07:00
Conrad Irwin
b0c525af5f inotify alert (#15027)
Release Notes:

- linux: Show an error and troubleshooting steps for inotify limits
(#10310)
2024-07-23 14:21:56 -06:00
Conrad Irwin
41a3e78b1e Don't try to connect to X11/Wayland when headless (#15028)
Release Notes:

- remote development: Stopped logging every 16ms when connected to a
remote server with a badly configured X server.
2024-07-23 14:11:47 -06:00
Stanislav Alekseev
5021397c01 Fix diagnostic popups flickering when moving cursor in the boundaries of the symbol (#14870)
This PR just uses ranges returned by an LSP to work, the subsequent PR
would focus on trying to fall back onto tree-sitter in case of info
hovers. I'm also unsure if I'm supposed to use `local_diagnostic` or
`primary_diagnostic` when both are available
Release Notes:

- Fix diagnostic popups flickering when moving cursor in the boundaries
of the symbol

Before:


https://github.com/user-attachments/assets/4905a7e5-c333-453b-b204-264b3ef79586

After:


https://github.com/user-attachments/assets/c742c424-fb20-450d-8848-baaf1937dd47
2024-07-23 14:10:19 -06:00
Kirill Bulatov
b2b9d4ccb6 Extend task templates with shell and hide fields to use custom shells and custom close behavior (#15031) 2024-07-23 22:58:36 +03:00
Marshall Bowers
4a43084cb7 Bump wasmtime and wasmtime-wasi to v19.0.2 (#15033)
This PR bumps `wasmtime` and `wasmtime-wasi` to v19.0.2 for some bug
fixes.

https://github.com/bytecodealliance/wasmtime/releases/tag/v19.0.2

Release Notes:

- N/A
2024-07-23 15:55:15 -04:00
Piotr Osiewicz
fa76d8edcf chore: Bump dependencies (#15029)
Release Notes:


- N/A
2024-07-23 21:38:47 +02:00
Marshall Bowers
5f8e799d60 repl: Fix a small typo in a variable name (#15030)
This PR fixes a small typo in a variable name.

Release Notes:

- N/A
2024-07-23 15:09:40 -04:00
Max Brunsfeld
38e3182bef Handle buffer diff base updates and file renames properly for SSH projects (#14989)
Release Notes:

- N/A

---------

Co-authored-by: Conrad <conrad@zed.dev>
2024-07-23 11:32:37 -07:00
Kyle Kelley
ec093c390f repl: Change keybinding to ctrl-shift-enter for repl::Run (#15026)
... on all platforms.

`ctrl-shift-enter` for the repl, `cmd-enter` for the assistant. People
can override this behavior as they desire in their own keymaps.

Release Notes:

- N/A
2024-07-23 11:23:06 -07:00
Piotr Osiewicz
3d1bf09299 Allow user to use multiple formatters (#14846)
Fixes #4822
- [x] Release note
- [ ] Surface formatting errors via a toast
- [x] Doc updates
- [x] Have "language-server" accept an optional name of the server.

Release Notes:

- `format` and `format_on_save` now accept an array of formatting
actions to run.
- `language_server` formatter option now accepts the name of a language
server to use (e.g. `{"language_server": {"name: "ruff"}}`); when not
specified, a primary language server is used.

---------

Co-authored-by: Thorsten <thorsten@zed.dev>
2024-07-23 20:05:09 +02:00
Kyle Kelley
53b711c2b4 repl: Make the terminal background transparent (#15022)
Keeps the background the same as the output area background by making
the terminal background be `Hsla::transparent_black()`.

Release Notes:

- N/A

---------

Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
2024-07-23 11:03:22 -07:00
Bennet Bo Fenner
d0f52e90e6 assistant: Overhaul provider infrastructure (#14929)
<img width="624" alt="image"
src="https://github.com/user-attachments/assets/f492b0bd-14c3-49e2-b2ff-dc78e52b0815">

- [x] Correctly set custom model token count
- [x] How to count tokens for Gemini models?
- [x] Feature flag zed.dev provider
- [x] Figure out how to configure custom models
- [ ] Update docs

Release Notes:

- Added support for quickly switching between multiple language model
providers in the assistant panel

---------

Co-authored-by: Antonio <antonio@zed.dev>
2024-07-23 19:48:41 +02:00
Thorsten Ball
17ef9a367f zed: Add ability to restore last session w/ multiple windows (#14965)
This adds the ability for Zed to restore multiple windows after
restarting. It's now the default behavior.

Release Notes:

- Added ability to restore all windows that were open when Zed was quit.
Previously only the last used workspace was restored. This is now the
default behavior. To get back the old behavior, add the following to
your settings: `{"restore_on_startup": "last_workspace"}` (Part of
[#4985](https://github.com/zed-industries/zed/issues/4985) and
[#4683](https://github.com/zed-industries/zed/issues/4683))

Demo:



https://github.com/user-attachments/assets/57a375ec-0c6a-4724-97c4-3fea8f18bc2d

---------

Co-authored-by: Nathan <nathan@zed.dev>
2024-07-23 19:44:02 +02:00
Antonio Scandurra
53f828df7d Avoid inserting extra newlines when evaluating code (#15018)
When the evaluation range ends at the start of a line, back it up to the
end of the previous line. This avoids inserting extra newlines below the
evaluation range when they already exist.

Release Notes:

- N/A

Co-authored-by: Nathan <nathan@zed.dev>
2024-07-23 19:03:15 +02:00
Nathan Sobo
d9a00b6f8b Update setting name in REPL docs (#15017)
cc @rgbkrk @iamnbutler 

Release Notes:

- N/A
2024-07-23 09:53:46 -07:00
Marshall Bowers
7d0386eff9 settings_ui: Add placeholder view (#15019)
This PR adds a placeholder view for the settings UI. It does not contain
any functionality, as of yet.

This view is staff-shipped behind a feature flag.

Release Notes:

- N/A
2024-07-23 12:50:11 -04:00
Conrad Irwin
bdf1d4edea linux: Better GPU debugging (#14706)
Release Notes:

- linux: Added GPU information to `editor: Copy System Specs to
Clipboard`
- linux: Show a prominant warning before running under llvmpipe and
similar.
2024-07-23 09:56:45 -06:00
Marshall Bowers
c262c81e52 repl: Filter commands out of command palette when REPL is disabled (#15016)
This PR makes it so the `repl: ` commands don't appear in the command
palette when the REPL feature is disabled.

Release Notes:

- N/A
2024-07-23 11:49:56 -04:00
Kirill Bulatov
a5cb66f0e1 Allow to regenerate a summary of the assistant context (#14964)
Both manual and LLM-through ways are supported:


https://github.com/user-attachments/assets/afb0d2b3-9a9b-4f78-a909-1e663e686323


Release Notes:

- Improved assistant panel summarization usability
2024-07-23 17:51:49 +03:00
Fabian
a0d687c24a astro: Ensure Typescript is present (#14849)
The current Astro Extension fails to load properly if it can't find a
`tsserver.js` file in the current workspaces' `node_modules` folder.
This happens pretty frequently, either if `typescript` is not installed
in the project (which it isn't by default), or if `node_modules` is not
in the workspace root.

This PR adds a fallback method of installing `typescript` alongside the
extensions' language server if it is not found in the workspaces'
`node_modules`, as well as correctly setting the `tsdk` path in the
initialization options.

Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-23 10:39:25 -04:00
Marshall Bowers
5f57efb266 astro: Align version numbers in extension.toml and Cargo.toml (#15011)
This PR aligns the version numbers in `extension.toml` and `Cargo.toml`
for the Astro extension, as they had gotten out-of-sync.

Release Notes:

- N/A
2024-07-23 10:28:09 -04:00
Marshall Bowers
6398b45084 astro: Upgrade zed_extension_api to v0.0.6 (#15010)
This PR upgrades the Astro extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-23 10:12:40 -04:00
Antonio Scandurra
728650f94a Fix interaction with Anthropic models when using it via zed.dev (#15009)
Release Notes:

- N/A

---------

Co-authored-by: Bennet <bennet@zed.dev>
2024-07-23 15:47:38 +02:00
Antonio Scandurra
dde9d37cf9 Remove completion dependency from collab (#15006)
This was causing CI to fail when trying to deploy collab.

Release Notes:

- N/A

Co-authored-by: Bennet <bennet@zed.dev>
2024-07-23 11:44:07 +02:00
Piotr Osiewicz
5d77a7dc6c Ruff: Do not pass --preview flag, respect binary settings (#15001)
Bumps version to 0.0.2 as well.

Release Notes:

- N/A
2024-07-23 09:57:42 +02:00
Benjamin Westphal
1fae99a7c4 vim: Add motion support for toggle comments (#14919)
### Summary

This PR adds support for count and object motions to the toggle comments
action in Vim mode. The relevant issue is
[#14337](https://github.com/zed-industries/zed/issues/14337).

For example, `2 g c j` will toggle comments three lines downward. `g c g
g` will toggle comments from the current cursor position up to the start
of the file.

Notably missing from this PR are `g c b` (toggle comments for the
current block) as well as `g c p` (toggle comments for the current
paragraph). These seem to be non-standard.

The new module `normal/toggle_comments.rs` has been copied almost
verbatim from `normal/indent.rs`. Maybe that ought to be abstracted over
but I feel I lack the overview.

Release Notes:

- vim: Added support for count and object motion to the toggle comments
action ([#14337](https://github.com/zed-industries/zed/issues/14337)).
2024-07-22 21:22:10 -06:00
CharlesChen0823
eb210ca248 linux: Fix crash in Wayland when dragging and dropping a tab not belonging to Zed (#14995)
close #14189 

Release Notes:

- N/A
2024-07-22 21:20:53 -06:00
Joseph T Lyons
ddea18d546 Add snippets category to docs sidebar 2024-07-22 21:21:11 -04:00
Joseph T. Lyons
b85dba106b Add minimal snippets documentation (#14992)
Release Notes:

- N/A
2024-07-22 21:18:39 -04:00
Nate Butler
4ba430b16c repl: Design tweaks (#14988)
- Add spinner to "Executing..."
- Update Queued label to match others.

Release Notes:

- N/A
2024-07-22 19:05:36 -04:00
Marshall Bowers
fe1f55cbfd repl: Iterate on design of REPL sessions view (#14987)
This PR iterates on the design of the REPL sessions view.

We now use the same component for both available kernels and running
ones to provide some consistency between the two modes:

<img width="1208" alt="Screenshot 2024-07-22 at 6 49 08 PM"
src="https://github.com/user-attachments/assets/8b5c3600-e438-49fa-8484-cefabf4b44f1">

<img width="1208" alt="Screenshot 2024-07-22 at 6 49 14 PM"
src="https://github.com/user-attachments/assets/5125e9b3-6465-4d1e-9036-e6ca270dedcb">

Release Notes:

- N/A
2024-07-22 19:02:11 -04:00
Kyle Kelley
01392c1329 repl: Enable jupyter by default, allow disabling (#14985)
Enables the jupyter feature by default, which is shown only when we have
a kernelspec or know that we (can) support it well (Python,
Deno/TypeScript).

Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-22 17:30:21 -04:00
Marshall Bowers
a9397834eb quick_action_bar: Add menu entry to view REPL sessions (#14984)
This PR adds a new menu entry in the REPL item in the quick action bar
to open up the REPL sessions view:

<img width="232" alt="Screenshot 2024-07-22 at 4 54 36 PM"
src="https://github.com/user-attachments/assets/acc60a25-7722-4331-9b80-fab9cca65842">

This makes this more discoverable than having to know that the command
exists.

Release Notes:

- N/A
2024-07-22 17:05:05 -04:00
Marshall Bowers
4227a3d3e0 repl: Remove unused repl_panel::ToggleFocus action (#14983)
This PR removes the `repl_panel::ToggleFocus` action, as we don't need
it anymore.

Release Notes:

- N/A
2024-07-22 16:45:04 -04:00
Marshall Bowers
2a69420c42 repl: Do some cleanup (#14982)
This PR cleans up the REPL implementation a bit.

Release Notes:

- N/A
2024-07-22 16:39:32 -04:00
Marshall Bowers
d8a42bbf63 repl: Replace REPL panel with sessions view (#14981)
This PR removes the REPL panel and replaces it with a new sessions view
that gets displayed in its own pane.

The sessions view can be opened with the `repl: sessions` command (we
can adjust the name, as needed).

There was a rather in-depth refactoring needed to extricate the various
REPL functionality on the editor from the `RuntimePanel`.

<img width="1136" alt="Screenshot 2024-07-22 at 4 12 12 PM"
src="https://github.com/user-attachments/assets/ac0da351-778e-4200-b08c-39f9e77d78bf">

<img width="1136" alt="Screenshot 2024-07-22 at 4 12 17 PM"
src="https://github.com/user-attachments/assets/6ca53476-6ac4-4f8b-afc8-f7863f7065c7">

Release Notes:

- N/A
2024-07-22 16:22:50 -04:00
Joseph T. Lyons
8f20ea1093 Add a section about navigating within multibuffers (#14979)
Release Notes:

- N/A
2024-07-22 15:10:02 -04:00
Kevin Wang
a20e92a8c1 Truncate line when accepting inline suggestions for Supermaven (#13884)
Configures inline completions to delete the remaining text on the given
line. This doesn't affect the github copilot inline completion provider
since it seems to only generate suggestions if the cursor is at the end
of the line but fixes the usability issues related to Supermaven.




https://github.com/user-attachments/assets/1b8bc9a3-4666-4665-a436-96e4beee01bb





Release Notes:

- Fixed https://github.com/zed-industries/zed/issues/13039

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-07-22 11:59:38 -07:00
Csaba Hoch
c703e20a06 docs: Fix ctrl-x meaning in vim mode (#14968)
Release Notes:

- N/A
2024-07-22 12:52:35 -06:00
Conrad Irwin
a955968de3 Don't panic on GPU hang (#14974)
Fixes: #12766
Fixes: #14022

Release Notes:

- linux: Fix panic when GPU is temporarily unavailable.
2024-07-22 12:21:28 -06:00
Kirill Bulatov
f597c29432 Position X for deleted hunks better (#14973)
Release Notes:

- N/A
2024-07-22 20:24:24 +03:00
Rashid Almheiri
a5a7a835fe Set the default Starlark LSP for zaucy/zed-starlark (#14972)
given zaucy/zed-starlark#4 was merged, zed-starlark now has multiple
LSPs and requires additional configuration which isn't available
directly for extensions.

cc @zaucy 

Release Notes:

- N/A
2024-07-22 12:58:28 -04:00
Marshall Bowers
28baa56e3d repl: Factor out ReplStore (#14970)
This PR factors a `ReplStore` out of the `RuntimePanel`.

Since we're planning to remove the `RuntimePanel` and replace it with an
ephemeral tab that can be opened, we need the kernel specifications and
sessions to have somewhere long-lived that they can reside in.

Release Notes:

- N/A
2024-07-22 12:46:33 -04:00
Conrad Irwin
2e23527e09 Refactor key dispatch (#14942)
Simplify key dispatch code.

Previously we would maintain a cache of key matchers for each context
that
would store the pending input. For the last while we've also stored the
typed prefix on the window. This is redundant, we only need one copy, so
now
it's just stored on the window, which lets us avoid the boilerplate of
keeping
all the matchers in sync.

This stops us from losing multikey bindings when the context on a node
changes
(#11009) (though we still interrupt multikey bindings if the focus
changes).

While in the code, I fixed up a few other things with multi-key bindings
that
were causing problems:

Previously we assumed that all multi-key bindings took precedence over
any
single-key binding, now this is done such that if a user binds a
single-key
binding, it will take precedence over all system-defined multi-key
bindings
(irrespective of the depth in the context tree). This was a common cause
of
confusion for new users trying to bind to `cmd-k` or `ctrl-w` in vim
mode
(#13543).

Previously after a pending multi-key keystroke failed to match, we would
drop
the prefix if it was an input event. Now we correctly replay it
(#14725).

Release Notes:

- Fixed multi-key shortcuts not working across completion menu changes
([#11009](https://github.com/zed-industries/zed/issues/11009))
- Fixed multi-key shortcuts discarding earlier input
([#14445](https://github.com/zed-industries/zed/pull/14445))
- vim: Fixed `jk` binding preventing you from repeating `j`
([#14725](https://github.com/zed-industries/zed/issues/14725))
- vim: Fixed `escape` in normal mode to also clear the selected
register.
- Fixed key maps so user-defined mappings take precedence over builtin
multi-key mappings
([#13543](https://github.com/zed-industries/zed/issues/13543))
- Fixed a bug where overridden shortcuts would still show in the Command
Palette
2024-07-22 10:46:16 -06:00
Piotr Osiewicz
865904a0c9 lsp: Pass back diagnostic .data when querying code actions for it (#14962)
Per the LSP spec, we should pass .data field of diagnostics into code
action request:
```
	/**
	 * A data entry field that is preserved between a
	 * `textDocument/publishDiagnostics` notification and
	 * `textDocument/codeAction` request. *
	 * @since 3.16.0 */ data?: LSPAny;
```


Release Notes:

- Fixed rare cases where a code action triggered by diagnostic may not
be available for use.
2024-07-22 17:49:11 +02:00
张小白
10d2353e07 windows: Treat settings.json as JSONC (#14944)
Before this PR, comments in `settings.json` are marked with red lines,
indicating that `"comments are not allowed in JSON."`

![Screenshot 2024-07-22
153951](https://github.com/user-attachments/assets/fbb631e8-43cf-4473-97c0-50c83c4d6ab1)


After this PR, this issue is resolved.

![Screenshot 2024-07-22
153527](https://github.com/user-attachments/assets/ee0f7877-c623-4caa-94cd-97e82f9b8945)

Release Notes:

- N/A
2024-07-22 10:46:52 -04:00
Floyd Wang
1ea363b020 Fix typo in font-weight setting story (#14958)
Release Notes:

- N/A
2024-07-22 07:49:27 -04:00
Antonio Scandurra
0155435142 Allow using a custom model when using zed.dev (#14933)
Release Notes:

- N/A
2024-07-22 12:25:53 +02:00
YeonGyu-Kim
a334c69e05 Add instructions for configuring linting in the Python documentation using Ruff extension (#14896)
Added documentation for #14198

I also suggest replacing format guides from `black` to `ruff` to unify
the tooling in the document.

Ruff is now widely used in the Python community, including
[fastapi](cd6e9db065/pyproject.toml (L213)).
It's compatible with black but a lot faster.

Release Notes:

- N/A
2024-07-22 11:59:42 +02:00
Kirill Bulatov
31d283932c Allow to input spaces in the outline panel filter input (#14951)
Release Notes:

- Fixed outline panel's filter not accepting spaces
2024-07-22 12:02:25 +03:00
Luke Naylor
0ef19dedd2 Correct escaping in snippets (#14912)
## Release Notes:

- Fixed issue with backslashes not appearing in snippets
([#14721](https://github.com/zed-industries/zed/issues/14721)),
motivated by a snippet provided by the latex LSP
([texlab](https://github.com/latex-lsp/texlab)) not working as intended
in Zed ([extension
issue](https://github.com/rzukic/zed-latex/issues/5)).

[Screencast from 2024-07-21
14-57-19.webm](https://github.com/user-attachments/assets/3c95a987-16e5-4132-8c96-15553966d4ac)

## Fix details:

Only $, }, \ can be escaped by a backslash as per [LSP spec (under
grammar
section)](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/\#snippet_syntax).
Technically, commas and pipes can also be escaped only in "choice"
tabstops but it does not look like they are implemented in Zed yet.

## Additional tests added for cases currently not covered:
- backslash not being used to escape anything (so just a normal
backslash)
- backslash escaping a backslash (so that the second does not escape
what follows it)

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2024-07-22 00:57:34 +02:00
Marshall Bowers
83f6a7f228 assistant: Use square buttons for the inline assist model selector (#14928)
This PR updates the model selector buttons in the inline assistant to
use `IconButtonShape::Square`.

Release Notes:

- N/A
2024-07-21 13:59:21 -04:00
Marshall Bowers
2d96bba61f assistant: Respect ui_font_weight setting for inline assist in the terminal (#14924)
This PR updates the terminal inline assist to respect the
`ui_font_weight` setting.

Release Notes:

- N/A
2024-07-21 13:09:25 -04:00
Marshall Bowers
54039162ac erlang: Add support for installing elp language server (#14923)
This PR updates the Erlang extension with support for installing the
[Erlang Language
Platform](https://github.com/WhatsApp/erlang-language-platform) (`elp`)
language server from the GitHub Release assets.

Release Notes:

- N/A
2024-07-21 12:42:21 -04:00
Marshall Bowers
45b45155d4 Treat tsconfig.json as JSONC (#14920)
This PR updates the default settings to treat `tsconfig.json` files as
JSONC.

Resolves https://github.com/zed-industries/zed/issues/14906.

Release Notes:

- TypeScript's `tsconfig.json` files are now treated as JSONC.
2024-07-21 12:17:16 -04:00
Ryan Hawkins
a4baba7edd Add button to copy SHA from Git blame (#14883)
The git blame dialog doesn't give the user a way to quickly copy the SHA
of the associated commit for a line. Adding an option for users to
quickly access this SHA is helpful for user's to do any more git-fu they
might need, such as viewing the full changes themselves within git,
checking the commit out, bisecting off the commit, etc.

This is also very handy for user's of self-hosted git providers.
Determining what provider a self-hosted repository is using could be
quite difficult and this presents an easy option to allow users to look
up more about a commit without having to memorize the short SHA.

Release Notes:

- Added a button to copy the SHA from a Git blame entry.

<img width="1552" alt="A screenshot showing the new copy SHA button
within the Zed editor's inline blame "
src="https://github.com/user-attachments/assets/9365950d-3a3f-4c11-b119-ab02654f5669">

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-21 12:02:16 -04:00
Marshall Bowers
cb2c334358 Use defaults for unchanged TextStyle fields (#14918)
This PR updates a number of spots where we were setting all of the
`TextStyle` fields even if we were not changing the values from the
defaults.

We now use `..Default::default()`.

Release Notes:

- N/A
2024-07-21 11:55:45 -04:00
Max Brunsfeld
e8bcc412b5 Fix usability issues with ssh connection modal (#14917)
Release Notes:

- N/A
2024-07-21 08:43:59 -07:00
Fabian Bergström
7b88fc5cda erlang: Add Erlang Language Platform support (#14879)
Added support for the [Erlang Language
Platform](https://whatsapp.github.io/erlang-language-platform/) language
server to the Erlang extension.

Release Notes:

- N/A

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-21 11:38:24 -04:00
Marshall Bowers
2f3df9fd93 erlang: Update structure to accommodate multiple language servers (#14915)
This PR updates the structure of the Erlang extension to accommodate
multiple language servers.

Release Notes:

- N/A
2024-07-21 11:21:52 -04:00
Marshall Bowers
7d063aa10b erlang: Upgrade zed_extension_api to v0.0.6 (#14914)
This PR upgrades the Erlang extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-21 10:59:05 -04:00
张小白
9c26d07f7a Ensure ExtensionBuilder respects the proxy settings (#14899)
Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-21 10:46:43 -04:00
Marshall Bowers
0a9d50bf01 http: Refactor construction of HTTP clients with a proxy (#14911)
This PR refactors the `http` crate to expose a better way of
constructing an `HttpClient` that contains a proxy.

Release Notes:

- N/A
2024-07-21 10:15:38 -04:00
Marshall Bowers
c7331b41e9 gpui: Include image URI in ImageCacheError::BadStatus (#14910)
This PR updates the `ImageCacheError::BadStatus` variant to include the
URI of the image that failed to load.

This helps contextualize the resulting error logs.

Release Notes:

- N/A
2024-07-21 10:13:31 -04:00
Mag Mell
70f7f2d2da theme_importer: Output logs to stderr (#14890)
Will allow writing directly to a file without logging via `cargo run -p
theme_importer -- /path/to/file`

Release Notes:

- N/A
2024-07-21 08:53:37 -04:00
Kyle Kelley
cd9b25d827 repl: Increase accuracy of error output line height (#14880) 2024-07-20 15:59:54 -07:00
Kyle Kelley
781633fb1a repl: Ensure that the output's computed line height is at least 1 (#14877) 2024-07-20 15:59:28 -07:00
Kyle Kelley
6dfb0a4a70 repl: Push button to clear outputs (#14873) 2024-07-20 11:32:03 -07:00
claytonrcarter
a1670551bf Fix description of -l flag in bundle-mac (#14864)
This removes mention of "copy bundle to `/Applications`" from the help
text for `bundle-mac` because, as far as I can tell, the `-l` flag only
controls the build, not the copy/install. (The copy/install is
controlled by using the `-i` flag in conjunction with `-l`.)


Release Notes:

- N/A
2024-07-20 19:16:54 +03:00
Piotr Osiewicz
71cbfc65b1 Ruff: pass initialization_options from settings (#14866)
No version bump, as the extension is not out yet.
Release Notes:

- N/A
2024-07-20 16:09:53 +02:00
Piotr Osiewicz
1218a846c1 extensions: Add Ruff extension (#14198)
Release Notes:

- Added extension for [Ruff](https://docs.astral.sh/ruff/), an extremely fast Python linter and code formatter, written in Rust.
2024-07-20 15:18:02 +02:00
versecafe
48c253feb8 Expand terminal menu actions (#14828)
<img width="422" alt="image"
src="https://github.com/user-attachments/assets/73195894-81a7-4b8e-b5cf-ae60bf5b1fb9">

Release Notes:

- Added `Copy`, `Paste`, `Select All`, & `New Terminal` into terminal's context menu
2024-07-20 12:20:53 +03:00
Kevin Wang
46b7fa9bcb Add Sign Out link for Supermaven (#14834)
Adds a menu item to sign out from a linked Supermaven account.


![image](https://github.com/user-attachments/assets/6af3c39f-9ca4-4ac2-a5c0-c7cb3c3aaac2)


Release Notes:

- Added the ability to sign out of a Supermaven account ([#12715(https://github.com/zed-industries/zed/issues/12715))
2024-07-20 03:53:24 +03:00
Max Brunsfeld
022e662815 Start work on showing progress when initializing ssh remoting 2024-07-19 17:25:28 -07:00
Max Brunsfeld
d89e2592a1 Fix file name conflict when downloading app update (#14847)
This fixes broken auto-updates on nightly. Unfortunately, nightly users
will need to re-download.

Release Notes:

- N/A
2024-07-19 16:33:41 -07:00
Fabian
a072caab0b node_runtime: Bump downloaded Node.js version to Current (Jod) (#14687)
This PR bumps the hard-coded Node.js version from v18.x (Hydrogen), which was LTS until October 2023, to v22.x (Jod) which will be the next LTS release in October 2024.

Release Notes:

- Updated Zed's node version (v18.x -> v22.x)
2024-07-20 01:18:56 +03:00
Max Brunsfeld
fbe30c6f2e Fixes for SSH remoting infrastructure (#14844)
* Fixed mis-named macOS remote server archives in actions and packaging
scripts
* Fixed an issue with the ask pass script on linux
* Download nightly versions of remote servers in dev mode (not stable)

Release Notes:

- N/A
2024-07-19 15:08:10 -07:00
Marshall Bowers
a5b8094082 editor: Implement From instead of Into for converting BlockIds to ElementIds (#14839)
This PR replaces the `Into<ElementId> for BlockId` implementation with
`From<BlockId> for ElementId`.

This keeps in line with Rust's guidance for preferring implementing
`From`, and gives us more flexibility when converting.

Release Notes:

- N/A
2024-07-19 16:24:12 -04:00
Conrad Irwin
d2efa12e16 vim: Fix gv after actions (#14829)
Fixes: #13720

Co-Authored-By: <tobbe@tlundberg.com>



Release Notes:

- vim: Fixed `gv` after `y`, `d`, etc.
([#13760](https://github.com/zed-industries/zed/issues/13760)).
2024-07-19 13:26:55 -06:00
Marshall Bowers
5e635b8914 ui: Remove absolute positioning for tab slots (#14836)
This PR reworks the `Tab` component to not use absolute positioning in
order to position the tab slots.

This should make any further adjustments we want to make to the spacing
easier to do.

Release Notes:

- N/A
2024-07-19 15:11:27 -04:00
Jason Lee
0a02691778 Fix tooltips sometimes continuously displaying when the button is selected (#14832)
Release Notes:

- Fixed sometime tooltip will continuously display when the button is
selected.

---

@mrnugget The #13857 This change has led into a bug, the selected item
before tooltip will continuous display if there are no other tooltips.



https://github.com/user-attachments/assets/06b4a9a4-dede-4c18-b020-e20b6090341f
2024-07-19 12:49:08 -06:00
Conrad Irwin
1dc4d4200f Add command aliases (#14826)
Co-Authored-By: <tobbe@tlundberg.com>

Release Notes:

- Added `"command_aliases"` setting to let you abbreviate commands
2024-07-19 12:48:48 -06:00
Max Brunsfeld
b22718e643 Fix log file path for dsymutil in bundle-mac 2024-07-19 11:35:31 -07:00
Max Brunsfeld
bc16c2f85d Fix error in bundle-mac 2024-07-19 11:22:46 -07:00
Max Brunsfeld
1805986d82 Suppress noisy output from dsymutil in bundle-mac 2024-07-19 11:22:46 -07:00
Marshall Bowers
ee0dfe9c44 elixir: Make start_lexical.sh executable (#14831)
This PR fixes an issue in the Lexical language server installation where
the `start_lexical.sh` script was not being made executable when
installed from GitHub.

Release Notes:

- N/A
2024-07-19 14:17:04 -04:00
Max Brunsfeld
f4074d784c Remove spurious self-hosted label for bundle-linux-arm job 2024-07-19 11:08:20 -07:00
Max Brunsfeld
e58db43ed8 Remove stray step from release nightly workflow 2024-07-19 10:49:34 -07:00
Richard Feldman
ec487d8f64 Extract completion provider crate (#14823)
We will soon need `semantic_index` to be able to use
`CompletionProvider`. This is currently impossible due to a cyclic crate
dependency, because `CompletionProvider` lives in the `assistant` crate,
which depends on `semantic_index`.

This PR breaks the dependency cycle by extracting two crates out of
`assistant`: `language_model` and `completion`.

Only one piece of logic changed: [this
code](922fcaf5a6 (diff-3857b3707687a4d585f1200eec4c34a7a079eae8d303b4ce5b4fce46234ace9fR61-R69)).
* As of https://github.com/zed-industries/zed/pull/13276, whenever we
ask a given completion provider for its available models, OpenAI
providers would go and ask the global assistant settings whether the
user had configured an `available_models` setting, and if so, return
that.
* This PR changes it so that instead of eagerly asking the assistant
settings for this info (the new crate must not depend on `assistant`, or
else the dependency cycle would be back), OpenAI completion providers
now store the user-configured settings as part of their struct, and
whenever the settings change, we update the provider.

In theory, this change should not change user-visible behavior...but
since it's the only change in this large PR that's more than just moving
code around, I'm mentioning it here in case there's an unexpected
regression in practice! (cc @amtoaer in case you'd like to try out this
branch and verify that the feature is still working the way you expect.)

Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-19 13:35:34 -04:00
Max Brunsfeld
b9a53ffa0b Add the ability to edit remote directories over SSH (#14530)
This is a first step towards allowing you to edit remote projects
directly over SSH. We'll start with a pretty bare-bones feature set, and
incrementally add further features.

### Todo

Distribution
* [x] Build nightly releases of `zed-remote-server` binaries
    * [x] linux (arm + x86)
    * [x] mac (arm + x86)
* [x] Build stable + preview releases of `zed-remote-server`
* [x] download and cache remote server binaries as needed when opening
ssh project
* [x] ensure server has the latest version of the binary


Auth
* [x] allow specifying password at the command line
* [x] auth via ssh keys
* [x] UI password prompt

Features
* [x] upload remote server binary to server automatically
* [x] opening directories
* [x] tracking file system updates
* [x] opening, editing, saving buffers
* [ ] file operations (rename, delete, create)
* [ ] git diffs
* [ ] project search

Release Notes:

- N/A

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2024-07-19 10:27:26 -07:00
Kyle Kelley
7733bf686b Repl reorder keybinding (#14824)
Ensures that the assistant keybinding for cmd-enter takes precedence
over `repl::Run`.

On Linux, `ctrl-enter` (the equivalent), issues `repl::Run` when in a
jupyter context.

Release Notes:

- N/A
2024-07-19 10:05:08 -07:00
Marshall Bowers
edddc68da6 client: Remove leftover http.rs file (#14822)
This PR removes an empty `http.rs` file that was leftover from a
previous PR.

Release Notes:

- N/A
2024-07-19 12:22:31 -04:00
Thorsten Ball
5de5d5bc56 go: Fix quoting of targeting expression for non-fish shells (#14821)
This fixes #14818.

The change in #14055 broke the tasks in `zsh` (and I suspect in `bash`,
`sh` too), because what was executed was NOT

    $ go test . -run '^TestThis$'

but instead this:

    $ go test . -run \'^TestThis$\'

And in `zsh` this means that `'` is part of the argument passed to `go`,
which means the targeting string is wrong.

Since the problem in `fish` doesn't seem to be the `^` but the `$`, we
can only escape that, which makes the escaped string work in `zsh` and
`fish` and `bash` (in which I've tested this change here)

Release Notes:

- go: Fix running single tests by changing the quoted expression in the
`go test` command to work again in `bash`, `zsh`, etc.
([#14818](https://github.com/zed-industries/zed/issues/14818))
2024-07-19 18:05:31 +02:00
Kyle Kelley
5467e18a5b repl: Refactor editor registration (#14819)
Cleans up action registration with the editors and also fixes a major
bug where only one workspace's panel was getting session info (due to my
not understanding that `cx.observe_new_views` is for the whole app).

Release Notes:

- N/A

Co-authored-by: Conrad <conrad@zed.dev>
2024-07-19 08:58:57 -07:00
Antonio Scandurra
4c7f1032a4 Allow an initial prompt to be associated with inline assist (#14816)
Release Notes:

- Added the ability to create custom inline assist bindings that
pre-fill a prompt from your keymap, e.g.:
    ```json
    [
        {
            "context": "Editor && mode == full",
            "bindings": {
                "ctrl-shift-enter": [
                    "assistant::InlineAssist",
                    { "prompt": "Build a snake game" }
                ]
            }
        }
    ]
    ```

---------

Co-authored-by: Nathan <nathan@zed.dev>
2024-07-19 17:13:48 +02:00
Antonio Scandurra
d61eaea4b9 Avoid losing focus when block decorations go offscreen (#14815)
Release Notes:

- Fixed a bug that caused focus to be lost when renames and inline
assists were scrolled offscreen.

---------

Co-authored-by: Nathan <nathan@zed.dev>
2024-07-19 17:04:18 +02:00
Richard Feldman
f5d50f2b1e Delete obsolete and unused remote_projects.rs (#14811)
See
https://github.com/zed-industries/zed/pull/11301#issuecomment-2234239630
for context

Release Notes:

- N/A
2024-07-19 08:50:49 -06:00
Kyle Kelley
be4b19babb repl: Create action to refresh kernelspecs (#14786)
Adds a command to refresh kernelspecs. Also added the kernelspecs to the
runtime panel when none are running. That's just for now until we move
out of the panel completely.

Release Notes:

- N/A
2024-07-19 07:42:18 -07:00
Marshall Bowers
272be98ec8 php: Bump to v0.1.2 (#14808)
This PR bumps the PHP extension to v0.1.2.

Changes:

- #14806

Release Notes:

- N/A
2024-07-19 09:13:23 -04:00
Marshall Bowers
e3d5eff858 Use ui::prelude::* in a few more spots (#14807)
This PR updates a couple files to make use of the `ui::prelude::*`
import.

Release Notes:

- N/A
2024-07-19 08:57:51 -04:00
Marshall Bowers
9cb17ac630 php: Respect LSP settings for Intelephense (#14806)
This PR updates the PHP extension with support for reading LSP settings
when using Intelephense as the language server.

Addresses #4258.

Release Notes:

- N/A
2024-07-19 08:51:44 -04:00
Jason Lee
fb541accb2 gpui: Update Menu name to use SharedString type to support more types (#14791)
Release Notes:

- N/A
2024-07-19 08:51:31 -04:00
Marshall Bowers
836f623800 Update icon positioning in tabs (#14804)
This PR updates the icon positioning in tabs to make give them even
spacing on either side.

Without file icons:

<img width="901" alt="Screenshot 2024-07-19 at 7 55 39 AM"
src="https://github.com/user-attachments/assets/89cc80cd-1323-424e-90a5-79d8586e8725">

With file icons:

<img width="956" alt="Screenshot 2024-07-19 at 7 55 52 AM"
src="https://github.com/user-attachments/assets/c5b47b4e-e6c3-4dbd-aeb3-fb09a0032105">

Release Notes:

- N/A
2024-07-19 08:04:57 -04:00
Kirill Bulatov
18c2e8f6ca Rework mouse handling of git hunks diff (#14727)
Closes https://github.com/zed-industries/zed/issues/12404

![Screenshot 2024-07-18 at 14 02
31](https://github.com/user-attachments/assets/a8addd22-0ed9-4f4b-852a-f347314c27ce)

![Screenshot 2024-07-18 at 14 02
43](https://github.com/user-attachments/assets/0daaed10-b9f3-4d4b-b8d7-189aa7e013b9)

Video:


https://github.com/user-attachments/assets/58e62527-da75-4017-a43e-a37803bd7b49


* now shows a context menu on left click instead of expanding the hunk
diff
* hunk diffs can be toggled with a single cmd-click still
* adds a X mark into gutter for every hunk expanded
* makes `editor::ToggleDiffHunk` to work inside the deleted hunk editors

Additionally, changes the way editor context menus behave when the
editor is scrolled — right click and diff hunks context menu now will
stick to the place it was invoked at, instead of staying onscreen at the
same pixel positions.

Release Notes:

- Improved the way git hunks diff can be toggled with mouse
([#12404](https://github.com/zed-industries/zed/issues/12404))

---------

Co-authored-by: Nate Butler <nate@zed.dev>
Co-authored-by: Conrad Irwin <conrad@zed.dev>
2024-07-19 13:48:04 +03:00
0x2CA
bf4645b1fe Fix vim <CTRL-J> slines downward linewise, Not Join Lines (#14796)
https://vimhelp.org/motion.txt.html#CTRL-J

Release Notes:

- vim: Added `ctrl-j` as a new binding that's equivalent to `j`.
2024-07-19 11:52:37 +02:00
Antonio Scandurra
4d177918c1 Start on adding support for editing via the assistant panel (#14795)
Note that this shouldn't have any visible user-facing behavior yet. The
feature is incomplete but we wanna merge early to avoid a long-running
branch.

Release Notes:

- N/A

---------

Co-authored-by: Nathan <nathan@zed.dev>
2024-07-19 11:13:15 +02:00
Conrad Irwin
87457f9ae8 Fix off-by-one errors in syntax highlighting (#14780)
In the case that a line ended with a 0-length run, we would get our
highlights offset by one position.

Release Notes:

- Fixed syntax highlights being offset from syntax in diagnostics
popovers.
2024-07-18 22:37:30 -06:00
Vishal Bhavsar
be45f32753 vim: Fix 'Y' to yank to end of line (#14783)
Instead of yanking the entire line.

Release Notes:

- vim: Updated `Y` to yank to end of line (like neovim)
https://github.com/zed-industries/zed/issues/14771
2024-07-18 22:34:40 -06:00
versecafe
18b5a87298 Add gpt-4o-mini as an available model (#14770)
Release Notes:

- Fixes #14769
2024-07-18 22:32:56 -06:00
Kyle Kelley
48211e8ce2 repl: Check process status and propagate to output (#14782)
<img width="582" alt="image"
src="https://github.com/user-attachments/assets/14bd321d-f5fc-4cc0-9386-f435423057ad">

Release Notes:

- N/A
2024-07-18 19:35:05 -07:00
Conrad Irwin
5008a388e6 Use -f in ssh remoting too (#14773)
Release Notes:

- N/A
2024-07-18 19:24:59 -06:00
versecafe
3c417864e6 typescript: Highlight using keyword (#14772)
Release Notes:

- Added syntax highlighting for the `using` keyword in TypeScript
([#14762](https://github.com/zed-industries/zed/issues/14762)).
2024-07-18 17:33:13 -04:00
Marshall Bowers
ad3055076d assistant: Allow /docs to perform JIT indexing when run (#14768)
This PR updates the `/docs` slash command with the ability to
just-in-time index a package when there are not yet any results in the
index.

When running a `/docs` slash command, we fist check to see if there are
any results in the index that would match the search.

If there are, we go ahead and return them, as we do today.

However, if there are not yet any results we kick off an indexing task
as part of the command execution to fetch the results.

Release Notes:

- N/A
2024-07-18 17:01:48 -04:00
Peter Tripp
7c63f26aa9 Add duplicate and support as core github issue labels (#14735) 2024-07-18 16:21:30 -04:00
Conrad Irwin
f15a441c9d Fix video rendering on docs (#14764)
Release Notes:

- N/A
2024-07-18 13:34:25 -06:00
Kyle Kelley
cb217381ce repl: Scroll down after running code (#14759)
Go to the next line after running code. Allows for fluid coding and
running.


https://github.com/user-attachments/assets/d11ac05d-7801-4191-b275-3b20302e54c5

Release Notes:

- N/A
2024-07-18 11:22:43 -07:00
Kevin Wang
862f5a0561 Handle supermaven account status messages (#14749)
Sets the account status state to allow the Supermaven button to move out
of the "Supermaven is initializing..." state. We also need to add the
ability to sign out and change tiers but I will do that in a separate
PR.

Release Notes:

- Improved Supermaven status messages
([#12715](https://github.com/zed-industries/zed/issues/12715)).
2024-07-18 11:22:30 -07:00
Hans
7d30175527 vim: Add repeat support for add_surround (#14746)
Fix: #14242

At present, we don't trigger the method `start_recording(cx)` to start
recording when typing add_surround, so it can't be repeated well, delete
and change actually don't increase, but when entering `d` and `c`, it
happens that these two operations are recorded, I think maybe we also
need to call `start_recording(cx)` when calling delete_surround and
change_surround, otherwise when the user modifies their shortcuts, these
two functions may not be supported by repeat

Release Notes:

- N/A
2024-07-18 11:54:59 -06:00
Hans
d044685706 vim: Adjust surrounding_markers method (#14752)
At present, when calculating some ranges, we take the `tuple_windows` to
iterate forward, which will cause some problems when the cursor is being
front, because `tuple_windows` iteration cannot iterate to the very
beginning, so there will be some cases that cannot be calculated, adjust
this method, and now it can calculate more perfectly, and the execution
speed is about the same

Release Notes:

- N/A
2024-07-18 11:53:51 -06:00
Joseph T. Lyons
0496d0db9a Add multibuffer edit video (#14757)
Release Notes:

- N/A
2024-07-18 13:45:06 -04:00
Marshall Bowers
c19e71f51e languages: Remove lingering Elm file (#14754)
This PR removes a leftover file from when Elm support was done natively.

Elm was extracted into an extension in #10432.

Release Notes:

- N/A
2024-07-18 12:41:18 -04:00
Marshall Bowers
f7ff9b0811 vue: Bump to v0.1.0 (#14748)
This PR bumps the Vue extension to v0.1.0.

Changes:

- https://github.com/zed-industries/zed/pull/14747

Release Notes:

- N/A
2024-07-18 11:39:30 -04:00
Marshall Bowers
be1ff8aee9 vue: Install a global version of TypeScript if not present in the project (#14747)
This PR updates the Vue extension with support for installing and using
its own copy of TypeScript if it can't find one in the project.

The way we resolve `typescript` is as follows:

- We check the project's `package.json` for `typescript` in either the
`devDependencies` or `dependencies`
- If found, we set the `typescript.tsdk` to
`node_modules/typescript/lib` to use the project's copy of TypeScript
- If not found, we install the latest version of `typescript` (if not
already downloaded) to the extension's `package.json` and use that
version for `typescript.tsdk`

This should resolve instances where Vue projects that do not have an
explicit `typescript` dependency—such as those using Vue with plain
JavaScript—fail to load the language server due to TypeScript not being
found.

Release Notes:

- N/A
2024-07-18 11:32:46 -04:00
Thorsten Ball
3a83fecea9 gpui: Prefer removable over integrated Metal devices (#14744)
For context, see:

-
https://github.com/zed-industries/zed/issues/5124#issuecomment-2227743811
-
https://github.com/zed-industries/zed/pull/14738#issuecomment-2236613976

Short version: on Intel MacBooks it's better to prefer integrated
(`is_low_poer()`) GPUs, except when a user has an eGPU plugged-in, in
which case they very likely want to prefer that.

Before this change, we'd always prefer the integrated GPU, even if an
eGPU was available.

Now, with this change, if a user has

- eGPU
- integrated GPU
- discrete GPU

We'd first prefer eGPU, then integrated, then discrete.



Release Notes:

- Changed preference for GPUs on macOS so that eGPUs are now preferred
over integrated ones (and both of which are preferred over discrete
GPUs) on Intel Macs.
2024-07-18 16:52:38 +02:00
CharlesChen0823
bac4a0428d project_panel: Select the newly created file when copy/pasting a file (#14705)
Closes: #14361 

Release Notes:

- Improved project panel to select newly created file on copy/paste ([#14361](https://github.com/zed-industries/zed/issues/14361))
2024-07-18 17:26:33 +03:00
Kirill Bulatov
ed3d3dc690 Improve same line diagnostic rendering (#14741)
Follow-up of https://github.com/zed-industries/zed/pull/14515

Fixed certain visual artifacts, related to multi line diagnostics and
block toggle rendering.
Also enabled diagnostics toolbar controls for the experimental view too.


Release Notes:

- N/A
2024-07-18 17:22:38 +03:00
Marshall Bowers
24d9374744 Add text_color helper for tab contents (#14737)
This PR adds a `text_color` method to `TabContentParams` to more easily
compute the text color to be used for tab contents.

This consolidates a number of conditionals that were scattered all over
the place to give us a singular source of truth for these colors.

Release Notes:

- N/A
2024-07-18 09:27:05 -04:00
Marshall Bowers
5d751f232c collab_ui: Refine channel tab appearance (#14736)
This PR refines the appearance of the channel tabs.

We now display the channel icon in the tab's icon slot. We also now
adjust the icon based on whether the channel is public or members-only
(the same we do in the channel list):

<img width="214" alt="Screenshot 2024-07-18 at 9 02 00 AM"
src="https://github.com/user-attachments/assets/973d83c5-f045-4282-a43a-18e12ce93f78">

The `read-only` and `disconnected` states are now also shown in a
visually different style than the channel name:

<img width="247" alt="Screenshot 2024-07-18 at 9 01 13 AM"
src="https://github.com/user-attachments/assets/359f61cf-3b80-4a3f-8948-d705f6c24695">

Release Notes:

- Refined the appearance of channel tabs.
2024-07-18 09:18:09 -04:00
Piotr Osiewicz
3fb3148995 lsp: Use CompletionTriggerKind::TRIGGER_CHARACTER only for characters allowlisted by the server (#14734)
Fixes #13823


Release Notes:

- N/A
2024-07-18 14:53:31 +02:00
Thorsten Ball
76ce1a8f50 lsp: Use LspCommand.check_capabilities consistently (#14733)
This is a follow-up to #14666 in which I noticed that we don't need that
additional check, since each request will check whether it's supported
via the call to `check_capabilities` before sending the request.


Release Notes:

- N/A
2024-07-18 14:38:27 +02:00
Vitaly Slobodin
80558a3986 ruby: Bump to v0.0.8 (#14707)
Bump version of the Ruby extension to 0.0.8.

Changes:

- https://github.com/zed-industries/zed/pull/12642
- https://github.com/zed-industries/zed/pull/13216
- https://github.com/zed-industries/zed/pull/14661
- https://github.com/zed-industries/zed/pull/14693

Release Notes:

- N/A
2024-07-18 08:13:36 -04:00
Buzz
cdfadcc582 docs: Introduce command palette earlier (#14467)
Can't get to many of the settings on linux without opening it, and can't
know the default keystroke to get to it without knowing where to look
first, so its a chicken-n-egg problem of needing to use a
default-keystroke to set the key bindings, esp on linux.


Release Notes:

- N/A

---------

Co-authored-by: Thorsten Ball <mrnugget@gmail.com>
2024-07-18 14:09:43 +02:00
apricotbucket28
013c9f0420 linux: Implement local time zone support (#14610)
I decided to remove the GPUI APIs since `chrono` already provides this
functionality, and is already been used for this purpose in other parts
of the code (e.g.
[here](80402a6840/crates/zed/src/main.rs (L756))
or
[here](80402a6840/crates/ui/src/utils/format_distance.rs (L258)))

These usages end up calling the `time_format` crate, which takes in a
`UtcOffset`. It's probably cleaner to rewrite the crate to take in
`chrono` types, but that would require rewriting most of the code there.

Release Notes:

- linux: Use local time zone in chat and Git blame
2024-07-18 13:42:18 +02:00
Thorsten Ball
22a2cc6950 lsp: Check which code actions are supported before request (#14666)
This fixes https://github.com/zed-industries/zed/issues/13633 by not
sending `source.organizeImports` to the ESLint language server anymore.

Turns out that ESLint tells us through its capabilities that it doesn't
support that code action kind, but we ignored that.

What this code does is to check whether a given server supports specific
code action kinds.

It does this in two places:

1. When constructing the request: we now filter down the list of
   requested `kinds`, in case we can do so. If we can't filter down the
   list, we keep the previous behavior of sending the
   `language_server.code_action_kinds()`
2. Before sending the request: we now check whether the server even
   supports sending the request.

This fixes the issue by only sending actions to servers that support it.

I tested this with various language servers and setups and everything
still works (or works better). But of course there are a ton of
different combinations of language servers and code actions and file
types, so I couldn't test them all.

Release Notes:

- Fix ESLint language server adding comments on save if the
`source.organizeImports` code action was used on save. Zed now filters
out code actions sent to the language servers by checking whether they
are supported first.
([#13633](https://github.com/zed-industries/zed/issues/13633)).
2024-07-18 13:40:06 +02:00
Thorsten Ball
49effeb7ba assistant: Fixed "quote selection" with Vim visual line mode (#14713)
Previously, when using Vim mode and doing a line-wise visual selection,
the `assistant: quote selection` action would not work correctly, since
it would ignore that these were line-wise selections.

With this change, one can now select lines using visual line mode and
"quote selection works"

Release Notes:

- Fixes `assistant: quote selection` not working correctly when making
visual-line-mode selections in Vim mode.
2024-07-18 10:30:01 +02:00
rimuy
edda634ca5 typescript: Highlight infer keyword (#14696)
This PR adds syntax highlighting to TypeScript's
[`infer`](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types)
keyword.

Theme used: Sandcastle

**Before:**

![image](https://github.com/user-attachments/assets/e082cc8c-2e12-4cfa-a641-40324dd93f31)

**After:**

![image](https://github.com/user-attachments/assets/6263b5b2-19c8-4b64-87b6-ceead947bc03)



Release Notes:

- Added syntax highlighting to TypeScript's `infer` keyword
([#14696](https://github.com/zed-industries/zed/pull/14696))
2024-07-18 10:42:17 +03:00
Elliot Thomas
75948e536f Fix worktree order serialization (#14676)
Fixes an issue in the serialization of workspaces that lead to incorrect
ordering of worktrees and refactors some other parts of the code to use
the new method.

Release Notes:

- N/A
2024-07-18 10:41:29 +03:00
Peter Tripp
eb7fe57453 Auto detect some DSLs (#14693)
- Brewfile, Vagrantfile, Puppetfile (ruby)
- Pipfile (toml)
2024-07-18 04:38:44 +00:00
Chung Wei Leong
6e08e49d30 docs: Fix tabs.file_icons default value (#14701)
Release Notes:

- Fixed `tabs.file_icons` default value in documentation, changed from
`true` to `false`
2024-07-17 23:03:57 -04:00
Marshall Bowers
2c8ead4423 Simplify constructing tab content that is purely textual (#14695)
This PR adds a streamlined way to consistently construct tab content for
items that only have textual content in the tabs.

The `Item` trait now has a new `tab_content_text` method that can be
used to return the textual content for the tab.

The `tab_content` method now has a default implementation that—unless
overridden—will construct a `Label` out of the text. This default
implementation also takes care of setting the label color based on the
active state of the tab, something that previously had to be repeated in
each `tab_content` implementation.

The majority of our tabs are now using `tab_content_text`.

Release Notes:

- N/A
2024-07-17 20:11:05 -04:00
Michael Angerman
ca2976559e docs: Fix jupyter spelling in the command jupyter kernelspec list (#14694)
jupyter was spelled wrong in the repl docs

Release Notes:

- N/A
2024-07-17 20:03:04 -04:00
Marshall Bowers
457da7b27c breadcrumbs: Use early return in set_active_pane_item (#14691)
This PR refactors the `set_active_pane_item` implementation for
`Breadcrumbs` to use an early return to avoid indenting the method body
more than necessary.

Release Notes:

- N/A
2024-07-17 18:58:44 -04:00
Marshall Bowers
a2424638f5 Improve multibuffer hints (#14690)
This PR improves the multibuffer hints added in #14668 to fix a few
issues.

The original implementation relied on bailing out early in `render` by
returning an `Empty` element. However, this had the unintended
side-effect that when initially opening a multibuffer (such as the
project search) there would be additional whitespace increasing the
height of the toolbar due to the empty element.

The reason we were doing this in the first place was because the hints
weren't updating when the item's breadcrumbs changed.

We're able to address this properly by using a subscription to the
item's events and recompute the visibility of the hint when the active
item's breadcrumbs change.

This also has the benefit of making the hints re-appear right away when
running the `welcome: reset hints` command with a multibuffer open.

Release Notes:

- N/A
2024-07-17 18:51:30 -04:00
Kyle Kelley
ba4fa17b83 Set the working directory according to the editor file path (#14688)
Kernels now launch in the same directory as the script invoking them,
similar to notebook behavior.


![image](https://github.com/user-attachments/assets/def86308-bea4-4fa3-8211-132a282a5ecc)


Release Notes:

- N/A
2024-07-17 15:37:47 -07:00
Conrad Irwin
f5f4578422 Tweak wording (#14686)
Co-Authored-By: Danilo <danilo@zed.dev>

Release Notes:

- N/A

Co-authored-by: Danilo <danilo@zed.dev>
2024-07-17 16:02:43 -06:00
Vitaly Slobodin
75775292b3 ruby: Add support for "rubocop" language server (#14661)
Hi, this pull request adds support for `rubocop` language server. I
noticed that `ruby-lsp` LS is becoming more popular but it still lacks
diagnostics support in Zed. To cover that missing feature, it could be
good to use `rubocop` LS to show diagnostics alongside with the running
Ruby LSP.

Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
2024-07-17 17:29:42 -04:00
Justin Su
344e315174 Add -f to curl commands (#14667)
Release Notes:

- Updated curl commands with `-f` for improved error handling
([#14346](https://github.com/zed-industries/zed/issues/14346)).
2024-07-17 15:27:32 -06:00
Marshall Bowers
8ef53aafa2 Have Danger check the format of GitHub issue links (#14684)
This PR updates the Danger rules to check for GitHub issue links that
aren't in the desired format:

<img width="916" alt="Screenshot 2024-07-17 at 5 11 48 PM"
src="https://github.com/user-attachments/assets/c77d3c28-3b09-44aa-a97f-03c2400df2e6">

We don't yet check that the links are exactly formatted as expected,
just that they aren't incorrectly formatted in the way that people
typically get it wrong.

Release Notes:

- N/A
2024-07-17 17:15:47 -04:00
Marshall Bowers
00c3c02f7d Render other tab icons in the start slot (#14683)
This PR reworks the rendering for tab icons to allow us to render all of
the tab icons—not just file icons—in the tab's start slot.

The `Item` trait now has a separate `tab_icon` method that can be used
to indicate what icon should be shown for the tab.

Release Notes:

- N/A
2024-07-17 16:59:41 -04:00
Nazar Matus
2edf224599 docs: Add openSUSE Tumbleweed to Linux installation options (#14642)
Add openSUSE Tumbleweed to the list

Release Notes:

- N/A
2024-07-17 14:22:55 -06:00
Congyu
16a4c59be0 Fix right clicks changing vim mode (#14626)
Release Notes:

- Fixed right clicks changing vim mode (#14625).

before:


https://github.com/user-attachments/assets/97f4c971-6b59-412d-844a-23e0bc4289aa

after:


https://github.com/user-attachments/assets/3fc9adf3-2572-428d-8674-b3c8317e457e
2024-07-17 14:19:35 -06:00
Conrad Irwin
90a46b0463 linux: Fix autoupdate in non-standard locations (#14624)
Release Notes:

- linux: Fixed auto-update into custom tarball locations (#14291)
2024-07-17 14:15:28 -06:00
Conrad Irwin
09b216cf5e Make project search feel better (#14674)
Release Notes:

- Improved UX of project search

---------

Co-authored-by: Marshall <marshall@zed.dev>
2024-07-17 14:14:46 -06:00
Marshall Bowers
84b34677e2 Exclude dev extensions from auto-updates (#14680)
This PR makes it so dev extensions that are installed are excluded when
checking for extension updates.

We don't want to accidentally clobber dev extensions if the upstream
extension is deemed more "up-to-date".

Release Notes:

- Changed dev extensions to be excluded from extension auto-updates.
2024-07-17 15:35:09 -04:00
Marshall Bowers
5a090bc3f3 Dim the shared screen tab's icon when it is inactive (#14678)
This PR makes it so the icon of the shared screen tab is properly dimmed
when the tab is inactive.

Release Notes:

- Fixed an issue where the shared screen tab's icon would not render as
dimmed when the tab was inactive.
2024-07-17 15:25:56 -04:00
Conrad Irwin
4852e170ff Introducing multibuffers (#14668)
Co-Authored-By: Marshall <marshall@zed.dev>

Release Notes:

- Added a hint the first few times you open a multibuffer to explain
what is going on.

Co-authored-by: Marshall <marshall@zed.dev>
2024-07-17 13:54:52 -04:00
Joseph T Lyons
53bcc3649a Add PR author to release notes scraper script 2024-07-17 13:20:19 -04:00
Thorsten Ball
9241b11e1f Restore unsaved buffers on restart (#13546)
This adds the ability for Zed to restore unsaved buffers on restart. The
user is no longer prompted to save/discard/cancel when trying to close a
Zed window with dirty buffers in it. Instead those dirty buffers are
stored and restored on restart.

It does this by saving the contents of dirty buffers to the internal
SQLite database in which Zed stores other data too. On restart, if there
are dirty buffers in the database, they are restored.

On certain events (buffer changed, file saved, ...) Zed will serialize
these buffers, throttled to a 100ms, so that we don't overload the
machine by saving on every keystroke. When Zed quits, it waits until all
the buffers are serialized.


### Current limitations
- It does not persist undo-history (right now we don't persist/restore
undo-history regardless of dirty buffers or not)
- It does not restore buffers in windows without projects/worktrees.
Example: if you open a new window with `cmd-shift-n` and type something
in a buffer, this will _not_ be stored and you will be asked whether to
save/discard on quit. In the future, we want to fix this by also
restoring windows without projects/worktrees.

### Demo



https://github.com/user-attachments/assets/45c63237-8848-471f-8575-ac05496bba19



### Related tickets

I'm unsure about closing them, without also fixing the 2nd limitation:
restoring of worktree-less windows. So let's wait until that.

- https://github.com/zed-industries/zed/issues/4985
- https://github.com/zed-industries/zed/issues/4683

### Note on performance

- Serializing editing buffer (asynchronously on background thread) with
500k lines takes ~200ms on M3 Max. That's an extreme case and that
performance seems acceptable.

Release Notes:

- Added automatic restoring of unsaved buffers. Zed can now be closed
even if there are unsaved changes in buffers. One current limitation is
that this only works when having projects open, not single files or
empty windows with unsaved buffers. The feature can be turned off by
setting `{"session": {"restore_unsaved_buffers": false}}`.

---------

Co-authored-by: Bennet <bennet@zed.dev>
Co-authored-by: Antonio <antonio@zed.dev>
2024-07-17 18:10:20 +02:00
Joseph T Lyons
8e9e94de22 v0.146.x dev 2024-07-17 11:29:16 -04:00
Marshall Bowers
1607e4e0e1 elixir: Bump to v0.0.6 (#14657)
This PR bumps the Elixir extension to v0.0.6.

Changes:

- #14655

Release Notes:

- N/A
2024-07-17 11:14:52 -04:00
Marshall Bowers
ceffc7e1cf elixir: Respect LSP settings for Lexical (#14655)
This PR updates the Elixir extension with support for reading the LSP
settings when using Lexical as the language server.

Release Notes:

- N/A
2024-07-17 11:04:34 -04:00
Thorsten Ball
e69b995a3b zig: Bump to v0.1.4 (#14651)
This PR bumps the Zig extension to v0.1.4.

Changes:

- #14379

Release Notes:

- N/A
2024-07-17 10:41:12 -04:00
Marshall Bowers
f19b51c0b2 zig: Revert changes dependent on new zed_extension_api (#14652)
This PR reverts the changes to the Zig extension dependent on the new
`zed_extension_api` version so that we can publish the Zig extension.

Release Notes:

- N/A
2024-07-17 10:40:25 -04:00
Marshall Bowers
1d2d3b209e svelte: Bump to v0.0.3 (#14650)
This PR bumps the Svelte extension to v0.0.3.

Changes:

- #14614

Release Notes:

- N/A
2024-07-17 10:20:50 -04:00
Marshall Bowers
959fbd5e45 docs: Fix typo in Svelte docs (#14649)
This PR fixes a typo in the Svelte docs to reflect the fixes from
#14614.

Release Notes:

- N/A
2024-07-17 10:08:20 -04:00
Nemo
ff85f1d608 Fix default sublime tab navigation (#14427)
Co-authored-by: Peter Tripp <peter@zed.dev>
2024-07-17 10:07:46 -04:00
Peter Tripp
d1300b7a66 Linux Keybinding Improvements (#14600)
- Fixed ctrl-shift-d (duplicate line) conflict.
- Fixes #14458
- Remove some duplicated definitions
- Fix Expand/Shrink selection (was ctrl-shift-up/down, now alt-shift-left/right)
- Add `ctrl-f2` / `cmd-f2` as alias for `editor::SelectAllMatches` matching VSCode
- Moved multi-cursor (Insert cursor above / below) from ctrl-shift-up/down to alt-shift-up/down
2024-07-17 10:06:47 -04:00
Mathias
62f5503e93 svelte: Fix typo in LSP config for inlayHints (#14614)
9b51c5b177/packages/service/configuration.schema.json (L158)

Before:
![Screenshot from 2024-07-17
02-45-37](https://github.com/user-attachments/assets/15f67b7b-ed29-418a-b6a5-23601c1ad820)

After:
![Screenshot from 2024-07-17
02-38-37](https://github.com/user-attachments/assets/c6cb71fc-70f4-4ea3-91d4-a184342163b4)

Release Notes:

- N/A
2024-07-17 09:59:21 -04:00
Kyle Kelley
738d079aa7 docs: Remove extra backtick within repl docs (#14611) 2024-07-17 06:59:05 -07:00
Marshall Bowers
4feb994ad8 php: Bump to v0.1.1 (#14647)
This PR bumps the PHP extension to v0.1.1.

Changes:

- #14643

Release Notes:

- N/A
2024-07-17 09:40:00 -04:00
Marshall Bowers
40ed3b6977 php: Allow using intelephense from PATH (#14643)
This PR updates the PHP extension to use `intelephense` from the PATH,
if it exists.

Tested using the following Nix shell:

```sh
NIXPKGS_ALLOW_UNFREE=1 nix-shell -p php nodePackages_latest.intelephense
```

Resolves #11994.

Release Notes:

- N/A
2024-07-17 09:20:31 -04:00
Mathias
bd02f4fe28 Respect user preference for JS/TS on_type formatting (#14536)
Release Notes:

- Fix user preferences for JS/TS on_type formatting not being respected by VTSLS.
([#13733](https://github.com/zed-industries/zed/issues/13733),
[#14499](https://github.com/zed-industries/zed/issues/14499))
2024-07-17 11:11:00 +02:00
Conrad Irwin
85bc233920 vim: Add :bd/:bp/:bn (#14623)
Also refactor command to be less wierd

Release Notes:

- vim: Added :bd/:bn/:bp (#14457)
2024-07-16 23:06:08 -06:00
Conrad Irwin
33f68882c1 vim: Fix ctrl-d/u going to top bottom (#14620)
Release Notes:

- vim: Fixed ctrl-d/ctrl-u getting to top/bottom of buffer (#13250)
2024-07-16 22:56:44 -06:00
Conrad Irwin
acc9c2421b Vim rename via menu too? (#14617)
Follow up to #14320

Release Notes:

- N/A
2024-07-16 21:00:00 -06:00
Conrad Irwin
2cdfae9ce3 Show an initial empty keymap (#14609)
Release Notes:

- Added default content for the user keymap file.
2024-07-16 20:24:13 -06:00
Soroush Mirzaei
cf92b83c04 Update install CLI message for linux (#14616)
This PR updates the `cli: install` message for Linux. It initially threw
me off thinking that because `path_for_auxiliary_executable` is not
implemented for Linux it's failing and I thought it's a bug. Turns out
the CLI gets installed by the package manager and it's just named
something else.

I ended up only updating the message so it's more clear. If you don't
like the message, let me know :)

The old message:

![image](https://github.com/zed-industries/zed/assets/829535/1a02d08d-2c7a-452a-bfee-dc55d29c0c10)

The new message:

![image](https://github.com/user-attachments/assets/82052a43-1cf5-4b86-88e8-1c1f01a0ae3c)

@ConradIrwin thank you for taking the time and explaining it to me.

closes: #14118

Release Notes:

- N/A
2024-07-16 20:23:10 -06:00
Kyle Kelley
252737aef4 Provide installation instructions for the R extension (#14601)
Release Notes:

- N/A
2024-07-16 15:51:40 -07:00
Kyle Kelley
9c43450fef repl: Don't send KernelInfoRequest on launch (#14608)
Closes #14146. This is just for the time being before a networking
refactoring to split reads and writes on the ROUTER/DEALER ZeroMQ
sockets. Some kernels have not been responding with `kernel_info_reply`,
which ends up hanging our shell socket.

Release Notes:

- N/A

Release notes for the REPL feature will be part of its official launch.
2024-07-16 15:51:23 -07:00
Marshall Bowers
f8cfb50bb4 php: Bump to v0.1.0 (#14607)
This PR bumps the PHP extension to v0.1.0.

Changes:

- #14603
- #14604

Release Notes:

- N/A
2024-07-16 18:49:58 -04:00
Danilo Leal
9499adf50d docs: Adjust the note and warning callout design (#14605)
So they're more consistent and polished. Felt like they could be a bit more refined.

---

Release Notes:

- N/A
2024-07-16 19:48:02 -03:00
Marshall Bowers
696591ca55 php: Add Phpactor support (#14604)
This PR extends the PHP extension with
[Phpactor](https://github.com/phpactor/phpactor) support.

Phpactor seems to provide a better feature set out-of-the-box for free,
so it has been made the default PHP language server.

Thank you to @xtrasmal for informing us of Phpactor's existence!

Release Notes:

- N/A
2024-07-16 18:39:13 -04:00
Alexander Mankuta
f9b0792aa0 Update Configuration docs (#14029)
Release Notes:

- N/A

---

I'd like to help improve Configuration documentation.

Currently I'm often confused by the configuration doc. It's incomplete:
not all settings are documented. It's disorganized: some options are
grouped together but overall there's not much structure or logic to it.
It's inconsistent: some examples show only key and value, some—just the
closes object, and others full nesting. It's confusing: individual keys
are listed but it's hard to understand where in the config structure
they belong.

I suggest the following changes:

- Always specify the full path of the setting
- Document all settings Zed recognises
- List settings in alphabetical order of their full path
- Always use full nesting in examples 

This is an example, of what it might look like. It's first draft, too.
So I'm open to suggestions.

Please let me know if you're interested in this. The whole thing might
need a bit of effort so I'd like to know if this is something you might
want before doing all the work.

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-07-16 16:11:55 -06:00
Marshall Bowers
60b22cf029 php: Upgrade zed_extension_api to v0.0.6 (#14603)
This PR upgrades the PHP extension to use v0.0.6 of the
`zed_extension_api`.

Release Notes:

- N/A
2024-07-16 17:53:43 -04:00
Conrad Irwin
1fe16f42ea Fix context in command palette from application menu (#14599)
Supercedes #14468

Release Notes:

- linux: Fixed the command palette when opened from the application menu
2024-07-16 15:14:18 -06:00
Peter Tripp
448ef538b3 More ignorable commits (#14596)
- More of https://github.com/zed-industries/zed/pull/13889
2024-07-16 17:09:50 -04:00
Kyle Kelley
f612c40bee repl: Don't run empty code submission (#14598)
Closes #14565.

Release Notes:

- N/A
2024-07-16 13:51:46 -07:00
Cappy Ishihara
0c6105992c Open URIs from the CLI, support for the zed:// URI scheme on Linux (#14104)
Allows Zed to open custom `zed://` links (redirects from
https://zed.dev/channels) on Linux used XDG MIME types.

This PR also allows the CLI to be able to open Zed (`zed://`) URIs
directly instead of executing the main executable in
`/usr/libexec/zed-editor`.


Release Notes:

- Linux: Allow `zed.dev/channel` (`zed://`) URIs to open on Linux
- CLI: Ability to open URIs from the command line

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-07-16 14:49:15 -06:00
Congyu
64a796d436 Fix renaming sometimes not working in vim mode (#14320)
Disable vim key contexts during renaming, to fix renaming being
interfered with vim commands.

Release Notes:

- Fixed renaming sometimes not working in vim mode
[#14292](https://github.com/zed-industries/zed/issues/14292)
[#11882](https://github.com/zed-industries/zed/issues/11882).
- Fixed inline assistant sometimes not working in vim mode #11559

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-07-16 14:46:03 -06:00
Conrad Irwin
76594ae5cd vim: fix escape while waiting (#14595)
Follow up from #14233

Release Notes:

- N/A
2024-07-16 14:08:05 -06:00
Robert Sturla
05de1dc8d2 Rename Linux desktop icon to match application name (#14437)
Release Notes:

- Updated the Linux manual installation docs to fix windows not matching
with desktop icons
([#14435](https://github.com/zed-industries/zed/issues/14435)).

The automated `curl | bash` installation script already renames the
`zed.desktop` file to match the window, so most users will not be facing
this issue. This is only affecting users who have downloaded and
extracted the files following the manual instructions.

Since the app ID and the desktop file name are not the same, open
windows are not being matched with the desktop icons, therefore showing
a default one. This PR changes the documentation to tell users they
should rename the `.desktop` file to `dev.zed.Zed.desktop`, and
therefore match the automated install script.

Before:

![image](https://github.com/user-attachments/assets/324b91e6-dae1-4902-b59c-b4f124a29820)

After:

![image](https://github.com/user-attachments/assets/169a4e8c-5c84-4400-8f0d-30cf478ca272)
2024-07-16 13:42:16 -06:00
Marshall Bowers
ef5305869f collab: Fix exact extension filtering (#14591)
This PR fixes the exact extension filtering introduced in #14588.

As we traversed the extensions we were always updating `exact_match`,
regardless of whether it matched the extension ID from the filter.

Release Notes:

- N/A
2024-07-16 15:18:48 -04:00
Kyle Kelley
8028e7f1b6 Refactor repl context menu (#14587) 2024-07-16 12:18:06 -07:00
Conrad Irwin
cb6fc11abc Rank exact extension ID matches higher in search results (#14588)
Release Notes:

- Improved relevance of extension search results

Co-authored-by: Marshall <marshall@zed.dev>
2024-07-16 12:33:28 -06:00
Conrad Irwin
cf8bd4a90a Remoting public alpha (#14541)
Release Notes:

- remoting: An alpha version of remote development is now available to
everyone. For more information on how to use it, and limitations see
https://zed.dev/docs/remote-development.
2024-07-16 12:05:55 -06:00
Conrad Irwin
62ab6e1a11 remoting: Allow Add/Remove remote folder (#14532)
Release Notes:

- remoting (alpha only): Allow add/remove folders to projects

---------

Co-authored-by: Max <max@zed.dev>
2024-07-16 12:01:59 -06:00
aohanhongzhi
be1387fee6 Fix text appearing twice after Chinese character input (#14558)
Release Notes:

- Fixed the issue where text appears twice in the editor after Chinese
Character input.([linux: Fix IME on
fcitx](https://github.com/zed-industries/zed/pull/14508)).

Before:

![zed2](https://github.com/user-attachments/assets/e387d70b-ca91-49c8-93e4-850f9e3ef227)

After Fixed:

![zed](https://github.com/user-attachments/assets/8307c12f-30a7-4e82-8c65-d0b53bb8cf44)
2024-07-16 10:54:53 -07:00
apricotbucket28
09459fa3a4 wayland: Fix drag and drop for paths with spaces (#14574)
This wasn't doing any proper parsing before, so `%20` or similar encoded
characters weren't handled correctly.

Release Notes:

- N/A
2024-07-16 10:42:57 -07:00
Marshall Bowers
400ae9c650 extensions_ui: Add feature upsell for Go (#14586)
This PR adds a feature upsell for Go when searching for it in the
extensions view.

Release Notes:

- N/A
2024-07-16 13:33:03 -04:00
Marshall Bowers
f9472ce90b extensions_ui: Add telemetry for docs click-throughs from feature upsells (#14583)
This PR adds some telemetry when the "View docs" button is clicked on a
feature upsell.

The goal here is to get a sense for how effective these upsells are at
getting users to click through if they can't find what they're looking
for.

Release Notes:

- N/A
2024-07-16 12:59:51 -04:00
Marshall Bowers
0556eddc21 docs: Add Git page (#14582)
This PR adds a basic Git page to the docs so that we have somewhere to
link to from the Git upsell within Zed.

Release Notes:

- N/A
2024-07-16 12:47:18 -04:00
Piotr Osiewicz
09c497f744 editor: Ensure allocation reuse (#14577)
In #14567 I claimed that the underlying allocation is reused. And it
was. At the time I've submitted a PR I was using `.filter_map(|x| x)`,
which got flagged by clippy as something that could be simplified to
`.flatten()` - that however broke the allocation reuse promise.

Thus, this PR goes back to using `filter_map` and additionally in debug
builds it performs checks for allocation reuse. With .flatten in place,
a bunch of unit test fail on that branch, so the checks do work.



Release Notes:

- N/A
2024-07-16 18:29:45 +02:00
Marshall Bowers
1b85438df9 docs: Fix casing of "REPL" in sidebar (#14579)
This PR fixes the casing of the REPL link in the sidebar.

Release Notes:

- N/A
2024-07-16 12:17:45 -04:00
Kyle Kelley
b3d0ac3e3c Show how to switch out kernels and discover them (#14531)
A few new doc changes for the repl feature.

Release Notes:

- N/A
2024-07-16 09:12:50 -07:00
Mag Mell
a51a9b0354 docs: Add AOSC OS Installation (#14575)
Added AOSC OS Installation docs

Release Notes:

- N/A
2024-07-16 12:07:17 -04:00
Conrad Irwin
6cf6614c48 Fix xkbcommon overflow more (#14571)
Release Notes:

- linux: Fixed overflow in xkbcommon-rs
2024-07-16 09:06:38 -06:00
Peter Tripp
0bf0152b74 Fix GoForward shortcut on non-US keyboard layouts (#14570)
- Fixes #14418. Originally broken by #13946
2024-07-16 11:00:15 -04:00
Piotr Osiewicz
d338e4a8a6 editor: Improve performance of edit coalescing (#14567)
# Background
In https://github.com/zed-industries/zed/issues/14408 we received a
repro for "Replace all" being slow, even after the work I did
https://github.com/zed-industries/zed/pull/13654. Admittedly #13654 was
a pretty straightforward change.
Under the profiler it turned out that we're spending *10 seconds* in
`memmove` on main thread. Ugh. Not great. The direct ancestor of the
memmove call was
66f0c390a8/crates/editor/src/display_map/tab_map.rs (L108-L119)

What?

# Accidental O(n^2)
We have a bunch of `consolidate_*_edits` functions which take a list of
Fold/Tab/Inlay/Wrap edits and merge consecutive edits if their ranges
overlap/are next to one another. The loop usually goes as follows:
```
while ix < edits.len() {
    let (prev_edits, next_edits) = edits.split_at_mut(ix);
    let prev_edit = prev_edits.last_mut().unwrap();
    let edit = &next_edits[0];
    if PREV_EDIT_CAN_BE_MERGED_WITH_CURRENT_ONE {
        MERGE_EDITS(prev_edit, edit);
        edits.remove(ix); // !!
    } else {
        ix += 1;
    }
}
```
The problem is the call to `.remove` - it has to shift all of the
consecutive elements in the `edits` vector! Thus, when processing the
edits from the original repro (where consolidation shrinks the edit list
from 210k entries to 30k), we mostly spend time moving entries in memory
around.

Thus, the original repro isn't really an issue with replace_all; it's
just that replace_all is one of the few tools available to the end user
that can apply large # of edits in a single transaction.

# Solution
In this PR I address the issue by rewriting the loop in a way that does
not throw items away via `.remove`. Instead, `Iterator::scan` is used,
which lets us achieve the same logic without having the pitfalls of
`.remove`s.
Crucially, **this code does not allocate a new backing buffer for
edits** (see [this article for
rationale](https://blog.polybdenum.com/2024/01/17/identifying-the-collect-vec-memory-leak-footgun.html));
with `vec.into_iter().scan().filter_map().collect()` we still use the
same underlying buffer as the one that's passed into `consolidate_*`
functions. In development I verified that by checking whether the
pointers to backing storage of a Vec are the same before and after the
consolidation.

# Results

### Before
Nightly 0.145.0
[66f0c390a8](66f0c390a8)


https://github.com/user-attachments/assets/8b0ad3bc-86d6-4f8a-850c-ebb86e8b3bfc

(~13s end-to-end)
### After


https://github.com/user-attachments/assets/366835db-1d84-4f95-8c74-b1506a9fabec

(~2s end-to-end)

The remaining lag is (I think) lies in `TextSummary` calculation and not
the consolidation itself. Thus, for the purposes of scoping this PR,
I'll tackle it separately.

Release Notes:

- Significantly improved performance of applying large quantities of
concurrent edits (e.g. when running "Replace all").
2024-07-16 15:53:29 +02:00
Thorsten Ball
751508b6a2 linux: Install dependencies when bundling nightly (#14566)
Release Notes:

- N/A
2024-07-16 15:44:24 +02:00
Thorsten Ball
f54f5dff65 linux: Build Nightly for ARM too (#14562)
Release Notes:

- N/A
2024-07-16 15:19:38 +02:00
Thorsten Ball
66f0c390a8 linux: Fix missing licenses in binary causing panics (#14561)
Turns out that the existing CI step for Nightly did create the licenses
and they have been baked into X86 builds ever since, because our
builders are stateful.

On ARM machines, the licenses wouldn't exist in the binary because we
called `script/generate-licenses` too late in `scripts/bundle-linux`,
after the binary had been created.

This removes the duplication and generates the licenses once, before the
binary is created.

Fixes #14302.

Release Notes:

- Fixed "View Dependency Licenses" (or `zed: open licenses`) crashing on
Linux ARM machines.
([#14302](https://github.com/zed-industries/zed/issues/14302)
2024-07-16 14:55:30 +02:00
Danilo Leal
fdd233eea9 Change the context menu and Copilot settings icon (#14501)
Felt the link we were using for menu items that open a browser page was
not the best. That one is most typically used for attachments within
scope, as opposed to opening external links. Noticed that via the
"Copilot Settings" menu, which also felt like it could have a bit more
descriptive label. Also reduced the size of the rendered icon in this
component.

---

Release Notes:

- N/A
2024-07-16 09:40:40 -03:00
Kirill Bulatov
bf7e474bbc Properly fix the tab icons 2024-07-16 14:46:16 +03:00
Kirill Bulatov
2a8cee57c9 Keep initial tab config without the icons (#14553)
Based on
https://zed-industries.slack.com/archives/C04S5TU0RSN/p1721125498461089

Release Notes:
- N/A
2024-07-16 13:43:17 +03:00
CharlesChen0823
ef20afa9a4 project_panel: Fixed open in split not working in project panel (#14535)
Release Notes:

- Fixed `cmd-double click` in project panel not opening a split view ([14465](https://github.com/zed-industries/zed/issues/14465))
2024-07-16 09:17:58 +03:00
Conrad Irwin
e413823ae7 Headless extensions (#14538)
Release Notes:

- remoting (alpha only): Fix extension installation
2024-07-16 00:08:56 -06:00
Kyle Kelley
e68d9f4625 Switch to muted color for kernel output labels (#14529)
Sets the text for "Executing...", "Queued", etc. to be `Color::Muted`

<img width="442" alt="image"
src="https://github.com/user-attachments/assets/10c27ce2-b804-41a3-a50e-0778b7e6cd09">


Release Notes:

- N/A
2024-07-15 18:20:45 -07:00
apricotbucket28
3407256aa3 linux: Tweak file chooser dialogs (#14526)
Mostly some small tweaks to the file chooser dialogs.

Fixes https://github.com/zed-industries/zed/issues/14127 (along with the
`ashpd` update in https://github.com/zed-industries/zed/pull/14401)

Also included a fix
(971d67c994)
for an issue that made multiple file chooser dialogs pop up on Wayland
when doing CTRL + O and quickly pressing the escape key.

Release Notes:

- N/A
2024-07-15 17:27:46 -07:00
Conrad Irwin
abc5abcd8b open picker (#14524)
Release Notes:

- linux: Added a fallback Open picker for when XDG is not working
- Added a new setting `use_system_path_prompts` (default true) that can
be disabled to use Zed's builtin keyboard-driven prompts.

---------

Co-authored-by: Max <max@zed.dev>
2024-07-15 17:04:15 -06:00
Marshall Bowers
da33aac156 extensions_ui: Remove commented-out code (#14525)
This PR removes some commented-out code from the `extensions_ui`.

Release Notes:

- N/A
2024-07-15 19:00:49 -04:00
Marshall Bowers
1818fef32f Display file icons in tabs (#14523)
This PR adds support for displaying file icons in tabs.

The `tabs.file_icons` setting controls whether the icons are displayed:

```json
{
  "tabs": {
    "file_icons": false
  }
}
```

This setting defaults to `true`.

<img width="1566" alt="Screenshot 2024-07-15 at 6 17 26 PM"
src="https://github.com/user-attachments/assets/86dfc8c9-764c-453d-95e4-2ec95d6fe715">

<img width="1566" alt="Screenshot 2024-07-15 at 6 24 26 PM"
src="https://github.com/user-attachments/assets/4b4e8489-49d3-41bf-b4cb-59365bdd3e9d">

Release Notes:

- Added file icons to buffer tabs
([#12138](https://github.com/zed-industries/zed/issues/12138)).
- If desired, these icons can be removed using `"tabs": { "file_icons":
false }`.
2024-07-15 18:33:08 -04:00
Marshall Bowers
2ae1a472e4 Upsell built-in features on the extensions page (#14516)
This PR extends the extensions page with support for upselling built-in
Zed features when certain keywords are searched for.

This should help inform users about features that Zed has out-of-the-box
when they go looking for them as extensions.

For example, when someone searches "vim":

<img width="1341" alt="Screenshot 2024-07-15 at 4 58 44 PM"
src="https://github.com/user-attachments/assets/b256d07a-559a-43c2-b491-3eca5bff436e">

Here are more examples of what the upsells can look like:

<img width="1341" alt="Screenshot 2024-07-15 at 4 54 39 PM"
src="https://github.com/user-attachments/assets/1f453132-ac14-4884-afc4-7c12db47ad1d">

Release Notes:

- Added banners for built-in Zed features when corresponding keywords
are used in the extension search.
2024-07-15 17:10:01 -04:00
Kirill Bulatov
d7a25c1696 Add an experimental, WIP diagnostics grouping panel (#14515)
Provide a current, broken state as an experimental way to browse
diagnostics.
The diagnostics are grouped by lines and reduced into a block that, in
case of multiple diagnostics per line, could be toggled back and forth
to show more diagnostics on the line.
Use `grouped_diagnostics::Deploy` to show the panel.

Issues remaining:
* panic on warnings toggle due to incorrect excerpt manipulation
* badly styled blocks
* no key bindings to navigate between blocks and toggle them
* overall odd usability gains for certain groups of people

Due to all above, the thing is feature-gated and not exposed to regular
people.


Release Notes:

- N/A
2024-07-15 22:58:18 +03:00
Eric Skogen
2c6cb4ec16 Fix Cmd+\ for workspace::ToggleLeftDock for Atom base keymap (#14098)
Release Notes:

- Fixed Left Dock in Atom keymap on Mac/Linux (`cmd-\`, `ctrl-\`) 
 ([#14098](https://github.com/zed-industries/zed/pull/14098), thanks [@audionerd](https://github.com/audionerd)).

---------

Co-authored-by: Peter Tripp <peter@zed.dev>
2024-07-15 15:56:10 -04:00
Marshall Bowers
143035b1ed gpui_macros: Extract border_style_methods macro (#14514)
This PR extracts a separate `border_style_methods` macro so that it can
be used independently from `style_helpers!`.

Release Notes:

- N/A
2024-07-15 15:51:29 -04:00
Nate Butler
fa3d29087d Add REPL dropdown menu to toolbar (#14493)
TODO: 


- [x] Actions run from menu not firing
- [x] Menu differentiates idle and busy for running kernel

Menu States:
- [x] No session && no support known

No session && no kernel installed for languages of known support
- (TODO after) Intro to REPL
- [x] Link to docs

No session but can start one
- [x] Start REPL
- (TODO after) More info -> Docs?

Yes Session

- [x] Info: Kernel name, language
  example: chatlab-3.7-adsf87fsa (Python)
  example: condapy-3.7 (Python)
- [x] Change Kernel -> https://zed.dev/docs/repl#change-kernel
- ---
- [x] Run
- [x] Interrupt
- [x] Clear Outputs
- ---
- [x] Shutdown


(Release notes left empty as the change will be documented in the REPL
release!)

Reserved for a follow on PR:

```
- [ ] Status should update when the menu is open (missing `cx.notify`?)
- [ ] Shutdown all kernels action
- [ ] Restart action
- [ ] [Default kernel changed - restart (this kernel) to apply] // todo!(kyle): need some kind of state thing that says if this has happened
```


Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2024-07-15 11:55:49 -07:00
Conrad Irwin
1856320516 Add mouse handling to gpui input example (#14350)
Release Notes:

- N/A

---------

Co-authored-by: Jason Lee <huacnlee@gmail.com>
2024-07-15 12:10:25 -06:00
Conrad Irwin
b58abb171f linux: Hide Install CLI from welcome (#14506)
Release Notes:

- linux: Remove "Install CLI" from welcome, it is not necessary
2024-07-15 12:08:37 -06:00
Conrad Irwin
868455f978 linux: Fix IME on fcitx5 (#14508)
Release Notes:

- linux: Fix IME under fcitx5 (#14192)
2024-07-15 12:07:19 -06:00
Conrad Irwin
c27c41274a linux: re-add open fallback (#14359)
Release Notes:

- linux: Fixed opening urls/directories on systems where the xdg desktop
portal doesn't handle those requests.
2024-07-15 11:11:38 -06:00
makeProjectGreatAgain
0b0de8ca83 Display hint to add PATH for Fish shell too (#14504)
tested on `fish 3.7.1 (released March 19, 2024)`
___

Release Notes:

- N/A
2024-07-15 11:11:09 -06:00
apricotbucket28
f3ddd18201 linux: Show warning if file picker portal is missing (#14401)
This PR adds a warning when the file chooser couldn't be opened on Linux

It's quite confusing when trying to open a file and apparently nothing
happens:

fixes https://github.com/zed-industries/zed/issues/11089,
https://github.com/zed-industries/zed/issues/14328,
https://github.com/zed-industries/zed/issues/13753#issuecomment-2225812703,
https://github.com/zed-industries/zed/issues/13766,
https://github.com/zed-industries/zed/issues/14384,
https://github.com/zed-industries/zed/issues/14353,
https://github.com/zed-industries/zed/issues/9209


![image](https://github.com/user-attachments/assets/5acabdaa-7a9d-4225-9480-e371d20387c3)


Release Notes:

- N/A
2024-07-15 09:36:39 -07:00
Ephram
5d860e2286 Fix selectable popover dismissing on key press (#14368)
Release Notes:

- Fixed dismissal bug included in #12918
2024-07-15 09:11:14 -06:00
Peter Tripp
e26dbe2c5b Add linux Zed log location to crash report github issue template (#14373)
Release Notes:

- N/A
2024-07-15 09:27:12 -04:00
Peter Tripp
3c38be59b5 Add keyboard shortcuts to center scrolling around current line (#14385)
- MacOS: Center the cursor in the visible area. `ctrl-l` (matches MacOS)
- Linux JetBrains: Scroll so cursor is at the Middle `ctrl-m`
- `editor::NextScreen` is not longer bound in any keymap by default (was
`ctrl-l` on MacOS)

Fixes #5247
2024-07-15 09:26:53 -04:00
Danilo Leal
e50811c425 Adjust list item & pickers spacing (#14250) 2024-07-15 10:23:18 -03:00
Piotr Osiewicz
c1aa4d939c rust: Expose import names in completions for modules and functions (#14490)
Release Notes:

- Improved accuracy of completion lists for Rust functions and modules.
2024-07-15 14:26:39 +02:00
Antonio Scandurra
e8d674dc04 Show cursors for shared contexts (#14484)
Release Notes:

- N/A

Co-authored-by: Nathan <nathan@zed.dev>
2024-07-15 12:42:10 +02:00
Nathan Sobo
f0279e672a Add Gemini models to cloud enum (#14482)
Release Notes:

- N/A
2024-07-15 12:21:58 +02:00
Max Brunsfeld
98b95d9a51 Introduce /symbols command in assistant panel (#14360)
Release Notes:

- Added `/symbols` command in assistant panel.

---------

Co-authored-by: Antonio <antonio@zed.dev>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Nathan <nathan@zed.dev>
2024-07-15 11:51:32 +02:00
Antonio Scandurra
decdd3b6ac Introduce following for assistant panel (#14479)
Release Notes:

- Added support for following into the assistant panel.

---------

Co-authored-by: Max <max@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Nathan <nathan@zed.dev>
2024-07-15 11:36:27 +02:00
Kirill Bulatov
977a1b7a82 Support dynamic formatting capabilities [un]registration (#14478)
Closes https://github.com/zed-industries/zed/issues/12661

Release Notes:

- Added dynamic [un]registration for LSP formatting capabilities
([#12661](https://github.com/zed-industries/zed/issues/12661))
2024-07-15 12:27:33 +03:00
llogick
684d9dde56 zig: Wire up LSP settings and binary.{path/arguments} for zls (#14379)
Enables the  LSP `settings` and `binary.{path/arguments}` functionality

Example:
```
"lsp": {
    "zls": {
      "settings": {
        "semantic_tokens": "none"
      },
      "binary": {
        "path": "/home/user/zls/zig-out/bin/zls",
        "arguments": ["--enable-debug-log"]
      }
    }
  },
```

Release Notes:

- N/A
2024-07-15 09:35:03 +02:00
张小白
315692d112 windows: Refactor clipboard implementation (#14347)
This PR provides a similar implementation to the macOS clipboard
implementation, adds support for metadata and includes tests.

Release Notes:

- N/A
2024-07-14 19:40:41 -07:00
张小白
ba09eabfba windows: Make window creation failable (#14395)
Release Notes:

- N/A
2024-07-14 19:37:46 -07:00
lea
70d983abe3 Include stable package in docs, mention UM, and link to sources for the Fedora package (#14432)
Hello, I'm one of the maintainers of the Zed package on Terra. I made
the following changes:

- Mention the Terra stable package, instead of only preview and nightly.
- Link to sources for Terra packages instead of pkgs.org.
- Mention Ultramarine in addition to Fedora (one of Terra's targets).

Release Notes:

- N/A
2024-07-14 19:34:08 -07:00
Fernando Tagawa
4a3097d4dd x11: Fix capitalization with neo 2 (#14466)
Fixed #14282

Release Notes:

- N/A
2024-07-14 18:19:20 -07:00
Kirill Bulatov
59ce3535d3 Turn off use_on_type_format too, for languages that have format_on_save disabled (#14413)
Based on the discussion in
https://github.com/zed-industries/zed/issues/14400


Release Notes:

- N/A
2024-07-13 22:04:15 +03:00
Kirill Bulatov
f8b5e42070 Do not send textDocument/didSave message if server does not declare its support (#14412)
Release Notes:

- Improved Zed logic for sending `textDocument/didSave` request
([14286](https://github.com/zed-industries/zed/issues/14286))
2024-07-13 21:59:21 +03:00
Kirill Bulatov
88c5eb550e Lookup prettier more leniently (#14403)
Do not require the `prettier` dependency name to be in package.json's
[dev]Dependencies, instead just checking the `node_modules` contents.

Release Notes:

- Improved `prettier` detection to pick up its installation from
transitive dependencies
([12731](https://github.com/zed-industries/zed/issues/12731)
2024-07-13 21:59:14 +03:00
Bedis Nbiba
e5dc6beace deno: wire up LSP settings (#14410)
Currently deno lsp only works because deno have a workaround when it
detects deno.json it gets activated, but without a deno.json it won't
work
With this change now it works correctly regardless of a deno.json
presence, it only require enable:true:


```json
{
  "lsp": {
    "deno": {
      "settings": {
        "deno": {
          "enable": true
        }
      }
    }
  }
}
```


Release Notes:

- Improved initial Deno set-up to enable it without explicit deno.json present in the file system
2024-07-13 21:10:36 +03:00
Zak Johnson
3a410942b4 Apply terminal.foreground and terminal.background from theme (#14281)
Release Notes:

- Fixed terminal colors not respecting the theme
([#11418](https://github.com/zed-industries/zed/discussions/11418)).
2024-07-13 14:41:44 +03:00
Kirill Bulatov
89fbd6528f Do not fold excerpts by default in the outline panel (#14378)
Release Notes:

- N/A
2024-07-13 04:08:21 +03:00
Kirill Bulatov
9ce989a704 Tidy up collab-related signature help data (#14377)
Follow-up of https://github.com/zed-industries/zed/pull/12909

* Fully preserve LSP data when sending it via collab, and only strip it
on the client.
* Avoid extra custom request handlers, and extend multi LSP server query
protocol instead.


Release Notes:

- N/A
2024-07-13 04:06:01 +03:00
Kirill Bulatov
dd63e25f23 Revert hold: true for macOS tasks (#14376)
Otherwise, ctrl-c makes them stuck being held from time to time

Follow-up of https://github.com/zed-industries/zed/pull/13898 that
reverts the macOS-related part of the PR.

Release Notes:

- N/A
2024-07-13 04:02:38 +03:00
Max Brunsfeld
489077befc Extract a BufferStore object from Project (#14037)
This is a ~small~ pure refactor that's a step toward SSH remoting. I've
extracted the Project's buffer state management into a smaller, separate
struct called `BufferStore`, currently in the same crate. I did this as
a separate PR to reduce conflicts between main and `remoting-over-ssh`.

The idea is to make use of this struct (and other smaller structs that
make up `Project`) in a dedicated, simpler `HeadlessProject` type that
we will use in the SSH server to model the remote end of a project. With
this approach, as we develop the headless project, we can avoid adding
more conditional logic to `Project` itself (which is already very
complex), and actually make `Project` a bit smaller by extracting out
helper objects.

Release Notes:

- N/A
2024-07-12 15:25:54 -07:00
FilipeBisinella
21c5ce2bbd Add pyright workspace configuration (#14265)
Release Notes:

- Added support for pyright workspace configuration, as described in
https://microsoft.github.io/pyright/#/settings .
2024-07-12 15:13:09 -07:00
Marshall Bowers
3deb000f70 assistant: Add basic glob support for expanding items in /docs (#14370)
This PR updates the `/docs` slash command with basic globbing support
for expanding docs.

A `*` can be added to the item path to signify the end of a prefix
match.

For example:

```
# This will match any documentation items starting with `auk::`.
# In this case, it will pull in the docs for each item in the crate.
/docs docs-rs auk::*

# This will match any documentation items starting with `auk::visitor::`,
# which will pull in docs for the `visitor` module.
/docs docs-rs auk::visitor::*
```


https://github.com/user-attachments/assets/5e1e21f1-241b-483f-9cd1-facc3aa76365

Release Notes:

- N/A
2024-07-12 17:57:50 -04:00
Mikayla Maki
fe3fe945a9 linux: Indicate when the window is focused (#14266)
fixes #14202

Release Notes:

- Added a representation of the current focus state to Zed's window
style ([#14202](https://github.com/zed-industries/zed/issues/14202))
2024-07-12 14:20:58 -07:00
Stanislav Alekseev
11178eacc7 Fix diagnostic popover not overflowing when necessary (#14322)
It was broken after #13996 moved rendering text one level deeper,
causing `max_h` and `overflow_y_scroll` to apply to different widgets
Release Notes:

- Fixed large diagnostic popovers not overflowing when nessesary

Before:
<img width="814" alt="Screenshot 2024-07-12 at 15 25 46"
src="https://github.com/user-attachments/assets/4f615600-2857-4470-8b77-864e3a9e38d5">

After:
<img width="813" alt="Screenshot 2024-07-12 at 15 26 10"
src="https://github.com/user-attachments/assets/83c1f344-b3b1-4929-8197-4b24a0e9c65e">
2024-07-12 14:14:11 -07:00
Stanislav Alekseev
59bc027750 Fix direnv option being named direnv and not load_direnv in the docs (#14309)
This is a quick followup to #13902 that fixes a mistake with the setting
naming in the docs, I accidentally made
Release Notes:

- N/A
2024-07-12 14:12:02 -07:00
张小白
0a718c65e2 windows: Return client size and position from window_bounds (#14228)
This is a follow up of #14218 , since we open the window based on the
size of the client area, `window_bounds` should also return the size of
the client area to maintain consistency.

Release Notes:

- N/A
2024-07-12 13:19:36 -07:00
Marshall Bowers
85d77a3eec Clarify /docs error message when target/doc does not exist (#14364)
This PR improves the error message shown by the `/docs` slash command
when indexing fails due to the absence of `target/doc`.

We now distinguish between the overall `target/doc` directory missing
and an individual crate directory missing beneath it.

Release Notes:

- N/A
2024-07-12 16:09:16 -04:00
Marshall Bowers
ca80343486 assistant: Add docs provider for docs.rs (#14356)
This PR adds an indexed docs provider for retrieving docs from `docs.rs`
using the `/docs` slash command.

Release Notes:

- N/A
2024-07-12 13:22:52 -04:00
Semen Fomchenkov
739038ddaf docs: Add ALT Linux (Sisyphus) (#14351)
Added ALT Linux (Sisyphus) as one of the ways to install via the package
manager in linux.md.

Release Notes:

- N/A
2024-07-12 12:59:17 -04:00
Peter Tripp
106e0623dd PlainText language: Default to SoftWrap::EditorWidth (#14331)
- Remove wrap guide / vertical ruler in untitled buffers
- Fixes https://github.com/zed-industries/zed/issues/12473
2024-07-12 11:10:59 -04:00
Peter Tripp
607ad6de3c zig: Improve indentation (#14332)
- Fixes https://github.com/zed-industries/zed/issues/14140
2024-07-12 10:24:07 -04:00
Kirill Bulatov
ea26a01f5f Do not render a signature popover when its location is before the visible range (#14307)
Follow-up of https://github.com/zed-industries/zed/pull/12909

Release Notes:

- N/A
2024-07-12 11:31:52 +03:00
Stanislav Alekseev
8abc000553 Fix nushell local env detection by using direnv export (#13902)
I don't intend fully on getting this merged, this is just an experiment
on using `direnv` directly without relying on shell-specific behaviours.
It works though, so this finally closes #8633
Release Notes:

- Fixed nushell not picking up `direnv` environments by directly
interfacing with it using `direnv export`

---------

Co-authored-by: Thorsten Ball <mrnugget@gmail.com>
2024-07-12 10:29:32 +02:00
Kirill Bulatov
9f5309cedd Remove non-default wrap setting for markdown (#14304)
With this setting, markdown files are one of the few that get a line
wrap indicator, a vertical line on the right, which confuses people.

Release Notes:

- N/A
2024-07-12 11:15:57 +03:00
Conrad Irwin
adf74fdc14 linux: Fix panic handling unknown keys (#14274)
Pulls in https://github.com/rust-x-bindings/xkbcommon-rs/pull/54 to
avoid
panicking.

Release Notes:

- linux: Fix a panic in keyboard handling
2024-07-11 17:03:19 -06:00
sherwyn
e402d7e96a vim: Add support for vim::PreviousLineStart motion (#14193)
Release Notes:

- vim: Added `-`/`+` to go to beginning of line above/below
([#14183](https://github.com/zed-industries/zed/issues/14183)).
- vim: (Breaking) Removed non-standard builtin binding from `-` to open
the project panel. You can re-add it to your keymap file with:
`{"context":"VimControl", "bindings":{ "-":
"pane::RevealInProjectPanel"}}`


Optionally, include screenshots / media showcasing your addition that
can be included in the release notes.


https://github.com/zed-industries/zed/assets/32429059/0e9e9348-265e-4a81-a45a-4739034dc5d9

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2024-07-11 16:36:07 -06:00
Conrad Irwin
12dfd4a2c2 Don't panic on unknown cursor style on x11 (#14264)
Release Notes:

- linux: Fixed a panic if we request a cursor style your system doesn't
support
2024-07-11 16:05:01 -06:00
Conrad Irwin
b87d1eabcc linux: Panic less on window init (#14255)
This change pulls in https://github.com/kvark/blade/pull/135 and updates
the simplelog dependency for compatibility with that.


Release Notes:

- linux: Show link to troubleshooting docs when we can't open a window
2024-07-11 16:04:46 -06:00
Max Brunsfeld
ac528dda64 Fix panic when evaluating a code snippet containing multi-byte characters (#14269)
Also, don't retrieve code snippets when rendering the repl quick action
button

Release Notes:

- N/A

---------

Co-authored-by: Kyle Kelley <kylek@zed.dev>
Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
2024-07-11 15:04:13 -07:00
Marshall Bowers
906688f012 assistant: Show a warning indicator when the user needs to run cargo doc (#14262)
This PR updates the `/docs` slash command to show a warning to the user
if a crate's docs cannot be indexed due to the target directory not
containing docs:

<img width="782" alt="Screenshot 2024-07-11 at 5 11 46 PM"
src="https://github.com/user-attachments/assets/2f54f7a1-97f4-4d2d-b51f-57ba31e50a2f">

Release Notes:

- N/A
2024-07-11 17:37:31 -04:00
Nate Butler
c18e9aedcd Add items_baseline to Styled (#14238)
Add support for aligning items to the baseline.

Release Notes:

- N/A

---------

Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
2024-07-11 16:38:21 -04:00
Marshall Bowers
cd4847ca22 assistant: Use a more generic icon for the /docs command (#14247)
This PR updates the `/docs` slash command to use a more generic icon to
convey docs.

It was still using the Rust icon, a relic of when it was still
`/rustdoc`.

Release Notes:

- N/A
2024-07-11 15:46:33 -04:00
Brad Pitcher
4c63e8b203 docs: Fix Linux aarch64 tarball links (#14245)
Fixed tarball documentation links for linux aarch64 (they were pointing
at x86_64 tarballs)

Release Notes:

- N/A
2024-07-11 15:43:10 -04:00
TC
d9d8c1f6d9 assistant: Handle http:// links in /fetch (#14243)
Previously http://google.com would get modified to
https://http://google.com which doesn't work. I assume http links should
be supported.

Release Notes:

- N/A
2024-07-11 15:30:45 -04:00
Conrad Irwin
b0dbc80575 vim: (BREAKING) clean up keymap contexts (#14233)
Release Notes:

- vim: (BREAKING) Improved vim keymap contexts.

Previously `vim_mode == normal` was true even when operators were
pending, which led to bugs like #13789 and a requirement for custom
keymaps to exclude various conditions like (`!VimObject` and
`!VimWaiting`) to avoid bugs.

Now `vim_mode` will be set to `operator` or `waiting` in these cases as
described in [the docs](https://zed.dev/docs/vim#keybindings). For most
custom keymaps this change will be a no-op or an improvement, but if you
were deliberately relying on the old behaviour (if you were relying on
`VimObject` or `VimWaiting` becoming true) you will need to update your
keymap.

---------

Co-authored-by: Thorsten <thorsten@zed.dev>
2024-07-11 13:16:26 -06:00
Mikayla Maki
8e853e2b56 Update linux.md 2024-07-11 12:05:59 -07:00
Mikayla Maki
47a78907d6 Update system-requirements.md 2024-07-11 11:59:52 -07:00
Mikayla Maki
0c1a3db87d Update getting-started.md 2024-07-11 11:50:36 -07:00
Omer Tuchfeld
3541a1175f Disrupt blink for immediate feedback on cursor shape changes (#14177)
# Issue

When a user does something that changes the cursor shape, such as when
switching between vim modes, there may be an up to 500ms (cursor blink
interval) delay until the user receives feedback for their action. This
happens when the shape change happens during the invisible phase of a
blink - the user will not see the cursor shape change until the next
phase, which could be 500ms away.

# Solution

Cursor shape changes should disrupt blinking by forcing the cursor to be
shown, this results in immediate feedback for shape changes. This is in
line with the behavior of other editors I've tried.

Release Notes:

- Improved visual feedback when changing cursor shape
2024-07-11 12:47:10 -06:00
Kyle Kelley
e51d469025 Invalidate anchors when they get deleted (#14116)
Allows deleting the outputs directly within the editor. This also fixes
the overlap logic to make sure that the ends and the starts are
compared.


https://github.com/zed-industries/zed/assets/836375/84f5f582-95f3-4c6a-a3c9-54da6009e34d

Release Notes:

- N/A

---------

Co-authored-by: Antonio <antonio@zed.dev>
2024-07-11 11:21:41 -07:00
Conrad Irwin
018a2a29ea vim: Fix c when range ends in a multibyte character (#14139)
Release Notes:

- vim: Fixed `c <motion>` omitting trailing multibyte characters
([#13909](https://github.com/zed-industries/zed/issues/13909)).
2024-07-11 12:01:56 -06:00
Donough Liu
d49727ff10 terminal: Set TERM_PROGRAM and TERM_PROGRAM_VERSION environment variables in integrated terminal (#14213)
![image](https://github.com/zed-industries/zed/assets/31354274/9d1c5410-897b-40a1-8256-2d7e207f69ff)

These two environment variables are essential when people need to detect
terminal type and do something. Many popular terminals set them.

fixes https://github.com/zed-industries/zed/issues/4571

Release Notes:

- Set `TERM_PROGRAM` and `TERM_PROGRAM_VERSION` environment variables in
the integrated terminal
([#4571](https://github.com/zed-industries/zed/issues/4571)).
2024-07-11 20:48:46 +03:00
oliverpool
c195c4ddff docs: Document buffer_line_height (#14168)
`buffer_line_height` has been requested in #5590 and implemented in
#2718, however the documentation was still lacking.

Release Notes:

- N/A
2024-07-11 13:42:27 -04:00
Stanislav Alekseev
fd03454540 Fix reverse selections always being cleared (#14150)
When I implemented #13701, I kinda messed up with the reversed
selections, thinking that their anchors are flipped, so I flipped them
again. This caused the reverse selections to always be cleared

Release Notes:

- Fix reverse selections always being cleared, even if the right click
was performed inside
2024-07-11 11:35:18 -06:00
张小白
6eeec9b403 windows: Create window with correct size (#14218)
The `Bounds<DevicePixels>` we use to create a window represents the size
of the drawable area.

### Before:



https://github.com/zed-industries/zed/assets/14981363/52f0d196-b113-4b64-a0d1-407972674990

### After



https://github.com/zed-industries/zed/assets/14981363/83298b6c-5e5f-4a47-b051-35b4a02404ac



Release Notes:

- N/A
2024-07-11 09:54:59 -07:00
Marshall Bowers
b558e8da1e svelte: Bump to v0.0.2 (#14220)
This PR bumps the Svelte extension to v0.0.2.

Changes:

- https://github.com/zed-industries/zed/pull/12788

Release Notes:

- N/A
2024-07-11 11:47:44 -04:00
Peter Tripp
1d7b28c658 Add Upper/LowerCase binds to Linux Sublime Text keybinds (#14155) 2024-07-11 11:15:49 -04:00
Peter Tripp
de78eb44b1 Keymap changes for editor::JoinLines (#14136)
- Linux (default) add ctrl-shift-j
- Linux (default) remove ctrl-j
  - Conflicted with: `"ctrl-j": "workspace::ToggleBottomDock",`
- MacOS (sublime) add cmd-shift-j
2024-07-11 11:14:25 -04:00
Danilo Leal
c071e19899 docs: Add stray design tweaks (#14205)
- Mostly just tweaking some design (colors & spacing) stuff
- Some small accessibility things—e.g., underline decoration for links
and one h1 only per page
- Most of the other captured changes are really just Prettier indenting
stuff

Release Notes:

- N/A
2024-07-11 11:57:22 -03:00
Marshall Bowers
37fc4ce09d Allow Zed Nightly to use v0.0.7 of the Zed extension API (#14209)
This PR updates the Wasm API compatibility check to allow Nightly to
load extensions using v0.0.7 of the Zed extension API.

Release Notes:

- N/A
2024-07-11 10:54:15 -04:00
Danilo Leal
99f56252be docs: Tiny formatting tweaks on the Linux page (#14208)
Release Notes:

- N/A
2024-07-11 11:53:34 -03:00
Aleksei Gusev
f61abe0247 Pass hold: true to Alacritty for tasks (#13898)
It seems `hold: false` causes alacritty to close the channel earlier,
without waiting for the output from the child command to go to Zed.

Fixes [#13683](https://github.com/zed-industries/zed/issues/13683)

Release Notes:

- Fixed loosing output of a spawned task
([#13683](https://github.com/zed-industries/zed/issues/13683)).

[Screencast from 2024-07-06
18-28-56.webm](https://github.com/zed-industries/zed/assets/39293/4ebef8b5-7c0d-46be-9341-4ac0d809458d)
2024-07-11 17:50:00 +03:00
Marshall Bowers
45c54d189a assistant: Show a message when no docs providers are available (#14207)
This PR updates the `/docs` slash command to show a message to more
clearly indicate when there are no available docs providers.

<img width="379" alt="Screenshot 2024-07-11 at 10 31 53 AM"
src="https://github.com/zed-industries/zed/assets/1486634/d079f87c-4933-4da9-ad82-34dbfe6a284c">

Release Notes:

- N/A
2024-07-11 10:49:13 -04:00
657 changed files with 34560 additions and 17284 deletions

View File

@@ -12,3 +12,7 @@ rustflags = ["-C", "link-arg=-fuse-ld=mold"]
[target.aarch64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
# This cfg will reduce the size of `windows::core::Error` from 16 bytes to 4 bytes
[target.'cfg(target_os = "windows")']
rustflags = ["--cfg", "windows_slim_errors"]

View File

@@ -19,6 +19,10 @@
# https://github.com/zed-industries/zed/pull/2394
eca93c124a488b4e538946cd2d313bd571aa2b86
# 2024-02-25 Format JSON files in assets/
# https://github.com/zed-industries/zed/pull/8405
ffdda588b41f7d9d270ffe76cab116f828ad545e
# 2024-07-05 Improved formatting of default keymaps (single line per bind)
# https://github.com/zed-industries/zed/pull/13887
813cc3f5e537372fc86720b5e71b6e1c815440ab

View File

@@ -27,7 +27,8 @@ body:
attributes:
label: If applicable, attach your `~/Library/Logs/Zed/Zed.log` file to this issue.
description: |
Drag Zed.log into the text input below.
macOS: `~/Library/Logs/Zed/Zed.log`
Linux: `~/.local/share/zed/logs/Zed.log` or $XDG_DATA_HOME
If you only need the most recent lines, you can run the `zed: open log` command palette action to see the last 1000.
value: |
<details><summary>Zed.log</summary><pre>

View File

@@ -10,7 +10,7 @@ runs:
cargo install cargo-nextest
- name: Install Node
uses: actions/setup-node@v4
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
with:
node-version: "18"

View File

@@ -19,7 +19,7 @@ jobs:
- test
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
ref: ${{ github.event.inputs.branch }}
ssh-key: ${{ secrets.ZED_BOT_DEPLOY_KEY }}

View File

@@ -30,7 +30,7 @@ jobs:
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
fetch-depth: 0
@@ -40,10 +40,15 @@ jobs:
- name: Check spelling
run: |
if ! which typos > /dev/null; then
cargo install typos-cli
if ! cargo install --list | grep "typos-cli v$TYPOS_CLI_VERSION" > /dev/null; then
echo "Installing typos-cli@$TYPOS_CLI_VERSION..."
cargo install "typos-cli@$TYPOS_CLI_VERSION"
else
echo "typos-cli@$TYPOS_CLI_VERSION is already installed."
fi
typos
env:
TYPOS_CLI_VERSION: "1.23.3"
- name: Run style checks
uses: ./.github/actions/check_style
@@ -85,7 +90,7 @@ jobs:
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
@@ -112,7 +117,7 @@ jobs:
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
@@ -132,17 +137,18 @@ jobs:
runs-on: hosted-windows-1
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
- name: Cache dependencies
uses: swatinem/rust-cache@v2
uses: swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: cargo clippy
run: ./script/clippy
# Windows can't run shell scripts, so we need to use `cargo xtask`.
run: cargo xtask clippy
- name: Build Zed
run: cargo build -p zed
@@ -165,12 +171,12 @@ jobs:
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
steps:
- name: Install Node
uses: actions/setup-node@v4
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
with:
node-version: "18"
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
# We need to fetch more than one commit so that `script/draft-release-notes`
# is able to diff between the current and previous tag.
@@ -225,32 +231,34 @@ jobs:
mv target/x86_64-apple-darwin/release/Zed.dmg target/x86_64-apple-darwin/release/Zed-x86_64.dmg
- name: Upload app bundle (universal) to workflow run if main branch or specific label
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
with:
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
path: target/release/Zed.dmg
- name: Upload app bundle (aarch64) to workflow run if main branch or specific label
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
with:
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg
path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg
- name: Upload app bundle (x86_64) to workflow run if main branch or specific label
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
with:
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg
path: target/x86_64-apple-darwin/release/Zed-x86_64.dmg
- uses: softprops/action-gh-release@v1
- uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
name: Upload app bundle to release
if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
with:
draft: true
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
files: |
target/zed-remote-server-macos-x86_64.gz
target/zed-remote-server-macos-aarch64.gz
target/aarch64-apple-darwin/release/Zed-aarch64.dmg
target/x86_64-apple-darwin/release/Zed-x86_64.dmg
target/release/Zed.dmg
@@ -273,7 +281,7 @@ jobs:
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
@@ -311,18 +319,20 @@ jobs:
run: script/bundle-linux
- name: Upload Linux bundle to workflow run if main branch or specific label
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
with:
name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
path: target/release/zed-*.tar.gz
- name: Upload app bundle to release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
with:
draft: true
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
files: target/release/zed-linux-x86_64.tar.gz
files: |
target/zed-remote-server-linux-x86_64.gz
target/release/zed-linux-x86_64.tar.gz
body: ""
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -338,11 +348,11 @@ jobs:
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
- name: "Setup jq"
uses: dcarbone/install-jq-action@v2
uses: dcarbone/install-jq-action@8867ddb4788346d7c22b72ea2e2ffe4d514c7bcb # v2
- name: Set up Clang
run: |
@@ -350,7 +360,7 @@ jobs:
sudo apt-get install -y llvm-10 clang-10 build-essential cmake pkg-config libasound2-dev libfontconfig-dev libwayland-dev libxkbcommon-x11-dev libssl-dev libsqlite3-dev libzstd-dev libvulkan1 libgit2-dev
echo "/usr/lib/llvm-10/bin" >> $GITHUB_PATH
- uses: rui314/setup-mold@v1
- uses: rui314/setup-mold@2e332a0b602c2fc65d2d3995941b1b29a5f554a0 # v1
with:
mold-version: 2.32.0
@@ -393,19 +403,21 @@ jobs:
run: script/bundle-linux
- name: Upload Linux bundle to workflow run if main branch or specific label
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
with:
name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
path: target/release/zed-*.tar.gz
- name: Upload app bundle to release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
with:
draft: true
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
files: target/release/zed-linux-aarch64.tar.gz
files: |
target/zed-remote-server-linux-aarch64.gz
target/release/zed-linux-aarch64.tar.gz
body: ""
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -14,14 +14,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- uses: pnpm/action-setup@v3
with:
version: 9
- name: Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
with:
node-version: "20"
cache: "pnpm"

View File

@@ -12,12 +12,12 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v2
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2
with:
mdbook-version: "0.4.37"
@@ -28,28 +28,28 @@ jobs:
mdbook build ./docs --dest-dir=../target/deploy/docs/
- name: Deploy Docs
uses: cloudflare/wrangler-action@v3
uses: cloudflare/wrangler-action@f84a562284fc78278ff9052435d9526f9c718361 # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy target/deploy --project-name=docs
- name: Deploy Install
uses: cloudflare/wrangler-action@v3
uses: cloudflare/wrangler-action@f84a562284fc78278ff9052435d9526f9c718361 # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: r2 object put -f script/install.sh zed-open-source-website-assets/install.sh
- name: Deploy Docs Workers
uses: cloudflare/wrangler-action@v3
uses: cloudflare/wrangler-action@f84a562284fc78278ff9052435d9526f9c718361 # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy .cloudflare/docs-proxy/src/worker.js
- name: Deploy Install Workers
uses: cloudflare/wrangler-action@v3
uses: cloudflare/wrangler-action@f84a562284fc78278ff9052435d9526f9c718361 # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

View File

@@ -18,7 +18,7 @@ jobs:
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
fetch-depth: 0
@@ -37,7 +37,7 @@ jobs:
needs: style
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
fetch-depth: 0
@@ -71,7 +71,7 @@ jobs:
run: doctl registry login
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false

View File

@@ -16,12 +16,12 @@ jobs:
- ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
- name: Cache dependencies
uses: swatinem/rust-cache@v2
uses: swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}

View File

@@ -23,12 +23,12 @@ jobs:
- randomized-tests
steps:
- name: Install Node
uses: actions/setup-node@v4
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
with:
node-version: "18"
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false

View File

@@ -16,7 +16,7 @@ jobs:
fi
echo "::set-output name=URL::$URL"
- name: Get content
uses: 2428392/gh-truncate-string-action@v1.3.0
uses: 2428392/gh-truncate-string-action@67b1b814955634208b103cff064be3cb1c7a19be # v1.3.0
id: get-content
with:
stringToTruncate: |
@@ -26,7 +26,7 @@ jobs:
maxLength: 2000
truncationSymbol: "..."
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v5.3.0
uses: tsickert/discord-webhook@c840d45a03a323fbc3f7507ac7769dbd91bfb164 # v5.3.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: ${{ steps.get-content.outputs.string }}

View File

@@ -23,7 +23,7 @@ jobs:
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
fetch-depth: 0
@@ -33,6 +33,7 @@ jobs:
- name: Run clippy
run: ./script/clippy
tests:
timeout-minutes: 60
name: Run tests
@@ -43,7 +44,7 @@ jobs:
needs: style
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
@@ -68,12 +69,12 @@ jobs:
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Install Node
uses: actions/setup-node@v4
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4
with:
node-version: "18"
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
@@ -93,9 +94,9 @@ jobs:
- name: Upload Zed Nightly
run: script/upload-nightly macos
bundle-deb:
bundle-linux-x86:
timeout-minutes: 60
name: Create a Linux *.tar.gz bundle
name: Create a Linux *.tar.gz bundle for x86
if: github.repository_owner == 'zed-industries'
runs-on:
- self-hosted
@@ -107,7 +108,7 @@ jobs:
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
@@ -121,8 +122,56 @@ jobs:
echo "Publishing version: ${version} on release channel nightly"
echo "nightly" > crates/zed/RELEASE_CHANNEL
- name: Generate license file
run: script/generate-licenses
- name: Create Linux .tar.gz bundle
run: script/bundle-linux
- name: Upload Zed Nightly
run: script/upload-nightly linux-targz
bundle-linux-arm:
timeout-minutes: 60
name: Create a Linux *.tar.gz bundle for ARM
if: github.repository_owner == 'zed-industries'
runs-on:
- hosted-linux-arm-1
needs: tests
env:
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Checkout repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
with:
clean: false
- name: "Setup jq"
uses: dcarbone/install-jq-action@8867ddb4788346d7c22b72ea2e2ffe4d514c7bcb # v2
- name: Set up Clang
run: |
sudo apt-get update
sudo apt-get install -y llvm-10 clang-10 build-essential cmake pkg-config libasound2-dev libfontconfig-dev libwayland-dev libxkbcommon-x11-dev libssl-dev libsqlite3-dev libzstd-dev libvulkan1 libgit2-dev
echo "/usr/lib/llvm-10/bin" >> $GITHUB_PATH
- uses: rui314/setup-mold@2e332a0b602c2fc65d2d3995941b1b29a5f554a0 # v1
with:
mold-version: 2.32.0
- name: rustup
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Limit target directory size
run: script/clear-target-dir-if-larger-than 100
- name: Set release channel to nightly
run: |
set -euo pipefail
version=$(git rev-parse --short HEAD)
echo "Publishing version: ${version} on release channel nightly"
echo "nightly" > crates/zed/RELEASE_CHANNEL
- name: Create Linux .tar.gz bundle
run: script/bundle-linux

View File

@@ -8,8 +8,8 @@ jobs:
runs-on: ubuntu-latest
if: github.repository_owner == 'zed-industries'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5
with:
python-version: "3.11"
architecture: "x64"

View File

@@ -8,8 +8,8 @@ jobs:
runs-on: ubuntu-latest
if: github.repository_owner == 'zed-industries'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5
with:
python-version: "3.11"
architecture: "x64"

2160
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
[workspace]
resolver = "2"
members = [
"crates/activity_indicator",
"crates/anthropic",
"crates/assets",
"crates/assistant",
"crates/assistant_slash_command",
"crates/assistant_tooling",
"crates/audio",
"crates/auto_update",
"crates/breadcrumbs",
@@ -19,6 +19,7 @@ members = [
"crates/collections",
"crates/command_palette",
"crates/command_palette_hooks",
"crates/completion",
"crates/copilot",
"crates/db",
"crates/dev_server_projects",
@@ -43,13 +44,14 @@ members = [
"crates/gpui_macros",
"crates/headless",
"crates/html_to_markdown",
"crates/http",
"crates/http_client",
"crates/image_viewer",
"crates/indexed_docs",
"crates/inline_completion_button",
"crates/install_cli",
"crates/journal",
"crates/language",
"crates/language_model",
"crates/language_selector",
"crates/language_tools",
"crates/languages",
@@ -79,6 +81,8 @@ members = [
"crates/refineable",
"crates/refineable/derive_refineable",
"crates/release_channel",
"crates/remote",
"crates/remote_server",
"crates/repl",
"crates/rich_text",
"crates/rope",
@@ -86,7 +90,9 @@ members = [
"crates/search",
"crates/semantic_index",
"crates/semantic_version",
"crates/session",
"crates/settings",
"crates/settings_ui",
"crates/snippet",
"crates/snippet_provider",
"crates/sqlez",
@@ -119,6 +125,10 @@ members = [
"crates/zed",
"crates/zed_actions",
#
# Extensions
#
"extensions/astro",
"extensions/clojure",
"extensions/csharp",
@@ -137,6 +147,7 @@ members = [
"extensions/php",
"extensions/prisma",
"extensions/purescript",
"extensions/ruff",
"extensions/ruby",
"extensions/snippets",
"extensions/svelte",
@@ -147,19 +158,25 @@ members = [
"extensions/vue",
"extensions/zig",
#
# Tooling
#
"tooling/xtask",
]
default-members = ["crates/zed"]
resolver = "2"
[workspace.dependencies]
#
# Workspace member crates
#
activity_indicator = { path = "crates/activity_indicator" }
ai = { path = "crates/ai" }
anthropic = { path = "crates/anthropic" }
assets = { path = "crates/assets" }
assistant = { path = "crates/assistant" }
assistant_slash_command = { path = "crates/assistant_slash_command" }
assistant_tooling = { path = "crates/assistant_tooling" }
audio = { path = "crates/audio" }
auto_update = { path = "crates/auto_update" }
breadcrumbs = { path = "crates/breadcrumbs" }
@@ -173,6 +190,7 @@ collab_ui = { path = "crates/collab_ui" }
collections = { path = "crates/collections" }
command_palette = { path = "crates/command_palette" }
command_palette_hooks = { path = "crates/command_palette_hooks" }
completion = { path = "crates/completion" }
copilot = { path = "crates/copilot" }
db = { path = "crates/db" }
dev_server_projects = { path = "crates/dev_server_projects" }
@@ -195,13 +213,14 @@ gpui = { path = "crates/gpui" }
gpui_macros = { path = "crates/gpui_macros" }
headless = { path = "crates/headless" }
html_to_markdown = { path = "crates/html_to_markdown" }
http = { path = "crates/http" }
http_client = { path = "crates/http_client" }
image_viewer = { path = "crates/image_viewer" }
indexed_docs = { path = "crates/indexed_docs" }
inline_completion_button = { path = "crates/inline_completion_button" }
install_cli = { path = "crates/install_cli" }
journal = { path = "crates/journal" }
language = { path = "crates/language" }
language_model = { path = "crates/language_model" }
language_selector = { path = "crates/language_selector" }
language_tools = { path = "crates/language_tools" }
languages = { path = "crates/languages" }
@@ -230,7 +249,10 @@ project_symbols = { path = "crates/project_symbols" }
proto = { path = "crates/proto" }
quick_action_bar = { path = "crates/quick_action_bar" }
recent_projects = { path = "crates/recent_projects" }
refineable = { path = "crates/refineable" }
release_channel = { path = "crates/release_channel" }
remote = { path = "crates/remote" }
remote_server = { path = "crates/remote_server" }
repl = { path = "crates/repl" }
rich_text = { path = "crates/rich_text" }
rope = { path = "crates/rope" }
@@ -238,7 +260,9 @@ rpc = { path = "crates/rpc" }
search = { path = "crates/search" }
semantic_index = { path = "crates/semantic_index" }
semantic_version = { path = "crates/semantic_version" }
session = { path = "crates/session" }
settings = { path = "crates/settings" }
settings_ui = { path = "crates/settings_ui" }
snippet = { path = "crates/snippet" }
snippet_provider = { path = "crates/snippet_provider" }
sqlez = { path = "crates/sqlez" }
@@ -271,37 +295,44 @@ worktree = { path = "crates/worktree" }
zed = { path = "crates/zed" }
zed_actions = { path = "crates/zed_actions" }
#
# External crates
#
aho-corasick = "1.1"
alacritty_terminal = "0.23"
any_vec = "0.13"
anyhow = "1.0.57"
ashpd = { git = "https://github.com/bilelmoussaoui/ashpd", rev = "29f2e1a" }
any_vec = "0.14"
anyhow = "1.0.86"
ashpd = "0.9.1"
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
async-dispatcher = { version = "0.1" }
async-dispatcher = "0.1"
async-fs = "1.6"
async-pipe = { git = "https://github.com/zed-industries/async-pipe-rs", rev = "82d00a04211cf4e1236029aa03e6b6ce2a74c553" }
async-recursion = "1.0.0"
async-tar = "0.4.2"
async-trait = "0.1"
async-tungstenite = "0.23"
async-watch = "0.3.1"
async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] }
base64 = "0.13"
bitflags = "2.4.2"
blade-graphics = { git = "https://github.com/kvark/blade", rev = "21a56f780e21e4cb42c70a1dcf4b59842d1ad7f7" }
blade-macros = { git = "https://github.com/kvark/blade", rev = "21a56f780e21e4cb42c70a1dcf4b59842d1ad7f7" }
blade-util = { git = "https://github.com/kvark/blade", rev = "21a56f780e21e4cb42c70a1dcf4b59842d1ad7f7" }
cap-std = "3.0"
base64 = "0.22"
bitflags = "2.6.0"
blade-graphics = { git = "https://github.com/zed-industries/blade", rev = "7e497c534d5d4a30c18d9eb182cf39eaf0aaa25e" }
blade-macros = { git = "https://github.com/zed-industries/blade", rev = "7e497c534d5d4a30c18d9eb182cf39eaf0aaa25e" }
blade-util = { git = "https://github.com/zed-industries/blade", rev = "7e497c534d5d4a30c18d9eb182cf39eaf0aaa25e" }
cargo_metadata = "0.18"
cargo_toml = "0.20"
chrono = { version = "0.4", features = ["serde"] }
clap = { version = "4.4", features = ["derive"] }
clickhouse = { version = "0.11.6" }
clickhouse = "0.11.6"
cocoa = "0.25"
core-foundation = { version = "0.9.3" }
core-foundation = "0.9.3"
core-foundation-sys = "0.8.6"
ctor = "0.2.6"
dashmap = "5.5.3"
dashmap = "6.0"
derive_more = "0.99.17"
dirs = "4.0"
emojis = "0.6.1"
env_logger = "0.9"
env_logger = "0.11"
exec = "0.3.1"
fork = "0.1.23"
futures = "0.3"
@@ -315,16 +346,17 @@ html5ever = "0.27.0"
ignore = "0.4.22"
image = "0.25.1"
indexmap = { version = "1.6.2", features = ["serde"] }
indoc = "1"
indoc = "2"
# We explicitly disable http2 support in isahc.
isahc = { version = "1.7.2", default-features = false, features = [
"text-decoding",
] }
itertools = "0.11.0"
jsonwebtoken = "9.3"
lazy_static = "1.4.0"
libc = "0.2"
linkify = "0.10.0"
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
markup5ever_rcdom = "0.3.0"
nanoid = "0.4"
nix = "0.28"
@@ -342,15 +374,16 @@ prost-build = "0.9"
prost-types = "0.9"
pulldown-cmark = { version = "0.10.0", default-features = false }
rand = "0.8.5"
refineable = { path = "./crates/refineable" }
regex = "1.5"
repair_json = "0.1.0"
rsa = "0.9.6"
runtimelib = { version = "0.12", default-features = false, features = [
"async-dispatcher-runtime",
] }
rusqlite = { version = "0.29.0", features = ["blob", "array", "modern_sqlite"] }
rustc-demangle = "0.1.23"
rust-embed = { version = "8.4", features = ["include-exclude"] }
schemars = "0.8"
schemars = {version = "0.8", features = ["impl_json_schema"]}
semver = "1.0"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_derive = { version = "1.0", features = ["deserialize_in_place"] }
@@ -365,10 +398,12 @@ shellexpand = "2.1.0"
shlex = "1.3.0"
signal-hook = "0.3.17"
similar = "1.3"
simplelog = "0.12.2"
smallvec = { version = "1.6", features = ["union"] }
smol = "1.2"
strum = { version = "0.25.0", features = ["derive"] }
subtle = "2.5.0"
sys-locale = "0.3.1"
sysinfo = "0.30.7"
tempfile = "3.9.0"
thiserror = "1.0.29"
@@ -380,32 +415,32 @@ time = { version = "0.3", features = [
"serde-well-known",
"formatting",
] }
tiny_http = "0.8"
toml = "0.8"
tokio = { version = "1", features = ["full"] }
tower-http = "0.4.4"
tree-sitter = { version = "0.20", features = ["wasm"] }
tree-sitter-bash = "0.20.5"
tree-sitter-c = "0.20.1"
tree-sitter-cpp = "0.20.5"
tree-sitter-css = "0.20"
tree-sitter-elixir = "0.1.1"
tree-sitter = { version = "0.22", features = ["wasm"] }
tree-sitter-bash = "0.21"
tree-sitter-c = "0.21"
tree-sitter-cpp = "0.22"
tree-sitter-css = "0.21"
tree-sitter-elixir = "0.2"
tree-sitter-embedded-template = "0.20.0"
tree-sitter-go = { git = "https://github.com/tree-sitter/tree-sitter-go", rev = "b82ab803d887002a0af11f6ce63d72884580bf33" }
tree-sitter-gomod = "1.0.1"
tree-sitter-gowork = { git = "https://github.com/d1y/tree-sitter-go-work" }
rustc-demangle = "0.1.23"
tree-sitter-heex = { git = "https://github.com/phoenixframework/tree-sitter-heex", rev = "2e1348c3cf2c9323e87c2744796cf3f3868aa82a" }
tree-sitter-html = "0.19.0"
tree-sitter-jsdoc = { git = "https://github.com/tree-sitter/tree-sitter-jsdoc", rev = "6a6cf9e7341af32d8e2b2e24a37fbfebefc3dc55" }
tree-sitter-json = "0.20.2"
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
tree-sitter-proto = { git = "https://github.com/rewinfrey/tree-sitter-proto", rev = "36d54f288aee112f13a67b550ad32634d0c2cb52" }
tree-sitter-python = "0.20.2"
tree-sitter-regex = "0.20.0"
tree-sitter-ruby = "0.20.0"
tree-sitter-rust = "0.20.3"
tree-sitter-typescript = "0.20.5"
tree-sitter-yaml = "0.0.1"
tree-sitter-go = "0.21"
tree-sitter-go-mod = { git = "https://github.com/SomeoneToIgnore/tree-sitter-go-mod", rev = "8c1f54f12bb4c846336b634bc817645d6f35d641", package = "tree-sitter-gomod" }
tree-sitter-gowork = { git = "https://github.com/d1y/tree-sitter-go-work", rev = "dcbabff454703c3a4bc98a23cf8778d4be46fd22" }
tree-sitter-heex = { git = "https://github.com/phoenixframework/tree-sitter-heex", rev = "6dd0303acf7138dd2b9b432a229e16539581c701" }
tree-sitter-html = "0.20"
tree-sitter-jsdoc = "0.21"
tree-sitter-json = "0.21"
tree-sitter-md = { git = "https://github.com/zed-industries/tree-sitter-markdown", rev = "e3855e37f8f2c71aa7513c18a9c95fb7461b1b10" }
protols-tree-sitter-proto = "0.2"
tree-sitter-python = "0.21"
tree-sitter-regex = "0.21"
tree-sitter-ruby = "0.21"
tree-sitter-rust = "0.21"
tree-sitter-typescript = "0.21"
tree-sitter-yaml = "0.6"
unindent = "0.1.7"
unicase = "2.6"
unicode-segmentation = "1.10"
@@ -413,20 +448,19 @@ url = "2.2"
uuid = { version = "1.1.2", features = ["v4", "v5", "serde"] }
wasmparser = "0.201"
wasm-encoder = "0.201"
wasmtime = { version = "19.0.0", default-features = false, features = [
wasmtime = { version = "21.0.1", default-features = false, features = [
"async",
"demangle",
"runtime",
"cranelift",
"component-model",
] }
wasmtime-wasi = "19.0.0"
wasmtime-wasi = "21.0.1"
which = "6.0.0"
wit-component = "0.201"
sys-locale = "0.3.1"
[workspace.dependencies.windows]
version = "0.57"
version = "0.58"
features = [
"implement",
"Foundation_Numerics",
@@ -446,16 +480,15 @@ features = [
"Win32_Security",
"Win32_Security_Credentials",
"Win32_Storage_FileSystem",
"Win32_System_LibraryLoader",
"Win32_System_Com",
"Win32_System_Com_StructuredStorage",
"Win32_System_DataExchange",
"Win32_System_LibraryLoader",
"Win32_System_Memory",
"Win32_System_Ole",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_System_Time",
"Win32_System_WinRT",
"Win32_UI_Controls",
"Win32_UI_HiDpi",
@@ -466,9 +499,8 @@ features = [
]
[patch.crates-io]
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "7b4894ba2ae81b988846676f54c0988d4027ef4f" }
# Workaround for a broken nightly build of gpui: See #7644 and revisit once 0.5.3 is released.
pathfinder_simd = { git = "https://github.com/servo/pathfinder.git", rev = "4968e819c0d9b015437ffc694511e175801a17c7" }
# Patch Tree-sitter for updated wasmtime.
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "7f4a57817d58a2f134fe863674acad6bbf007228" }
[profile.dev]
split-debuginfo = "unpacked"
@@ -521,13 +553,6 @@ single_range_in_vec_init = "allow"
style = { level = "allow", priority = -1 }
# Individual rules that have violations in the codebase:
almost_complete_range = "allow"
arc_with_non_send_sync = "allow"
borrowed_box = "allow"
let_underscore_future = "allow"
map_entry = "allow"
non_canonical_partial_ord_impl = "allow"
reversed_empty_ranges = "allow"
type_complexity = "allow"
[workspace.metadata.cargo-machete]

View File

@@ -1,6 +1,6 @@
# syntax = docker/dockerfile:1.2
FROM rust:1.79-bookworm as builder
FROM rust:1.80-bookworm as builder
WORKDIR app
COPY . .

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.49574 4.74787L5.99574 7.25214L8.49574 4.74787" stroke="black" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 246 B

1
assets/icons/eye.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg>

After

Width:  |  Height:  |  Size: 358 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-code"><path d="M10 12.5 8 15l2 2.5"/><path d="m14 12.5 2 2.5-2 2.5"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/></svg>

After

Width:  |  Height:  |  Size: 388 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/></svg>

After

Width:  |  Height:  |  Size: 384 B

View File

@@ -1,14 +1,13 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_32_58)">
<path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.3999 21.9C12.3227 22.2159 14.2958 21.9632 16.0769 21.173C17.858 20.3827 19.3694 19.0893 20.4254 17.4517C21.4814 15.8142 22.036 13.9037 22.021 11.9553C22.006 10.0068 21.422 8.10512 20.3409 6.48401" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.4998 2.10002C11.5849 1.8076 9.62631 2.07763 7.86198 2.87732C6.09765 3.677 4.60356 4.9719 3.56126 6.60468C2.51896 8.23745 1.97332 10.1378 1.99063 12.0748C2.00795 14.0118 2.58749 15.9021 3.65882 17.516" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 13C12.5523 13 13 12.5523 13 12C13 11.4477 12.5523 11 12 11C11.4477 11 11 11.4477 11 12C11 12.5523 11.4477 13 12 13Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_62_95)">
<path d="M4.5 6C3.67157 6 3 5.32843 3 4.5C3 3.67157 3.67157 3 4.5 3C5.32843 3 6 3.67157 6 4.5C6 5.32843 5.32843 6 4.5 6Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.54433 13.4334C6.87775 13.5227 7.22046 13.3249 7.3098 12.9914C7.39914 12.658 7.20127 12.3153 6.86786 12.226L6.54433 13.4334ZM3.77426 6.86772L3.93603 6.26401L2.72862 5.94049L2.56686 6.54419L3.77426 6.86772ZM6.86786 12.226C4.53394 11.6006 3.14889 9.20163 3.77426 6.86772L2.56686 6.54419C1.76281 9.54494 3.54359 12.6293 6.54433 13.4334L6.86786 12.226Z" fill="white"/>
<path d="M11.5 13C10.6716 13 10 12.3284 10 11.5C10 10.6716 10.6716 10 11.5 10C12.3284 10 13 10.6716 13 11.5C13 12.3284 12.3284 13 11.5 13Z" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.1875 4.21113C9.88852 4.03854 9.7861 3.65629 9.95869 3.35736C10.1313 3.05843 10.5135 2.95601 10.8125 3.12859L10.1875 4.21113ZM11.7888 10.1875C12.9969 8.09496 12.28 5.41925 10.1875 4.21113L10.8125 3.12859C13.5028 4.6819 14.4246 8.12209 12.8713 10.8125L11.7888 10.1875Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_32_58">
<rect width="24" height="24" fill="white"/>
<clipPath id="clip0_62_95">
<rect width="16" height="16" fill="white" transform="matrix(-1 0 0 1 16 0)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,6 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4H8" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 10L11 10" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="4" cy="10" r="1.875" stroke="black" stroke-width="1.75"/>
<circle cx="10" cy="4" r="1.875" stroke="black" stroke-width="1.75"/>
</svg>

After

Width:  |  Height:  |  Size: 450 B

View File

@@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 6C5.69062 6.30938 4.56159 6.55977 3.51192 6.73263C3.27345 6.7719 3.27345 7.2281 3.51192 7.26737C4.56159 7.44023 5.69062 7.69062 6 8C6.30938 8.30938 6.55977 9.43841 6.73263 10.4881C6.7719 10.7266 7.2281 10.7266 7.26737 10.4881C7.44023 9.43841 7.69062 8.30938 8 8C8.30938 7.69062 9.43841 7.44023 10.4881 7.26737C10.7266 7.2281 10.7266 6.7719 10.4881 6.73263C9.43841 6.55977 8.30938 6.30938 8 6C7.69062 5.69062 7.44023 4.56159 7.26737 3.51192C7.2281 3.27345 6.7719 3.27345 6.73263 3.51192C6.55977 4.56159 6.30938 5.69062 6 6Z" stroke="black" stroke-width="1.25" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 700 B

View File

@@ -1,3 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.88889 1H2.11111C1.49746 1 1 1.49746 1 2.11111V9.88889C1 10.5025 1.49746 11 2.11111 11H9.88889C10.5025 11 11 10.5025 11 9.88889V2.11111C11 1.49746 10.5025 1 9.88889 1Z" stroke="#C56757" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 9.8V4.2C4 4.08954 4.08954 4 4.2 4H9.8C9.91046 4 10 4.08954 10 4.2V9.8C10 9.91046 9.91046 10 9.8 10H4.2C4.08954 10 4 9.91046 4 9.8Z" stroke="#C56757" stroke-width="1.25" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 310 B

View File

@@ -19,7 +19,6 @@
"escape": "menu::Cancel",
"ctrl-escape": "menu::Cancel",
"ctrl-c": "menu::Cancel",
"shift-enter": "picker::UseSelectedQuery",
"alt-enter": ["picker::ConfirmInput", { "secondary": false }],
"ctrl-alt-enter": ["picker::ConfirmInput", { "secondary": true }],
"ctrl-shift-w": "workspace::CloseWindow",
@@ -41,7 +40,6 @@
"backspace": "editor::Backspace",
"shift-backspace": "editor::Backspace",
"delete": "editor::Delete",
"ctrl-d": "editor::Delete",
"tab": "editor::Tab",
"shift-tab": "editor::TabPrev",
"ctrl-k": "editor::CutToEndOfLine",
@@ -79,10 +77,8 @@
"shift-down": "editor::SelectDown",
"shift-left": "editor::SelectLeft",
"shift-right": "editor::SelectRight",
"ctrl-shift-left": "editor::SelectToPreviousWordStart",
"ctrl-shift-right": "editor::SelectToNextWordEnd",
"ctrl-shift-up": "editor::AddSelectionAbove",
"ctrl-shift-down": "editor::AddSelectionBelow",
"ctrl-shift-left": "editor::SelectToPreviousWordStart", // cursorWordLeftSelect
"ctrl-shift-right": "editor::SelectToNextWordEnd", // cursorWordRightSelect
"ctrl-shift-home": "editor::SelectToBeginning",
"ctrl-shift-end": "editor::SelectToEnd",
"ctrl-a": "editor::SelectAll",
@@ -109,8 +105,8 @@
"bindings": {
"enter": "editor::Newline",
"shift-enter": "editor::Newline",
"ctrl-shift-enter": "editor::NewlineBelow",
"ctrl-enter": "editor::NewlineAbove",
"ctrl-shift-enter": "editor::NewlineBelow",
"alt-z": "editor::ToggleSoftWrap",
"ctrl-f": "buffer_search::Deploy",
"ctrl-h": ["buffer_search::Deploy", { "replace_enabled": true }],
@@ -208,7 +204,7 @@
}
},
{
"context": "ProjectSearchBar && in_replace",
"context": "ProjectSearchBar && in_replace > Editor",
"bindings": {
"enter": "search::ReplaceNext",
"ctrl-alt-enter": "search::ReplaceAll"
@@ -261,20 +257,20 @@
"bindings": {
"ctrl-[": "editor::Outdent",
"ctrl-]": "editor::Indent",
"shift-alt-up": "editor::AddSelectionAbove",
"shift-alt-down": "editor::AddSelectionBelow",
"shift-alt-up": "editor::AddSelectionAbove", // Insert Cursor Above
"shift-alt-down": "editor::AddSelectionBelow", // Insert Cursor Below
"ctrl-shift-k": "editor::DeleteLine",
"alt-up": "editor::MoveLineUp",
"alt-down": "editor::MoveLineDown",
"ctrl-alt-shift-up": "editor::DuplicateLineUp",
"ctrl-alt-shift-down": "editor::DuplicateLineDown",
"ctrl-shift-left": "editor::SelectToPreviousWordStart",
"ctrl-shift-right": "editor::SelectToNextWordEnd",
"ctrl-shift-up": "editor::SelectLargerSyntaxNode", //todo(linux) tmp keybinding
"ctrl-shift-down": "editor::SelectSmallerSyntaxNode", //todo(linux) tmp keybinding
"alt-shift-right": "editor::SelectLargerSyntaxNode", // Expand Selection
"alt-shift-left": "editor::SelectSmallerSyntaxNode", // Shrink Selection
"ctrl-shift-l": "editor::SelectAllMatches", // Select all occurrences of current selection
"ctrl-f2": "editor::SelectAllMatches", // Select all occurrences of current word
"ctrl-d": ["editor::SelectNext", { "replace_newest": false }],
"ctrl-shift-l": "editor::SelectAllMatches",
"ctrl-shift-d": ["editor::SelectPrevious", { "replace_newest": false }],
"ctrl-shift-down": ["editor::SelectNext", { "replace_newest": false }], // Add selection to Next Find Match
"ctrl-shift-up": ["editor::SelectPrevious", { "replace_newest": false }],
"ctrl-k ctrl-d": ["editor::SelectNext", { "replace_newest": true }],
"ctrl-k ctrl-shift-d": ["editor::SelectPrevious", { "replace_newest": true }],
"ctrl-k ctrl-i": "editor::Hover",
@@ -327,7 +323,7 @@
"alt-9": ["pane::ActivateItem", 8],
"alt-0": "pane::ActivateLastItem",
"ctrl-alt--": "pane::GoBack",
"ctrl-alt-shift--": "pane::GoForward",
"ctrl-alt-_": "pane::GoForward",
"ctrl-shift-t": "pane::ReopenClosedItem",
"f3": "search::SelectNextMatch",
"shift-f3": "search::SelectPrevMatch",
@@ -398,7 +394,7 @@
"bindings": {
"ctrl-shift-k": "editor::DeleteLine",
"ctrl-shift-d": "editor::DuplicateLineDown",
"ctrl-j": "editor::JoinLines",
"ctrl-shift-j": "editor::JoinLines",
"ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart",
"ctrl-alt-h": "editor::DeleteToPreviousSubwordStart",
"ctrl-alt-delete": "editor::DeleteToNextSubwordEnd",
@@ -481,6 +477,12 @@
"ctrl-enter": "assistant::InlineAssist"
}
},
{
"context": "Editor && jupyter && !ContextEditor",
"bindings": {
"ctrl-shift-enter": "repl::Run"
}
},
{
"context": "ContextEditor > Editor",
"bindings": {
@@ -567,6 +569,13 @@
"tab": "channel_modal::ToggleMode"
}
},
{
"context": "Picker > Editor",
"bindings": {
"tab": "picker::ConfirmCompletion",
"alt-enter": ["picker::ConfirmInput", { "secondary": false }]
}
},
{
"context": "ChannelModal > Picker > Editor",
"bindings": {
@@ -592,6 +601,7 @@
"ctrl-alt-space": "terminal::ShowCharacterPalette",
"shift-ctrl-c": "terminal::Copy",
"ctrl-insert": "terminal::Copy",
"ctrl-a": "editor::SelectAll",
"shift-ctrl-v": "terminal::Paste",
"shift-insert": "terminal::Paste",
"ctrl-enter": "assistant::InlineAssist",

View File

@@ -83,7 +83,7 @@
"ctrl-n": "editor::MoveDown",
"ctrl-b": "editor::MoveLeft",
"ctrl-f": "editor::MoveRight",
"ctrl-l": "editor::NextScreen",
"ctrl-l": "editor::ScrollCursorCenter",
"alt-left": "editor::MoveToPreviousWordStart",
"alt-b": "editor::MoveToPreviousWordStart",
"alt-right": "editor::MoveToNextWordEnd",
@@ -102,9 +102,9 @@
"ctrl-shift-b": "editor::SelectLeft",
"shift-right": "editor::SelectRight",
"ctrl-shift-f": "editor::SelectRight",
"alt-shift-left": "editor::SelectToPreviousWordStart",
"alt-shift-left": "editor::SelectToPreviousWordStart", // cursorWordLeftSelect
"alt-shift-b": "editor::SelectToPreviousWordStart",
"alt-shift-right": "editor::SelectToNextWordEnd",
"alt-shift-right": "editor::SelectToNextWordEnd", // cursorWordRightSelect
"alt-shift-f": "editor::SelectToNextWordEnd",
"ctrl-shift-up": "editor::SelectToStartOfParagraph",
"ctrl-shift-down": "editor::SelectToEndOfParagraph",
@@ -135,6 +135,7 @@
"bindings": {
"enter": "editor::Newline",
"shift-enter": "editor::Newline",
"cmd-enter": "editor::NewlineBelow",
"cmd-shift-enter": "editor::NewlineAbove",
"alt-z": "editor::ToggleSoftWrap",
"cmd-f": "buffer_search::Deploy",
@@ -146,12 +147,6 @@
"cmd-alt-e": "editor::SelectEnclosingSymbol"
}
},
{
"context": "Editor && mode == full && !jupyter",
"bindings": {
"cmd-enter": "editor::NewlineBelow"
}
},
{
"context": "Editor && mode == full && inline_completion",
"bindings": {
@@ -180,6 +175,12 @@
"cmd-c": "markdown::Copy"
}
},
{
"context": "Editor && jupyter && !ContextEditor",
"bindings": {
"ctrl-shift-enter": "repl::Run"
}
},
{
"context": "AssistantPanel",
"bindings": {
@@ -255,7 +256,7 @@
}
},
{
"context": "ProjectSearchBar && in_replace",
"context": "ProjectSearchBar && in_replace > Editor",
"bindings": {
"enter": "search::ReplaceNext",
"cmd-enter": "search::ReplaceAll"
@@ -292,7 +293,6 @@
"alt-cmd-c": "search::ToggleCaseSensitive",
"alt-cmd-w": "search::ToggleWholeWord",
"alt-cmd-f": "project_search::ToggleFilters",
"alt-cmd-g": "search::ToggleRegex",
"alt-cmd-x": "search::ToggleRegex"
}
},
@@ -302,19 +302,20 @@
"bindings": {
"cmd-[": "editor::Outdent",
"cmd-]": "editor::Indent",
"cmd-alt-up": "editor::AddSelectionAbove",
"cmd-alt-up": "editor::AddSelectionAbove", // Insert cursor above
"cmd-ctrl-p": "editor::AddSelectionAbove",
"cmd-alt-down": "editor::AddSelectionBelow",
"cmd-alt-down": "editor::AddSelectionBelow", // Insert cursor below
"cmd-ctrl-n": "editor::AddSelectionBelow",
"cmd-shift-k": "editor::DeleteLine",
"alt-up": "editor::MoveLineUp",
"alt-down": "editor::MoveLineDown",
"alt-shift-up": "editor::DuplicateLineUp",
"alt-shift-down": "editor::DuplicateLineDown",
"ctrl-shift-right": "editor::SelectLargerSyntaxNode",
"ctrl-shift-left": "editor::SelectSmallerSyntaxNode",
"cmd-d": ["editor::SelectNext", { "replace_newest": false }],
"cmd-shift-l": "editor::SelectAllMatches",
"ctrl-shift-right": "editor::SelectLargerSyntaxNode", // Expand Selection
"ctrl-shift-left": "editor::SelectSmallerSyntaxNode", // Shrink Selection
"cmd-d": ["editor::SelectNext", { "replace_newest": false }], // Add selection to Next Find Match
"cmd-shift-l": "editor::SelectAllMatches", // Select all occurrences of current selection
"cmd-f2": "editor::SelectAllMatches", // Select all occurrences of current word
"ctrl-cmd-d": ["editor::SelectPrevious", { "replace_newest": false }],
"cmd-k cmd-d": ["editor::SelectNext", { "replace_newest": true }],
"cmd-k ctrl-cmd-d": ["editor::SelectPrevious", { "replace_newest": true }],
@@ -569,12 +570,6 @@
"space": "project_panel::Open"
}
},
{
"context": "Editor && jupyter && !ContextEditor",
"bindings": {
"cmd-enter": "repl::Run"
}
},
{
"context": "CollabPanel && not_editing",
"bindings": {
@@ -594,6 +589,14 @@
"tab": "channel_modal::ToggleMode"
}
},
{
"context": "Picker > Editor",
"bindings": {
"tab": "picker::ConfirmCompletion",
"alt-enter": ["picker::ConfirmInput", { "secondary": false }],
"cmd-alt-enter": ["picker::ConfirmInput", { "secondary": true }]
}
},
{
"context": "ChannelModal > Picker > Editor",
"bindings": {
@@ -613,20 +616,13 @@
"ctrl-backspace": "tab_switcher::CloseSelectedItem"
}
},
{
"context": "Picker",
"bindings": {
"f2": "picker::UseSelectedQuery",
"alt-enter": ["picker::ConfirmInput", { "secondary": false }],
"cmd-alt-enter": ["picker::ConfirmInput", { "secondary": true }]
}
},
{
"context": "Terminal",
"bindings": {
"ctrl-cmd-space": "terminal::ShowCharacterPalette",
"cmd-c": "terminal::Copy",
"cmd-v": "terminal::Paste",
"cmd-a": "editor::SelectAll",
"cmd-k": "terminal::Clear",
"ctrl-enter": "assistant::InlineAssist",
// Some nice conveniences

View File

@@ -0,0 +1,21 @@
// Zed keymap
//
// For information on binding keys, see the Zed
// documentation: https://zed.dev/docs/key-bindings
//
// To see the default key bindings run `zed: Open Default Keymap`
// from the command palette.
[
{
"context": "Workspace",
"bindings": {
// "shift shift": "file_finder::Toggle"
}
},
{
"context": "Editor",
"bindings": {
// "j k": ["workspace::SendKeystrokes", "escape"]
}
}
]

View File

@@ -25,6 +25,7 @@
"ctrl-shift-d": "editor::DuplicateLineDown", // editor:duplicate-lines
"ctrl-up": "editor::MoveLineUp", // editor:move-line-up
"ctrl-down": "editor::MoveLineDown", // editor:move-line-down
"ctrl-\\": "workspace::ToggleLeftDock", // tree-view:toggle
"ctrl-shift-m": "markdown::OpenPreviewToTheSide" // markdown-preview:toggle
}
},

View File

@@ -13,6 +13,7 @@
"ctrl-shift-j": "editor::JoinLines",
"ctrl-d": "editor::DuplicateLineDown",
"ctrl-y": "editor::DeleteLine",
"ctrl-m": "editor::ScrollCursorCenter",
"ctrl-pagedown": "editor::MovePageDown",
"ctrl-pageup": "editor::MovePageUp",
// "ctrl-alt-shift-b": "editor::SelectToPreviousWordStart",

View File

@@ -3,17 +3,17 @@
"bindings": {
"ctrl-shift-[": "pane::ActivatePrevItem",
"ctrl-shift-]": "pane::ActivateNextItem",
"ctrl-pagedown": "pane::ActivatePrevItem",
"ctrl-pageup": "pane::ActivateNextItem",
"ctrl-shift-tab": "pane::ActivateNextItem",
"ctrl-tab": "pane::ActivatePrevItem"
"ctrl-pageup": "pane::ActivatePrevItem",
"ctrl-pagedown": "pane::ActivateNextItem",
"ctrl-tab": "pane::ActivateNextItem",
"ctrl-shift-tab": "pane::ActivatePrevItem"
}
},
{
"context": "Editor",
"bindings": {
"ctrl-shift-up": "editor::AddSelectionAbove",
"ctrl-shift-down": "editor::AddSelectionBelow",
"ctrl-shift-up": "editor::MoveLineUp",
"ctrl-shift-down": "editor::MoveLineDown",
"ctrl-shift-m": "editor::SelectLargerSyntaxNode",
"ctrl-shift-l": "editor::SplitSelectionIntoLines",
"ctrl-shift-a": "editor::SelectLargerSyntaxNode",
@@ -24,6 +24,8 @@
"ctrl-shift-f12": "editor::FindAllReferences",
"ctrl-.": "editor::GoToHunk",
"ctrl-,": "editor::GoToPrevHunk",
"ctrl-k ctrl-u": "editor::ConvertToUpperCase",
"ctrl-k ctrl-l": "editor::ConvertToLowerCase",
"shift-alt-m": "markdown::OpenPreviewToTheSide",
"ctrl-backspace": "editor::DeleteToPreviousWordStart",
"ctrl-delete": "editor::DeleteToNextWordEnd"

View File

@@ -26,6 +26,7 @@
"cmd-shift-d": "editor::DuplicateLineDown",
"ctrl-cmd-up": "editor::MoveLineUp",
"ctrl-cmd-down": "editor::MoveLineDown",
"cmd-\\": "workspace::ToggleLeftDock",
"ctrl-shift-m": "markdown::OpenPreviewToTheSide"
}
},

View File

@@ -3,10 +3,10 @@
"bindings": {
"cmd-shift-[": "pane::ActivatePrevItem",
"cmd-shift-]": "pane::ActivateNextItem",
"ctrl-pagedown": "pane::ActivatePrevItem",
"ctrl-pageup": "pane::ActivateNextItem",
"ctrl-shift-tab": "pane::ActivateNextItem",
"ctrl-tab": "pane::ActivatePrevItem"
"ctrl-pageup": "pane::ActivatePrevItem",
"ctrl-pagedown": "pane::ActivateNextItem",
"ctrl-tab": "pane::ActivateNextItem",
"ctrl-shift-tab": "pane::ActivatePrevItem"
}
},
{
@@ -14,6 +14,8 @@
"bindings": {
"ctrl-shift-up": "editor::AddSelectionAbove",
"ctrl-shift-down": "editor::AddSelectionBelow",
"cmd-ctrl-up": "editor::MoveLineUp",
"cmd-ctrl-down": "editor::MoveLineDown",
"cmd-shift-space": "editor::SelectAll",
"ctrl-shift-m": "editor::SelectLargerSyntaxNode",
"cmd-shift-l": "editor::SplitSelectionIntoLines",
@@ -27,6 +29,7 @@
"ctrl-,": "editor::GoToPrevHunk",
"cmd-k cmd-u": "editor::ConvertToUpperCase",
"cmd-k cmd-l": "editor::ConvertToLowerCase",
"cmd-shift-j": "editor::JoinLines",
"shift-alt-m": "markdown::OpenPreviewToTheSide",
"ctrl-backspace": "editor::DeleteToPreviousWordStart",
"ctrl-delete": "editor::DeleteToNextWordEnd"

View File

@@ -1,12 +1,6 @@
[
{
"context": "ProjectPanel || Editor",
"bindings": {
"ctrl-6": "pane::AlternateFile"
}
},
{
"context": "Editor && VimControl && !VimWaiting && !menu",
"context": "VimControl && !menu",
"bindings": {
"i": ["vim::PushOperator", { "Object": { "around": false } }],
"a": ["vim::PushOperator", { "Object": { "around": true } }],
@@ -16,8 +10,11 @@
"backspace": "vim::Backspace",
"j": "vim::Down",
"down": "vim::Down",
"ctrl-j": "vim::Down",
"enter": "vim::NextLineStart",
"ctrl-m": "vim::NextLineStart",
"+": "vim::NextLineStart",
"-": "vim::PreviousLineStart",
"tab": "vim::Tab",
"shift-tab": "vim::Tab",
"k": "vim::Up",
@@ -198,20 +195,20 @@
"ctrl-w g shift-d": "editor::GoToTypeDefinitionSplit",
"ctrl-w space": "editor::OpenExcerptsSplit",
"ctrl-w g space": "editor::OpenExcerptsSplit",
"-": "pane::RevealInProjectPanel"
"ctrl-6": "pane::AlternateFile"
}
},
{
// escape is in its own section so that it cancels a pending count.
"context": "Editor && vim_mode == normal && vim_operator == none && !VimWaiting",
"context": "VimControl && VimCount",
"bindings": {
"0": ["vim::Number", 0]
}
},
{
"context": "vim_mode == normal",
"bindings": {
"escape": "editor::Cancel",
"ctrl-[": "editor::Cancel"
}
},
{
"context": "Editor && vim_mode == normal && vim_operator == none && !VimWaiting",
"bindings": {
"ctrl-[": "editor::Cancel",
".": "vim::Repeat",
"c": ["vim::PushOperator", "Change"],
"shift-c": "vim::ChangeToEndOfLine",
@@ -219,7 +216,7 @@
"shift-d": "vim::DeleteToEndOfLine",
"shift-j": "vim::JoinLines",
"y": ["vim::PushOperator", "Yank"],
"shift-y": "vim::YankLine",
"shift-y": "vim::YankToEndOfLine",
"i": "vim::InsertBefore",
"shift-i": "vim::InsertFirstNonWhitespace",
"a": "vim::InsertAfter",
@@ -255,127 +252,12 @@
"] d": "editor::GoToDiagnostic",
"[ d": "editor::GoToPrevDiagnostic",
"] c": "editor::GoToHunk",
"[ c": "editor::GoToPrevHunk"
"[ c": "editor::GoToPrevHunk",
"g c": ["vim::PushOperator", "ToggleComments"]
}
},
{
"context": "Editor && vim_mode == visual && vim_operator == none && !VimWaiting",
"bindings": {
"\"": ["vim::PushOperator", "Register"],
// tree-sitter related commands
"[ x": "editor::SelectLargerSyntaxNode",
"] x": "editor::SelectSmallerSyntaxNode"
}
},
{
"context": "Editor && VimCount && vim_mode != insert",
"bindings": {
"0": ["vim::Number", 0]
}
},
{
"context": "Editor && vim_operator == c",
"bindings": {
"c": "vim::CurrentLine",
"d": "editor::Rename" // zed specific
}
},
{
"context": "Editor && vim_mode == normal && vim_operator == c",
"bindings": {
"s": ["vim::PushOperator", { "ChangeSurrounds": {} }]
}
},
{
"context": "Editor && vim_operator == d",
"bindings": {
"d": "vim::CurrentLine"
}
},
{
"context": "Editor && vim_operator == gu",
"bindings": {
"g u": "vim::CurrentLine",
"u": "vim::CurrentLine"
}
},
{
"context": "Editor && vim_operator == gU",
"bindings": {
"g shift-u": "vim::CurrentLine",
"shift-u": "vim::CurrentLine"
}
},
{
"context": "Editor && vim_operator == g~",
"bindings": {
"g ~": "vim::CurrentLine",
"~": "vim::CurrentLine"
}
},
{
"context": "Editor && vim_mode == normal && vim_operator == d",
"bindings": {
"s": ["vim::PushOperator", "DeleteSurrounds"]
}
},
{
"context": "Editor && vim_operator == y",
"bindings": {
"y": "vim::CurrentLine"
}
},
{
"context": "Editor && vim_mode == normal && vim_operator == y",
"bindings": {
"s": ["vim::PushOperator", { "AddSurrounds": {} }]
}
},
{
"context": "Editor && vim_operator == ys",
"bindings": {
"s": "vim::CurrentLine"
}
},
{
"context": "Editor && vim_operator == >",
"bindings": {
">": "vim::CurrentLine"
}
},
{
"context": "Editor && vim_operator == <",
"bindings": {
"<": "vim::CurrentLine"
}
},
{
"context": "Editor && VimObject",
"bindings": {
"w": "vim::Word",
"shift-w": ["vim::Word", { "ignorePunctuation": true }],
"t": "vim::Tag",
"s": "vim::Sentence",
"p": "vim::Paragraph",
"'": "vim::Quotes",
"`": "vim::BackQuotes",
"\"": "vim::DoubleQuotes",
"|": "vim::VerticalBars",
"(": "vim::Parentheses",
")": "vim::Parentheses",
"b": "vim::Parentheses",
"[": "vim::SquareBrackets",
"]": "vim::SquareBrackets",
"{": "vim::CurlyBrackets",
"}": "vim::CurlyBrackets",
"shift-b": "vim::CurlyBrackets",
"<": "vim::AngleBrackets",
">": "vim::AngleBrackets",
"a": "vim::Argument"
}
},
{
"context": "Editor && vim_mode == visual && !VimWaiting && !VimObject",
"context": "vim_mode == visual",
"bindings": {
"u": "vim::ConvertToLowerCase",
"U": "vim::ConvertToUpperCase",
@@ -410,23 +292,16 @@
">": "vim::Indent",
"<": "vim::Outdent",
"i": ["vim::PushOperator", { "Object": { "around": false } }],
"a": ["vim::PushOperator", { "Object": { "around": true } }]
"a": ["vim::PushOperator", { "Object": { "around": true } }],
"g c": "vim::ToggleComments",
"\"": ["vim::PushOperator", "Register"],
// tree-sitter related commands
"[ x": "editor::SelectLargerSyntaxNode",
"] x": "editor::SelectSmallerSyntaxNode"
}
},
{
"context": "Editor && vim_mode == normal && !VimWaiting",
"bindings": {
"g c c": "vim::ToggleComments"
}
},
{
"context": "Editor && vim_mode == visual",
"bindings": {
"g c": "vim::ToggleComments"
}
},
{
"context": "Editor && vim_mode == insert",
"context": "vim_mode == insert",
"bindings": {
"escape": "vim::NormalBefore",
"ctrl-c": "vim::NormalBefore",
@@ -445,30 +320,124 @@
}
},
{
"context": "Editor && vim_mode == replace",
"context": "vim_mode == replace",
"bindings": {
"escape": "vim::NormalBefore",
"ctrl-c": "vim::NormalBefore",
"ctrl-[": "vim::NormalBefore",
"backspace": "vim::UndoReplace",
"tab": "vim::Tab",
"enter": "vim::Enter",
"backspace": "vim::UndoReplace"
"enter": "vim::Enter"
}
},
{
"context": "Editor && vim_mode != replace && VimWaiting",
"context": "vim_mode == waiting",
"bindings": {
"tab": "vim::Tab",
"enter": "vim::Enter",
"escape": ["vim::SwitchMode", "Normal"],
"ctrl-[": ["vim::SwitchMode", "Normal"]
"escape": "vim::ClearOperators",
"ctrl-c": "vim::ClearOperators",
"ctrl-[": "vim::ClearOperators"
}
},
{
"context": "Editor && vim_mode == insert && VimWaiting",
"context": "vim_mode == operator",
"bindings": {
"escape": "vim::NormalBefore",
"ctrl-[": "vim::NormalBefore"
"escape": "vim::ClearOperators",
"ctrl-c": "vim::ClearOperators",
"ctrl-[": "vim::ClearOperators"
}
},
{
"context": "vim_operator == a || vim_operator == i || vim_operator == cs",
"bindings": {
"w": "vim::Word",
"shift-w": ["vim::Word", { "ignorePunctuation": true }],
"t": "vim::Tag",
"s": "vim::Sentence",
"p": "vim::Paragraph",
"'": "vim::Quotes",
"`": "vim::BackQuotes",
"\"": "vim::DoubleQuotes",
"|": "vim::VerticalBars",
"(": "vim::Parentheses",
")": "vim::Parentheses",
"b": "vim::Parentheses",
"[": "vim::SquareBrackets",
"]": "vim::SquareBrackets",
"{": "vim::CurlyBrackets",
"}": "vim::CurlyBrackets",
"shift-b": "vim::CurlyBrackets",
"<": "vim::AngleBrackets",
">": "vim::AngleBrackets",
"a": "vim::Argument"
}
},
{
"context": "vim_operator == c",
"bindings": {
"c": "vim::CurrentLine",
"d": "editor::Rename", // zed specific
"s": ["vim::PushOperator", { "ChangeSurrounds": {} }]
}
},
{
"context": "vim_operator == d",
"bindings": {
"d": "vim::CurrentLine",
"s": ["vim::PushOperator", "DeleteSurrounds"]
}
},
{
"context": "vim_operator == gu",
"bindings": {
"g u": "vim::CurrentLine",
"u": "vim::CurrentLine"
}
},
{
"context": "vim_operator == gU",
"bindings": {
"g shift-u": "vim::CurrentLine",
"shift-u": "vim::CurrentLine"
}
},
{
"context": "vim_operator == g~",
"bindings": {
"g ~": "vim::CurrentLine",
"~": "vim::CurrentLine"
}
},
{
"context": "vim_operator == y",
"bindings": {
"y": "vim::CurrentLine",
"s": ["vim::PushOperator", { "AddSurrounds": {} }]
}
},
{
"context": "vim_operator == ys",
"bindings": {
"s": "vim::CurrentLine"
}
},
{
"context": "vim_operator == >",
"bindings": {
">": "vim::CurrentLine"
}
},
{
"context": "vim_operator == <",
"bindings": {
"<": "vim::CurrentLine"
}
},
{
"context": "vim_operator == gc",
"bindings": {
"c": "vim::CurrentLine"
}
},
{
@@ -508,7 +477,8 @@
"x": "project_panel::RevealInFileManager",
"shift-g": "menu::SelectLast",
"g g": "menu::SelectFirst",
"-": "project_panel::SelectParent"
"-": "project_panel::SelectParent",
"ctrl-6": "pane::AlternateFile"
}
},
{

View File

@@ -0,0 +1,241 @@
Your task is to map a step from the conversation above to operations on symbols inside the provided source files.
Guidelines:
- There's no need to describe *what* to do, just *where* to do it.
- If creating a file, assume any subsequent updates are included at the time of creation.
- Don't create and then update a file.
- We'll create it in one shot.
- Prefer updating symbols lower in the syntax tree if possible.
- Never include operations on a parent symbol and one of its children in the same <operations> block.
- Never nest an operation with another operation or include CDATA or other content. All operations are leaf nodes.
- Include a description attribute for each operation with a brief, one-line description of the change to perform.
- Descriptions are required for all operations except delete.
- When generating multiple operations, ensure the descriptions are specific to each individual operation.
- Avoid referring to the location in the description. Focus on the change to be made, not the location where it's made. That's implicit with the symbol you provide.
- Don't generate multiple operations at the same location. Instead, combine them together in a single operation with a succinct combined description.
The available operation types are:
1. <update>: Modify an existing symbol in a file.
2. <create_file>: Create a new file.
3. <insert_sibling_after>: Add a new symbol as sibling after an existing symbol in a file.
4. <append_child>: Add a new symbol as the last child of an existing symbol in a file.
5. <prepend_child>: Add a new symbol as the first child of an existing symbol in a file.
6. <delete>: Remove an existing symbol from a file. The `description` attribute is invalid for delete, but required for other ops.
All operations *require* a path.
Operations that *require* a symbol: <update>, <insert_sibling_after>, <delete>
Operations that don't allow a symbol: <create>
Operations that have an *optional* symbol: <prepend_child>, <append_child>
Example 1:
User:
```rs src/rectangle.rs
struct Rectangle {
width: f64,
height: f64,
}
impl Rectangle {
fn new(width: f64, height: f64) -> Self {
Rectangle { width, height }
}
}
```
Symbols for src/rectangle.rs:
- struct Rectangle
- impl Rectangle
- impl Rectangle fn new
<step>Add new methods 'calculate_area' and 'calculate_perimeter' to the Rectangle struct</step>
<step>Implement the 'Display' trait for the Rectangle struct</step>
What are the operations for the step: <step>Add a new method 'calculate_area' to the Rectangle struct</step>
Assistant (wrong):
<operations>
<append_child path="src/shapes.rs" symbol="impl Rectangle" description="Add calculate_area method" />
<append_child path="src/shapes.rs" symbol="impl Rectangle" description="Add calculate_perimeter method" />
</operations>
This demonstrates what NOT to do. NEVER append multiple children at the same location.
Assistant (corrected):
<operations>
<append_child path="src/shapes.rs" symbol="impl Rectangle" description="Add calculate area and perimeter methods" />
</operations>
User:
What are the operations for the step: <step>Implement the 'Display' trait for the Rectangle struct</step>
Assistant:
<operations>
<insert_sibling_after path="src/shapes.rs" symbol="impl Rectangle" description="Implement Display trait for Rectangle"/>
</operations>
Example 2:
User:
```rs src/user.rs
struct User {
pub name: String,
age: u32,
email: String,
}
impl User {
fn new(name: String, age: u32, email: String) -> Self {
User { name, age, email }
}
pub fn print_info(&self) {
println!("Name: {}, Age: {}, Email: {}", self.name, self.age, self.email);
}
}
```
Symbols for src/user.rs:
- struct User
- struct User pub name
- struct User age
- struct User email
- impl User
- impl User fn new
- impl User pub fn print_info
<step>Update the 'print_info' method to use formatted output</step>
<step>Remove the 'email' field from the User struct</step>
What are the operations for the step: <step>Update the 'print_info' method to use formatted output</step>
Assistant:
<operations>
<update path="src/user.rs" symbol="impl User fn print_info" description="Use formatted output" />
</operations>
User:
What are the operations for the step: <step>Remove the 'email' field from the User struct</step>
Assistant:
<operations>
<delete path="src/user.rs" symbol="struct User email" description="Remove the email field" />
</operations>
Example 3:
User:
```rs src/vehicle.rs
struct Vehicle {
make: String,
model: String,
year: u32,
}
impl Vehicle {
fn new(make: String, model: String, year: u32) -> Self {
Vehicle { make, model, year }
}
fn print_year(&self) {
println!("Year: {}", self.year);
}
}
```
Symbols for src/vehicle.rs:
- struct Vehicle
- struct Vehicle make
- struct Vehicle model
- struct Vehicle year
- impl Vehicle
- impl Vehicle fn new
- impl Vehicle fn print_year
<step>Add a 'use std::fmt;' statement at the beginning of the file</step>
<step>Add a new method 'start_engine' in the Vehicle impl block</step>
What are the operations for the step: <step>Add a 'use std::fmt;' statement at the beginning of the file</step>
Assistant:
<operations>
<prepend_child path="src/vehicle.rs" description="Add 'use std::fmt' statement" />
</operations>
User:
What are the operations for the step: <step>Add a new method 'start_engine' in the Vehicle impl block</step>
Assistant:
<operations>
<insert_sibling_after path="src/vehicle.rs" symbol="impl Vehicle fn new" description="Add start_engine method"/>
</operations>
Example 4:
User:
```rs src/employee.rs
struct Employee {
name: String,
position: String,
salary: u32,
department: String,
}
impl Employee {
fn new(name: String, position: String, salary: u32, department: String) -> Self {
Employee { name, position, salary, department }
}
fn print_details(&self) {
println!("Name: {}, Position: {}, Salary: {}, Department: {}",
self.name, self.position, self.salary, self.department);
}
fn give_raise(&mut self, amount: u32) {
self.salary += amount;
}
}
```
Symbols for src/employee.rs:
- struct Employee
- struct Employee name
- struct Employee position
- struct Employee salary
- struct Employee department
- impl Employee
- impl Employee fn new
- impl Employee fn print_details
- impl Employee fn give_raise
<step>Make salary an f32</step>
What are the operations for the step: <step>Make salary an f32</step>
A (wrong):
<operations>
<update path="src/employee.rs" symbol="struct Employee" description="Change the type of salary to an f32" />
<update path="src/employee.rs" symbol="struct Employee salary" description="Change the type to an f32" />
</operations>
This example demonstrates what not to do. `struct Employee salary` is a child of `struct Employee`.
A (corrected):
<operations>
<update path="src/employee.rs" symbol="struct Employee salary" description="Change the type to an f32" />
</operations>
User:
What are the correct operations for the step: <step>Remove the 'department' field and update the 'print_details' method</step>
A:
<operations>
<delete path="src/employee.rs" symbol="struct Employee department" />
<update path="src/employee.rs" symbol="impl Employee fn print_details" description="Don't print the 'department' field" />
</operations>
Now generate the operations for the following step.
Output only valid XML containing valid operations with their required attributes.
NEVER output code or any other text inside <operation> tags. If you do, you will replaced with another model.
Your response *MUST* begin with <operations> and end with </operations>:

View File

@@ -26,6 +26,9 @@
},
// The name of a font to use for rendering text in the editor
"buffer_font_family": "Zed Plex Mono",
// Set the buffer text's font fallbacks, this will be merged with
// the platform's default fallbacks.
"buffer_font_fallbacks": [],
// The OpenType features to enable for text in the editor.
"buffer_font_features": {
// Disable ligatures:
@@ -47,8 +50,11 @@
// },
"buffer_line_height": "comfortable",
// The name of a font to use for rendering text in the UI
// (On macOS) You can set this to ".SystemUIFont" to use the system font
// You can set this to ".SystemUIFont" to use the system font
"ui_font_family": "Zed Plex Sans",
// Set the UI's font fallbacks, this will be merged with the platform's
// default font fallbacks.
"ui_font_fallbacks": [],
// The OpenType features to enable for text in the UI
"ui_font_features": {
// Disable ligatures:
@@ -82,7 +88,7 @@
// Whether to confirm before quitting Zed.
"confirm_quit": false,
// Whether to restore last closed project when fresh Zed instance is opened.
"restore_on_startup": "last_workspace",
"restore_on_startup": "last_session",
// Size of the drop target in the editor.
"drop_target_size": 0.2,
// Whether the window should be closed when using 'close active item' on a window with no tabs.
@@ -94,6 +100,9 @@
// 3. Never close the window
// "when_closing_with_no_tabs": "keep_window_open",
"when_closing_with_no_tabs": "platform_default",
// Whether to use the system provided dialogs for Open and Save As.
// When set to false, Zed will use the built-in keyboard-first pickers.
"use_system_path_prompts": true,
// Whether the cursor blinks in the editor.
"cursor_blink": true,
// How to highlight the current line in the editor.
@@ -133,14 +142,7 @@
// The default number of lines to expand excerpts in the multibuffer by.
"expand_excerpt_lines": 3,
// Globs to match against file paths to determine if a file is private.
"private_files": [
"**/.env*",
"**/*.pem",
"**/*.key",
"**/*.cert",
"**/*.crt",
"**/secrets.yml"
],
"private_files": ["**/.env*", "**/*.pem", "**/*.key", "**/*.cert", "**/*.crt", "**/secrets.yml"],
// Whether to use additional LSP queries to format (and amend) the code after
// every "trigger" symbol input, defined by LSP server capabilities.
"use_on_type_format": true,
@@ -316,7 +318,7 @@
"auto_reveal_entries": true,
// Whether to fold directories automatically and show compact folders
// (e.g. "a/b/c" ) when a directory has only one subdirectory inside.
"auto_fold_dirs": false,
"auto_fold_dirs": true,
/// Scrollbar-related settings
"scrollbar": {
/// When to show the scrollbar in the project panel.
@@ -379,7 +381,7 @@
},
"assistant": {
// Version of this setting.
"version": "1",
"version": "2",
// Whether the assistant is enabled.
"enabled": true,
// Whether to show the assistant panel button in the status bar.
@@ -390,17 +392,12 @@
"default_width": 640,
// Default height when the assistant is docked to the bottom.
"default_height": 320,
// AI provider.
"provider": {
"name": "openai",
// The default model to use when creating new contexts. This
// setting can take three values:
//
// 1. "gpt-3.5-turbo"
// 2. "gpt-4"
// 3. "gpt-4-turbo-preview"
// 4. "gpt-4o"
"default_model": "gpt-4o"
// The default model to use when creating new contexts.
"default_model": {
// The provider to use.
"provider": "openai",
// The model to use.
"model": "gpt-4o"
}
},
// Whether the screen sharing icon is shown in the os status bar.
@@ -438,7 +435,9 @@
// Show git status colors in the editor tabs.
"git_status": false,
// Position of the close button on the editor tabs.
"close_position": "right"
"close_position": "right",
// Whether to show the file icon for a tab.
"file_icons": false
},
// Settings related to preview tabs.
"preview_tabs": {
@@ -546,6 +545,14 @@
// "delay_ms": 600
}
},
// Configuration for how direnv configuration should be loaded. May take 2 values:
// 1. Load direnv configuration through the shell hook, works for POSIX shells and fish.
// "load_direnv": "shell_hook"
// 2. Load direnv configuration using `direnv export json` directly.
// This can help with some shells that otherwise would not detect
// the direnv environment, such as nushell or elvish.
// "load_direnv": "direct"
"load_direnv": "shell_hook",
"inline_completions": {
// A list of globs representing files that inline completions should be disabled for.
"disabled_globs": [".env"]
@@ -674,6 +681,10 @@
// Set the terminal's font family. If this option is not included,
// the terminal will default to matching the buffer's font family.
// "font_family": "Zed Plex Mono",
// Set the terminal's font fallbacks. If this option is not included,
// the terminal will default to matching the buffer's font fallbacks.
// This will be merged with the platform's default font fallbacks
// "font_fallbacks": ["FiraCode Nerd Fonts"],
// Sets the maximum number of lines in the terminal's scrollback buffer.
// Default: 10_000, maximum: 100_000 (all bigger values set will be treated as 100_000), 0 disables the scrolling.
// Existing terminals will not pick up this change until they are recreated.
@@ -698,7 +709,7 @@
//
"file_types": {
"JSON": ["flake.lock"],
"JSONC": ["**/.zed/**/*.json", "**/zed/**/*.json"]
"JSONC": ["**/.zed/**/*.json", "**/zed/**/*.json", "**/Zed/**/*.json", "tsconfig.json"]
},
// The extensions that Zed should automatically install on startup.
//
@@ -721,10 +732,12 @@
}
},
"C": {
"format_on_save": "off"
"format_on_save": "off",
"use_on_type_format": false
},
"C++": {
"format_on_save": "off"
"format_on_save": "off",
"use_on_type_format": false
},
"CSS": {
"prettier": {
@@ -734,6 +747,9 @@
"Elixir": {
"language_servers": ["elixir-ls", "!next-ls", "!lexical", "..."]
},
"Erlang": {
"language_servers": ["erlang-ls", "!elp", "..."]
},
"Go": {
"code_actions_on_format": {
"source.organizeImports": true
@@ -776,11 +792,13 @@
},
"Markdown": {
"format_on_save": "off",
"use_on_type_format": false,
"prettier": {
"allowed": true
}
},
"PHP": {
"language_servers": ["phpactor", "!intelephense", "..."],
"prettier": {
"allowed": true,
"plugins": ["@prettier/plugin-php"],
@@ -788,7 +806,7 @@
}
},
"Ruby": {
"language_servers": ["solargraph", "!ruby-lsp", "..."]
"language_servers": ["solargraph", "!ruby-lsp", "!rubocop", "..."]
},
"SCSS": {
"prettier": {
@@ -801,6 +819,9 @@
"plugins": ["prettier-plugin-sql"]
}
},
"Starlark": {
"language_servers": ["starpls", "!buck2-lsp", "..."]
},
"Svelte": {
"prettier": {
"allowed": true,
@@ -841,6 +862,18 @@
}
}
},
// Different settings for specific language models.
"language_models": {
"anthropic": {
"api_url": "https://api.anthropic.com"
},
"openai": {
"api_url": "https://api.openai.com/v1"
},
"ollama": {
"api_url": "http://localhost:11434"
}
},
// Zed's Prettier integration settings.
// Allows to enable/disable formatting with Prettier
// and configure default Prettier, used when no project-level Prettier installation is found.
@@ -873,6 +906,15 @@
// }
// }
},
// Jupyter settings
"jupyter": {
"enabled": true
// Specify the language name as the key and the kernel name as the value.
// "kernel_selections": {
// "python": "conda-base"
// "typescript": "deno"
// }
},
// Vim settings
"vim": {
"use_system_clipboard": "always",
@@ -925,5 +967,29 @@
// Examples:
// - "proxy": "socks5://localhost:10808"
// - "proxy": "http://127.0.0.1:10809"
"proxy": null
"proxy": null,
// Set to configure aliases for the command palette.
// When typing a query which is a key of this object, the value will be used instead.
//
// Examples:
// {
// "W": "workspace::Save"
// }
"command_aliases": {},
// ssh_connections is an array of ssh connections.
// By default this setting is null, which disables the direct ssh connection support.
// You can configure these from `project: Open Remote` in the command palette.
// Zed's ssh support will pull configuration from your ~/.ssh too.
// Examples:
// [
// {
// "host": "example-box",
// "projects": [
// {
// "paths": ["/home/user/code/zed"]
// }
// ]
// }
// ]
"ssh_connections": null
}

View File

@@ -1,5 +1,5 @@
// Folder-specific settings
//
// For a full list of overridable settings, and general information on folder-specific settings,
// see the documentation: https://zed.dev/docs/configuring-zed#folder-specific-settings
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
{}

View File

@@ -17,6 +17,27 @@
// What to do with the terminal pane and tab, after the command was started:
// * `always` — always show the terminal pane, add and focus the corresponding task's tab in it (default)
// * `never` — avoid changing current terminal pane focus, but still add/reuse the task's tab there
"reveal": "always"
"reveal": "always",
// What to do with the terminal pane and tab, after the command had finished:
// * `never` — Do nothing when the command finishes (default)
// * `always` — always hide the terminal tab, hide the pane also if it was the last tab in it
// * `on_success` — hide the terminal tab on task success only, otherwise behaves similar to `always`
"hide": "never",
// Which shell to use when running a task inside the terminal.
// May take 3 values:
// 1. (default) Use the system's default terminal configuration in /etc/passwd
// "shell": "system"
// 2. A program:
// "shell": {
// "program": "sh"
// }
// 3. A program with arguments:
// "shell": {
// "with_arguments": {
// "program": "/bin/bash",
// "arguments": ["--login"]
// }
// }
"shell": "system"
}
]

View File

@@ -4,8 +4,8 @@
// documentation: https://zed.dev/docs/configuring-zed
//
// To see all of Zed's default settings without changing your
// custom settings, run the `open default settings` command
// from the command palette or from `Zed` application menu.
// custom settings, run the `zed: Open Default Settings` command
// from the command palette
{
"ui_font_size": 16,
"buffer_font_size": 16,

View File

@@ -38,6 +38,7 @@
"icon.accent": "#10a793ff",
"status_bar.background": "#262933ff",
"title_bar.background": "#262933ff",
"title_bar.inactive_background": "#21242bff",
"toolbar.background": "#1e2025ff",
"tab_bar.background": "#21242bff",
"tab.inactive_background": "#21242bff",

View File

@@ -38,6 +38,7 @@
"icon.accent": "#566ddaff",
"status_bar.background": "#3a353fff",
"title_bar.background": "#3a353fff",
"title_bar.inactive_background": "#221f26ff",
"toolbar.background": "#19171cff",
"tab_bar.background": "#221f26ff",
"tab.inactive_background": "#221f26ff",
@@ -422,6 +423,7 @@
"icon.accent": "#586cdaff",
"status_bar.background": "#bfbcc5ff",
"title_bar.background": "#bfbcc5ff",
"title_bar.inactive_background": "#e6e3ebff",
"toolbar.background": "#efecf4ff",
"tab_bar.background": "#e6e3ebff",
"tab.inactive_background": "#e6e3ebff",
@@ -806,6 +808,7 @@
"icon.accent": "#6684e0ff",
"status_bar.background": "#45433bff",
"title_bar.background": "#45433bff",
"title_bar.inactive_background": "#262622ff",
"toolbar.background": "#20201dff",
"tab_bar.background": "#262622ff",
"tab.inactive_background": "#262622ff",
@@ -1190,6 +1193,7 @@
"icon.accent": "#6684dfff",
"status_bar.background": "#cecab4ff",
"title_bar.background": "#cecab4ff",
"title_bar.inactive_background": "#eeebd7ff",
"toolbar.background": "#fefbecff",
"tab_bar.background": "#eeebd7ff",
"tab.inactive_background": "#eeebd7ff",
@@ -1574,6 +1578,7 @@
"icon.accent": "#36a165ff",
"status_bar.background": "#424136ff",
"title_bar.background": "#424136ff",
"title_bar.inactive_background": "#2c2b23ff",
"toolbar.background": "#22221bff",
"tab_bar.background": "#2c2b23ff",
"tab.inactive_background": "#2c2b23ff",
@@ -1958,6 +1963,7 @@
"icon.accent": "#37a165ff",
"status_bar.background": "#c5c4b9ff",
"title_bar.background": "#c5c4b9ff",
"title_bar.inactive_background": "#ebeae3ff",
"toolbar.background": "#f4f3ecff",
"tab_bar.background": "#ebeae3ff",
"tab.inactive_background": "#ebeae3ff",
@@ -2342,6 +2348,7 @@
"icon.accent": "#407ee6ff",
"status_bar.background": "#443c39ff",
"title_bar.background": "#443c39ff",
"title_bar.inactive_background": "#27211eff",
"toolbar.background": "#1b1918ff",
"tab_bar.background": "#27211eff",
"tab.inactive_background": "#27211eff",
@@ -2726,6 +2733,7 @@
"icon.accent": "#407ee6ff",
"status_bar.background": "#ccc7c5ff",
"title_bar.background": "#ccc7c5ff",
"title_bar.inactive_background": "#e9e6e4ff",
"toolbar.background": "#f0eeedff",
"tab_bar.background": "#e9e6e4ff",
"tab.inactive_background": "#e9e6e4ff",
@@ -3110,6 +3118,7 @@
"icon.accent": "#5169ebff",
"status_bar.background": "#433a43ff",
"title_bar.background": "#433a43ff",
"title_bar.inactive_background": "#252025ff",
"toolbar.background": "#1b181bff",
"tab_bar.background": "#252025ff",
"tab.inactive_background": "#252025ff",
@@ -3494,6 +3503,7 @@
"icon.accent": "#5169ebff",
"status_bar.background": "#c6b8c6ff",
"title_bar.background": "#c6b8c6ff",
"title_bar.inactive_background": "#e0d5e0ff",
"toolbar.background": "#f7f3f7ff",
"tab_bar.background": "#e0d5e0ff",
"tab.inactive_background": "#e0d5e0ff",
@@ -3878,6 +3888,7 @@
"icon.accent": "#267eadff",
"status_bar.background": "#33444dff",
"title_bar.background": "#33444dff",
"title_bar.inactive_background": "#1c2529ff",
"toolbar.background": "#161b1dff",
"tab_bar.background": "#1c2529ff",
"tab.inactive_background": "#1c2529ff",
@@ -4262,6 +4273,7 @@
"icon.accent": "#267eadff",
"status_bar.background": "#a6cadcff",
"title_bar.background": "#a6cadcff",
"title_bar.inactive_background": "#cdeaf9ff",
"toolbar.background": "#ebf8ffff",
"tab_bar.background": "#cdeaf9ff",
"tab.inactive_background": "#cdeaf9ff",
@@ -4646,6 +4658,7 @@
"icon.accent": "#7272caff",
"status_bar.background": "#3b3535ff",
"title_bar.background": "#3b3535ff",
"title_bar.inactive_background": "#252020ff",
"toolbar.background": "#1b1818ff",
"tab_bar.background": "#252020ff",
"tab.inactive_background": "#252020ff",
@@ -5030,6 +5043,7 @@
"icon.accent": "#7272caff",
"status_bar.background": "#c1bbbbff",
"title_bar.background": "#c1bbbbff",
"title_bar.inactive_background": "#ebe3e3ff",
"toolbar.background": "#f4ececff",
"tab_bar.background": "#ebe3e3ff",
"tab.inactive_background": "#ebe3e3ff",
@@ -5414,6 +5428,7 @@
"icon.accent": "#468b8fff",
"status_bar.background": "#353f39ff",
"title_bar.background": "#353f39ff",
"title_bar.inactive_background": "#1f2621ff",
"toolbar.background": "#171c19ff",
"tab_bar.background": "#1f2621ff",
"tab.inactive_background": "#1f2621ff",
@@ -5798,6 +5813,7 @@
"icon.accent": "#488b90ff",
"status_bar.background": "#bcc5bfff",
"title_bar.background": "#bcc5bfff",
"title_bar.inactive_background": "#e3ebe6ff",
"toolbar.background": "#ecf4eeff",
"tab_bar.background": "#e3ebe6ff",
"tab.inactive_background": "#e3ebe6ff",
@@ -6182,6 +6198,7 @@
"icon.accent": "#3e62f4ff",
"status_bar.background": "#3b453bff",
"title_bar.background": "#3b453bff",
"title_bar.inactive_background": "#1f231fff",
"toolbar.background": "#131513ff",
"tab_bar.background": "#1f231fff",
"tab.inactive_background": "#1f231fff",
@@ -6566,6 +6583,7 @@
"icon.accent": "#3e61f4ff",
"status_bar.background": "#b4ceb4ff",
"title_bar.background": "#b4ceb4ff",
"title_bar.inactive_background": "#daeedaff",
"toolbar.background": "#f3faf3ff",
"tab_bar.background": "#daeedaff",
"tab.inactive_background": "#daeedaff",
@@ -6950,6 +6968,7 @@
"icon.accent": "#3e8ed0ff",
"status_bar.background": "#3e4769ff",
"title_bar.background": "#3e4769ff",
"title_bar.inactive_background": "#262f51ff",
"toolbar.background": "#202646ff",
"tab_bar.background": "#262f51ff",
"tab.inactive_background": "#262f51ff",
@@ -7334,6 +7353,7 @@
"icon.accent": "#3e8fd0ff",
"status_bar.background": "#c1c5d8ff",
"title_bar.background": "#c1c5d8ff",
"title_bar.inactive_background": "#e5e8f5ff",
"toolbar.background": "#f5f7ffff",
"tab_bar.background": "#e5e8f5ff",
"tab.inactive_background": "#e5e8f5ff",

View File

@@ -38,6 +38,7 @@
"icon.accent": "#5ac1feff",
"status_bar.background": "#313337ff",
"title_bar.background": "#313337ff",
"title_bar.inactive_background": "#1f2127ff",
"toolbar.background": "#0d1016ff",
"tab_bar.background": "#1f2127ff",
"tab.inactive_background": "#1f2127ff",
@@ -407,6 +408,7 @@
"icon.accent": "#3b9ee5ff",
"status_bar.background": "#dcdddeff",
"title_bar.background": "#dcdddeff",
"title_bar.inactive_background": "#ececedff",
"toolbar.background": "#fcfcfcff",
"tab_bar.background": "#ececedff",
"tab.inactive_background": "#ececedff",
@@ -776,6 +778,7 @@
"icon.accent": "#72cffeff",
"status_bar.background": "#464a52ff",
"title_bar.background": "#464a52ff",
"title_bar.inactive_background": "#353944ff",
"toolbar.background": "#242835ff",
"tab_bar.background": "#353944ff",
"tab.inactive_background": "#353944ff",

View File

@@ -47,6 +47,7 @@
"icon.accent": "#83a598ff",
"status_bar.background": "#4c4642ff",
"title_bar.background": "#4c4642ff",
"title_bar.inactive_background": "#3a3735ff",
"toolbar.background": "#282828ff",
"tab_bar.background": "#3a3735ff",
"tab.inactive_background": "#3a3735ff",
@@ -430,6 +431,7 @@
"icon.accent": "#83a598ff",
"status_bar.background": "#4c4642ff",
"title_bar.background": "#4c4642ff",
"title_bar.inactive_background": "#393634ff",
"toolbar.background": "#1d2021ff",
"tab_bar.background": "#393634ff",
"tab.inactive_background": "#393634ff",
@@ -813,6 +815,7 @@
"icon.accent": "#83a598ff",
"status_bar.background": "#4c4642ff",
"title_bar.background": "#4c4642ff",
"title_bar.inactive_background": "#3b3735ff",
"toolbar.background": "#32302fff",
"tab_bar.background": "#3b3735ff",
"tab.inactive_background": "#3b3735ff",
@@ -1196,6 +1199,7 @@
"icon.accent": "#0b6678ff",
"status_bar.background": "#d9c8a4ff",
"title_bar.background": "#d9c8a4ff",
"title_bar.inactive_background": "#ecddb4ff",
"toolbar.background": "#fbf1c7ff",
"tab_bar.background": "#ecddb4ff",
"tab.inactive_background": "#ecddb4ff",
@@ -1579,6 +1583,7 @@
"icon.accent": "#0b6678ff",
"status_bar.background": "#d9c8a4ff",
"title_bar.background": "#d9c8a4ff",
"title_bar.inactive_background": "#ecddb5ff",
"toolbar.background": "#f9f5d7ff",
"tab_bar.background": "#ecddb5ff",
"tab.inactive_background": "#ecddb5ff",
@@ -1962,6 +1967,7 @@
"icon.accent": "#0b6678ff",
"status_bar.background": "#d9c8a4ff",
"title_bar.background": "#d9c8a4ff",
"title_bar.inactive_background": "#ecdcb3ff",
"toolbar.background": "#f2e5bcff",
"tab_bar.background": "#ecdcb3ff",
"tab.inactive_background": "#ecdcb3ff",

View File

@@ -38,6 +38,7 @@
"icon.accent": "#74ade8ff",
"status_bar.background": "#3b414dff",
"title_bar.background": "#3b414dff",
"title_bar.inactive_background": "#2e343eff",
"toolbar.background": "#282c33ff",
"tab_bar.background": "#2f343eff",
"tab.inactive_background": "#2f343eff",
@@ -412,6 +413,7 @@
"icon.accent": "#5c78e2ff",
"status_bar.background": "#dcdcddff",
"title_bar.background": "#dcdcddff",
"title_bar.inactive_background": "#ebebecff",
"toolbar.background": "#fafafaff",
"tab_bar.background": "#ebebecff",
"tab.inactive_background": "#ebebecff",

View File

@@ -38,6 +38,7 @@
"icon.accent": "#9bced6ff",
"status_bar.background": "#292738ff",
"title_bar.background": "#292738ff",
"title_bar.inactive_background": "#1c1b2aff",
"toolbar.background": "#191724ff",
"tab_bar.background": "#1c1b2aff",
"tab.inactive_background": "#1c1b2aff",
@@ -417,6 +418,7 @@
"icon.accent": "#57949fff",
"status_bar.background": "#dcd8d8ff",
"title_bar.background": "#dcd8d8ff",
"title_bar.inactive_background": "#fef9f2ff",
"toolbar.background": "#faf4edff",
"tab_bar.background": "#fef9f2ff",
"tab.inactive_background": "#fef9f2ff",
@@ -796,6 +798,7 @@
"icon.accent": "#9bced6ff",
"status_bar.background": "#38354eff",
"title_bar.background": "#38354eff",
"title_bar.inactive_background": "#28253cff",
"toolbar.background": "#232136ff",
"tab_bar.background": "#28253cff",
"tab.inactive_background": "#28253cff",

View File

@@ -38,6 +38,7 @@
"icon.accent": "#518b8bff",
"status_bar.background": "#333944ff",
"title_bar.background": "#333944ff",
"title_bar.inactive_background": "#2b3038ff",
"toolbar.background": "#282c33ff",
"tab_bar.background": "#2b3038ff",
"tab.inactive_background": "#2b3038ff",

View File

@@ -38,6 +38,7 @@
"icon.accent": "#278ad1ff",
"status_bar.background": "#073743ff",
"title_bar.background": "#073743ff",
"title_bar.inactive_background": "#04313bff",
"toolbar.background": "#002a35ff",
"tab_bar.background": "#04313bff",
"tab.inactive_background": "#04313bff",
@@ -407,6 +408,7 @@
"icon.accent": "#288bd1ff",
"status_bar.background": "#cfd0c4ff",
"title_bar.background": "#cfd0c4ff",
"title_bar.inactive_background": "#f3eddaff",
"toolbar.background": "#fdf6e3ff",
"tab_bar.background": "#f3eddaff",
"tab.inactive_background": "#f3eddaff",

View File

@@ -38,6 +38,7 @@
"icon.accent": "#499befff",
"status_bar.background": "#2a261cff",
"title_bar.background": "#2a261cff",
"title_bar.inactive_background": "#231f16ff",
"toolbar.background": "#1b1810ff",
"tab_bar.background": "#231f16ff",
"tab.inactive_background": "#231f16ff",

View File

@@ -107,6 +107,7 @@ impl ActivityIndicator {
Editor::for_buffer(buffer, Some(project.clone()), cx)
})),
None,
true,
cx,
);
})?;

View File

@@ -18,7 +18,7 @@ path = "src/anthropic.rs"
[dependencies]
anyhow.workspace = true
futures.workspace = true
http.workspace = true
http_client.workspace = true
isahc.workspace = true
schemars = { workspace = true, optional = true }
serde.workspace = true

View File

@@ -1,6 +1,6 @@
use anyhow::{anyhow, Result};
use futures::{io::BufReader, stream::BoxStream, AsyncBufReadExt, AsyncReadExt, StreamExt};
use http::{AsyncBody, HttpClient, Method, Request as HttpRequest};
use http_client::{AsyncBody, HttpClient, Method, Request as HttpRequest};
use isahc::config::Configurable;
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, time::Duration};
@@ -20,6 +20,8 @@ pub enum Model {
Claude3Sonnet,
#[serde(alias = "claude-3-haiku", rename = "claude-3-haiku-20240307")]
Claude3Haiku,
#[serde(rename = "custom")]
Custom { name: String, max_tokens: usize },
}
impl Model {
@@ -33,30 +35,38 @@ impl Model {
} else if id.starts_with("claude-3-haiku") {
Ok(Self::Claude3Haiku)
} else {
Err(anyhow!("Invalid model id: {}", id))
Err(anyhow!("invalid model id"))
}
}
pub fn id(&self) -> &'static str {
pub fn id(&self) -> &str {
match self {
Model::Claude3_5Sonnet => "claude-3-5-sonnet-20240620",
Model::Claude3Opus => "claude-3-opus-20240229",
Model::Claude3Sonnet => "claude-3-sonnet-20240229",
Model::Claude3Haiku => "claude-3-opus-20240307",
Self::Custom { name, .. } => name,
}
}
pub fn display_name(&self) -> &'static str {
pub fn display_name(&self) -> &str {
match self {
Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
Self::Claude3Opus => "Claude 3 Opus",
Self::Claude3Sonnet => "Claude 3 Sonnet",
Self::Claude3Haiku => "Claude 3 Haiku",
Self::Custom { name, .. } => name,
}
}
pub fn max_token_count(&self) -> usize {
200_000
match self {
Self::Claude3_5Sonnet
| Self::Claude3Opus
| Self::Claude3Sonnet
| Self::Claude3Haiku => 200_000,
Self::Custom { max_tokens, .. } => *max_tokens,
}
}
}
@@ -90,7 +100,7 @@ impl From<Role> for String {
#[derive(Debug, Serialize)]
pub struct Request {
pub model: Model,
pub model: String,
pub messages: Vec<RequestMessage>,
pub stream: bool,
pub system: String,

View File

@@ -23,15 +23,16 @@ test-support = [
[dependencies]
anthropic = { workspace = true, features = ["schemars"] }
anyhow.workspace = true
assets.workspace = true
assistant_slash_command.workspace = true
async-watch.workspace = true
breadcrumbs.workspace = true
cargo_toml.workspace = true
chrono.workspace = true
client.workspace = true
clock.workspace = true
collections.workspace = true
command_palette_hooks.workspace = true
completion.workspace = true
editor.workspace = true
feature_flags.workspace = true
fs.workspace = true
@@ -40,10 +41,11 @@ fuzzy.workspace = true
gpui.workspace = true
heed.workspace = true
html_to_markdown.workspace = true
http.workspace = true
http_client.workspace = true
indexed_docs.workspace = true
indoc.workspace = true
language.workspace = true
language_model.workspace = true
log.workspace = true
menu.workspace = true
multi_buffer.workspace = true
@@ -63,21 +65,20 @@ serde_json.workspace = true
settings.workspace = true
similar.workspace = true
smol.workspace = true
strsim = "0.11"
strum.workspace = true
telemetry_events.workspace = true
terminal.workspace = true
terminal_view.workspace = true
theme.workspace = true
tiktoken-rs.workspace = true
toml.workspace = true
ui.workspace = true
util.workspace = true
uuid.workspace = true
workspace.workspace = true
picker.workspace = true
roxmltree = "0.20.0"
[dev-dependencies]
completion = { workspace = true, features = ["test-support"] }
ctor.workspace = true
editor = { workspace = true, features = ["test-support"] }
env_logger.workspace = true

View File

@@ -38,7 +38,7 @@ Considering these aspects will ensure our conversation view design is optimized
@nate> 2 feels like it isn't important at the moment, we can explore that later. Let's start with 4, which I think will lead us to discussion 3 and 5.
#zed share your thoughts on the points we need to consider to design a layout and visualization for a conversation view between you (#zed) and multuple peoople, or between multiple people and multiple bots (you and other bots).
#zed share your thoughts on the points we need to consider to design a layout and visualization for a conversation view between you (#zed) and multiple people, or between multiple people and multiple bots (you and other bots).
@nathan> Agreed. I'm interested in threading I think more than anything. Or 4 yeah. I think we need to scope the threading conversation. Also, asking #zed to propose the solution... not sure it will be that effective but it's worth a try...

View File

@@ -1,42 +1,40 @@
pub mod assistant_panel;
pub mod assistant_settings;
mod completion_provider;
mod context;
pub mod context_store;
mod inline_assistant;
mod model_selector;
mod prompt_library;
mod prompts;
mod search;
mod slash_command;
mod streaming_diff;
mod terminal_inline_assistant;
pub use assistant_panel::{AssistantPanel, AssistantPanelEvent};
use assistant_settings::{AnthropicModel, AssistantSettings, CloudModel, OllamaModel, OpenAiModel};
use assistant_settings::AssistantSettings;
use assistant_slash_command::SlashCommandRegistry;
use client::{proto, Client};
use command_palette_hooks::CommandPaletteFilter;
pub use completion_provider::*;
use completion::LanguageModelCompletionProvider;
pub use context::*;
pub use context_store::*;
use fs::Fs;
use gpui::{actions, AppContext, Global, SharedString, UpdateGlobal};
use gpui::{actions, impl_actions, AppContext, Global, SharedString, UpdateGlobal};
use indexed_docs::IndexedDocsRegistry;
pub(crate) use inline_assistant::*;
use language_model::{
LanguageModelId, LanguageModelProviderId, LanguageModelRegistry, LanguageModelResponseMessage,
};
pub(crate) use model_selector::*;
use semantic_index::{CloudEmbeddingProvider, SemanticIndex};
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore};
use settings::{update_settings_file, Settings, SettingsStore};
use slash_command::{
active_command, default_command, diagnostics_command, docs_command, fetch_command,
file_command, now_command, project_command, prompt_command, search_command, tabs_command,
term_command,
};
use std::{
fmt::{self, Display},
sync::Arc,
file_command, now_command, project_command, prompt_command, search_command, symbols_command,
tabs_command, term_command,
};
use std::sync::Arc;
pub(crate) use streaming_diff::*;
actions!(
@@ -49,16 +47,22 @@ actions!(
InsertIntoEditor,
ToggleFocus,
ResetKey,
InlineAssist,
InsertActivePrompt,
DeployHistory,
DeployPromptLibrary,
ApplyEdit,
ConfirmCommand,
ToggleModelSelector
ToggleModelSelector,
DebugEditSteps
]
);
#[derive(Clone, Default, Deserialize, PartialEq)]
pub struct InlineAssist {
prompt: Option<String>,
}
impl_actions!(assistant, [InlineAssist]);
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct MessageId(clock::Lamport);
@@ -68,166 +72,6 @@ impl MessageId {
}
}
#[derive(Clone, Copy, Serialize, Deserialize, Debug, Eq, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum Role {
User,
Assistant,
System,
}
impl Role {
pub fn from_proto(role: i32) -> Role {
match proto::LanguageModelRole::from_i32(role) {
Some(proto::LanguageModelRole::LanguageModelUser) => Role::User,
Some(proto::LanguageModelRole::LanguageModelAssistant) => Role::Assistant,
Some(proto::LanguageModelRole::LanguageModelSystem) => Role::System,
Some(proto::LanguageModelRole::LanguageModelTool) => Role::System,
None => Role::User,
}
}
pub fn to_proto(&self) -> proto::LanguageModelRole {
match self {
Role::User => proto::LanguageModelRole::LanguageModelUser,
Role::Assistant => proto::LanguageModelRole::LanguageModelAssistant,
Role::System => proto::LanguageModelRole::LanguageModelSystem,
}
}
pub fn cycle(self) -> Role {
match self {
Role::User => Role::Assistant,
Role::Assistant => Role::System,
Role::System => Role::User,
}
}
}
impl Display for Role {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Role::User => write!(f, "user"),
Role::Assistant => write!(f, "assistant"),
Role::System => write!(f, "system"),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum LanguageModel {
Cloud(CloudModel),
OpenAi(OpenAiModel),
Anthropic(AnthropicModel),
Ollama(OllamaModel),
}
impl Default for LanguageModel {
fn default() -> Self {
LanguageModel::Cloud(CloudModel::default())
}
}
impl LanguageModel {
pub fn telemetry_id(&self) -> String {
match self {
LanguageModel::OpenAi(model) => format!("openai/{}", model.id()),
LanguageModel::Anthropic(model) => format!("anthropic/{}", model.id()),
LanguageModel::Cloud(model) => format!("zed.dev/{}", model.id()),
LanguageModel::Ollama(model) => format!("ollama/{}", model.id()),
}
}
pub fn display_name(&self) -> String {
match self {
LanguageModel::OpenAi(model) => model.display_name().into(),
LanguageModel::Anthropic(model) => model.display_name().into(),
LanguageModel::Cloud(model) => model.display_name().into(),
LanguageModel::Ollama(model) => model.display_name().into(),
}
}
pub fn max_token_count(&self) -> usize {
match self {
LanguageModel::OpenAi(model) => model.max_token_count(),
LanguageModel::Anthropic(model) => model.max_token_count(),
LanguageModel::Cloud(model) => model.max_token_count(),
LanguageModel::Ollama(model) => model.max_token_count(),
}
}
pub fn id(&self) -> &str {
match self {
LanguageModel::OpenAi(model) => model.id(),
LanguageModel::Anthropic(model) => model.id(),
LanguageModel::Cloud(model) => model.id(),
LanguageModel::Ollama(model) => model.id(),
}
}
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct LanguageModelRequestMessage {
pub role: Role,
pub content: String,
}
impl LanguageModelRequestMessage {
pub fn to_proto(&self) -> proto::LanguageModelRequestMessage {
proto::LanguageModelRequestMessage {
role: self.role.to_proto() as i32,
content: self.content.clone(),
tool_calls: Vec::new(),
tool_call_id: None,
}
}
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct LanguageModelRequest {
pub model: LanguageModel,
pub messages: Vec<LanguageModelRequestMessage>,
pub stop: Vec<String>,
pub temperature: f32,
}
impl LanguageModelRequest {
pub fn to_proto(&self) -> proto::CompleteWithLanguageModel {
proto::CompleteWithLanguageModel {
model: self.model.id().to_string(),
messages: self.messages.iter().map(|m| m.to_proto()).collect(),
stop: self.stop.clone(),
temperature: self.temperature,
tool_choice: None,
tools: Vec::new(),
}
}
/// Before we send the request to the server, we can perform fixups on it appropriate to the model.
pub fn preprocess(&mut self) {
match &self.model {
LanguageModel::OpenAi(_) => {}
LanguageModel::Anthropic(_) => {}
LanguageModel::Ollama(_) => {}
LanguageModel::Cloud(model) => match model {
CloudModel::Claude3Opus
| CloudModel::Claude3Sonnet
| CloudModel::Claude3Haiku
| CloudModel::Claude3_5Sonnet => {
preprocess_anthropic_request(self);
}
_ => {}
},
}
}
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct LanguageModelResponseMessage {
pub role: Option<Role>,
pub content: Option<String>,
}
#[derive(Deserialize, Debug)]
pub struct LanguageModelUsage {
pub prompt_tokens: u32,
@@ -321,6 +165,16 @@ pub fn init(fs: Arc<dyn Fs>, client: Arc<Client>, cx: &mut AppContext) {
cx.set_global(Assistant::default());
AssistantSettings::register(cx);
// TODO: remove this when 0.148.0 is released.
if AssistantSettings::get_global(cx).using_outdated_settings_version {
update_settings_file::<AssistantSettings>(fs.clone(), cx, {
let fs = fs.clone();
|content, cx| {
content.update_file(fs, cx);
}
});
}
cx.spawn(|mut cx| {
let client = client.clone();
async move {
@@ -338,7 +192,7 @@ pub fn init(fs: Arc<dyn Fs>, client: Arc<Client>, cx: &mut AppContext) {
context_store::init(&client);
prompt_library::init(cx);
completion_provider::init(client.clone(), cx);
init_completion_provider(cx);
assistant_slash_command::init(cx);
register_slash_commands(cx);
assistant_panel::init(cx);
@@ -363,10 +217,43 @@ pub fn init(fs: Arc<dyn Fs>, client: Arc<Client>, cx: &mut AppContext) {
.detach();
}
fn init_completion_provider(cx: &mut AppContext) {
completion::init(cx);
update_active_language_model_from_settings(cx);
cx.observe_global::<SettingsStore>(update_active_language_model_from_settings)
.detach();
cx.observe(&LanguageModelRegistry::global(cx), |_, cx| {
update_active_language_model_from_settings(cx)
})
.detach();
}
fn update_active_language_model_from_settings(cx: &mut AppContext) {
let settings = AssistantSettings::get_global(cx);
let provider_name = LanguageModelProviderId::from(settings.default_model.provider.clone());
let model_id = LanguageModelId::from(settings.default_model.model.clone());
let Some(provider) = LanguageModelRegistry::global(cx)
.read(cx)
.provider(&provider_name)
else {
return;
};
let models = provider.provided_models(cx);
if let Some(model) = models.iter().find(|model| model.id() == model_id).cloned() {
LanguageModelCompletionProvider::global(cx).update(cx, |completion_provider, cx| {
completion_provider.set_active_model(model, cx);
});
}
}
fn register_slash_commands(cx: &mut AppContext) {
let slash_command_registry = SlashCommandRegistry::global(cx);
slash_command_registry.register_command(file_command::FileSlashCommand, true);
slash_command_registry.register_command(active_command::ActiveSlashCommand, true);
slash_command_registry.register_command(symbols_command::OutlineSlashCommand, true);
slash_command_registry.register_command(tabs_command::TabsSlashCommand, true);
slash_command_registry.register_command(project_command::ProjectSlashCommand, true);
slash_command_registry.register_command(search_command::SearchSlashCommand, true);

File diff suppressed because it is too large Load Diff

View File

@@ -1,154 +1,14 @@
use std::fmt;
use std::sync::Arc;
use crate::{preprocess_anthropic_request, LanguageModel, LanguageModelRequest};
pub use anthropic::Model as AnthropicModel;
use gpui::Pixels;
pub use ollama::Model as OllamaModel;
pub use open_ai::Model as OpenAiModel;
use schemars::{
schema::{InstanceType, Metadata, Schema, SchemaObject},
JsonSchema,
};
use serde::{
de::{self, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use settings::{Settings, SettingsSources};
use strum::{EnumIter, IntoEnumIterator};
#[derive(Clone, Debug, Default, PartialEq, EnumIter)]
pub enum CloudModel {
Gpt3Point5Turbo,
Gpt4,
Gpt4Turbo,
#[default]
Gpt4Omni,
Claude3_5Sonnet,
Claude3Opus,
Claude3Sonnet,
Claude3Haiku,
Custom(String),
}
impl Serialize for CloudModel {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.id())
}
}
impl<'de> Deserialize<'de> for CloudModel {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ZedDotDevModelVisitor;
impl<'de> Visitor<'de> for ZedDotDevModelVisitor {
type Value = CloudModel;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string for a ZedDotDevModel variant or a custom model")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
let model = CloudModel::iter()
.find(|model| model.id() == value)
.unwrap_or_else(|| CloudModel::Custom(value.to_string()));
Ok(model)
}
}
deserializer.deserialize_str(ZedDotDevModelVisitor)
}
}
impl JsonSchema for CloudModel {
fn schema_name() -> String {
"ZedDotDevModel".to_owned()
}
fn json_schema(_generator: &mut schemars::gen::SchemaGenerator) -> Schema {
let variants = CloudModel::iter()
.filter_map(|model| {
let id = model.id();
if id.is_empty() {
None
} else {
Some(id.to_string())
}
})
.collect::<Vec<_>>();
Schema::Object(SchemaObject {
instance_type: Some(InstanceType::String.into()),
enum_values: Some(variants.iter().map(|s| s.clone().into()).collect()),
metadata: Some(Box::new(Metadata {
title: Some("ZedDotDevModel".to_owned()),
default: Some(CloudModel::default().id().into()),
examples: variants.into_iter().map(Into::into).collect(),
..Default::default()
})),
..Default::default()
})
}
}
impl CloudModel {
pub fn id(&self) -> &str {
match self {
Self::Gpt3Point5Turbo => "gpt-3.5-turbo",
Self::Gpt4 => "gpt-4",
Self::Gpt4Turbo => "gpt-4-turbo-preview",
Self::Gpt4Omni => "gpt-4o",
Self::Claude3_5Sonnet => "claude-3-5-sonnet",
Self::Claude3Opus => "claude-3-opus",
Self::Claude3Sonnet => "claude-3-sonnet",
Self::Claude3Haiku => "claude-3-haiku",
Self::Custom(id) => id,
}
}
pub fn display_name(&self) -> &str {
match self {
Self::Gpt3Point5Turbo => "GPT 3.5 Turbo",
Self::Gpt4 => "GPT 4",
Self::Gpt4Turbo => "GPT 4 Turbo",
Self::Gpt4Omni => "GPT 4 Omni",
Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
Self::Claude3Opus => "Claude 3 Opus",
Self::Claude3Sonnet => "Claude 3 Sonnet",
Self::Claude3Haiku => "Claude 3 Haiku",
Self::Custom(id) => id.as_str(),
}
}
pub fn max_token_count(&self) -> usize {
match self {
Self::Gpt3Point5Turbo => 2048,
Self::Gpt4 => 4096,
Self::Gpt4Turbo | Self::Gpt4Omni => 128000,
Self::Claude3_5Sonnet
| Self::Claude3Opus
| Self::Claude3Sonnet
| Self::Claude3Haiku => 200000,
Self::Custom(_) => 4096, // TODO: Make this configurable
}
}
pub fn preprocess_request(&self, request: &mut LanguageModelRequest) {
match self {
Self::Claude3Opus | Self::Claude3Sonnet | Self::Claude3Haiku => {
preprocess_anthropic_request(request)
}
_ => {}
}
}
}
use anthropic::Model as AnthropicModel;
use fs::Fs;
use gpui::{AppContext, Pixels};
use language_model::{settings::AllLanguageModelSettings, CloudModel, LanguageModel};
use ollama::Model as OllamaModel;
use open_ai::Model as OpenAiModel;
use schemars::{schema::Schema, JsonSchema};
use serde::{Deserialize, Serialize};
use settings::{update_settings_file, Settings, SettingsSources};
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
@@ -159,43 +19,9 @@ pub enum AssistantDockPosition {
Bottom,
}
#[derive(Debug, PartialEq)]
pub enum AssistantProvider {
ZedDotDev {
model: CloudModel,
},
OpenAi {
model: OpenAiModel,
api_url: String,
low_speed_timeout_in_seconds: Option<u64>,
available_models: Vec<OpenAiModel>,
},
Anthropic {
model: AnthropicModel,
api_url: String,
low_speed_timeout_in_seconds: Option<u64>,
},
Ollama {
model: OllamaModel,
api_url: String,
low_speed_timeout_in_seconds: Option<u64>,
},
}
impl Default for AssistantProvider {
fn default() -> Self {
Self::OpenAi {
model: OpenAiModel::default(),
api_url: open_ai::OPEN_AI_API_URL.into(),
low_speed_timeout_in_seconds: None,
available_models: Default::default(),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(tag = "name", rename_all = "snake_case")]
pub enum AssistantProviderContent {
pub enum AssistantProviderContentV1 {
#[serde(rename = "zed.dev")]
ZedDotDev { default_model: Option<CloudModel> },
#[serde(rename = "openai")]
@@ -226,7 +52,8 @@ pub struct AssistantSettings {
pub dock: AssistantDockPosition,
pub default_width: Pixels,
pub default_height: Pixels,
pub provider: AssistantProvider,
pub default_model: AssistantDefaultModel,
pub using_outdated_settings_version: bool,
}
/// Assistant panel settings
@@ -258,34 +85,142 @@ impl Default for AssistantSettingsContent {
}
impl AssistantSettingsContent {
fn upgrade(&self) -> AssistantSettingsContentV1 {
pub fn is_version_outdated(&self) -> bool {
match self {
AssistantSettingsContent::Versioned(settings) => match settings {
VersionedAssistantSettingsContent::V1(settings) => settings.clone(),
VersionedAssistantSettingsContent::V1(_) => true,
VersionedAssistantSettingsContent::V2(_) => false,
},
AssistantSettingsContent::Legacy(settings) => AssistantSettingsContentV1 {
AssistantSettingsContent::Legacy(_) => true,
}
}
pub fn update_file(&mut self, fs: Arc<dyn Fs>, cx: &AppContext) {
if let AssistantSettingsContent::Versioned(settings) = self {
if let VersionedAssistantSettingsContent::V1(settings) = settings {
if let Some(provider) = settings.provider.clone() {
match provider {
AssistantProviderContentV1::Anthropic {
api_url,
low_speed_timeout_in_seconds,
..
} => update_settings_file::<AllLanguageModelSettings>(
fs,
cx,
move |content, _| {
if content.anthropic.is_none() {
content.anthropic =
Some(language_model::settings::AnthropicSettingsContent {
api_url,
low_speed_timeout_in_seconds,
..Default::default()
});
}
},
),
AssistantProviderContentV1::Ollama {
api_url,
low_speed_timeout_in_seconds,
..
} => update_settings_file::<AllLanguageModelSettings>(
fs,
cx,
move |content, _| {
if content.ollama.is_none() {
content.ollama =
Some(language_model::settings::OllamaSettingsContent {
api_url,
low_speed_timeout_in_seconds,
});
}
},
),
AssistantProviderContentV1::OpenAi {
api_url,
low_speed_timeout_in_seconds,
available_models,
..
} => update_settings_file::<AllLanguageModelSettings>(
fs,
cx,
move |content, _| {
if content.openai.is_none() {
content.openai =
Some(language_model::settings::OpenAiSettingsContent {
api_url,
low_speed_timeout_in_seconds,
available_models,
});
}
},
),
_ => {}
}
}
}
}
*self = AssistantSettingsContent::Versioned(VersionedAssistantSettingsContent::V2(
self.upgrade(),
));
}
fn upgrade(&self) -> AssistantSettingsContentV2 {
match self {
AssistantSettingsContent::Versioned(settings) => match settings {
VersionedAssistantSettingsContent::V1(settings) => AssistantSettingsContentV2 {
enabled: settings.enabled,
button: settings.button,
dock: settings.dock,
default_width: settings.default_width,
default_height: settings.default_width,
default_model: settings
.provider
.clone()
.and_then(|provider| match provider {
AssistantProviderContentV1::ZedDotDev { default_model } => {
default_model.map(|model| AssistantDefaultModel {
provider: "zed.dev".to_string(),
model: model.id().to_string(),
})
}
AssistantProviderContentV1::OpenAi { default_model, .. } => {
default_model.map(|model| AssistantDefaultModel {
provider: "openai".to_string(),
model: model.id().to_string(),
})
}
AssistantProviderContentV1::Anthropic { default_model, .. } => {
default_model.map(|model| AssistantDefaultModel {
provider: "anthropic".to_string(),
model: model.id().to_string(),
})
}
AssistantProviderContentV1::Ollama { default_model, .. } => {
default_model.map(|model| AssistantDefaultModel {
provider: "ollama".to_string(),
model: model.id().to_string(),
})
}
}),
},
VersionedAssistantSettingsContent::V2(settings) => settings.clone(),
},
AssistantSettingsContent::Legacy(settings) => AssistantSettingsContentV2 {
enabled: None,
button: settings.button,
dock: settings.dock,
default_width: settings.default_width,
default_height: settings.default_height,
provider: if let Some(open_ai_api_url) = settings.openai_api_url.as_ref() {
Some(AssistantProviderContent::OpenAi {
default_model: settings.default_open_ai_model.clone(),
api_url: Some(open_ai_api_url.clone()),
low_speed_timeout_in_seconds: None,
available_models: Some(Default::default()),
})
} else {
settings.default_open_ai_model.clone().map(|open_ai_model| {
AssistantProviderContent::OpenAi {
default_model: Some(open_ai_model),
api_url: None,
low_speed_timeout_in_seconds: None,
available_models: Some(Default::default()),
}
})
},
default_model: Some(AssistantDefaultModel {
provider: "openai".to_string(),
model: settings
.default_open_ai_model
.clone()
.unwrap_or_default()
.id()
.to_string(),
}),
},
}
}
@@ -296,6 +231,9 @@ impl AssistantSettingsContent {
VersionedAssistantSettingsContent::V1(settings) => {
settings.dock = Some(dock);
}
VersionedAssistantSettingsContent::V2(settings) => {
settings.dock = Some(dock);
}
},
AssistantSettingsContent::Legacy(settings) => {
settings.dock = Some(dock);
@@ -303,74 +241,78 @@ impl AssistantSettingsContent {
}
}
pub fn set_model(&mut self, new_model: LanguageModel) {
pub fn set_model(&mut self, language_model: Arc<dyn LanguageModel>) {
let model = language_model.id().0.to_string();
let provider = language_model.provider_id().0.to_string();
match self {
AssistantSettingsContent::Versioned(settings) => match settings {
VersionedAssistantSettingsContent::V1(settings) => match &mut settings.provider {
Some(AssistantProviderContent::ZedDotDev {
default_model: model,
}) => {
if let LanguageModel::Cloud(new_model) = new_model {
*model = Some(new_model);
}
VersionedAssistantSettingsContent::V1(settings) => match provider.as_ref() {
"zed.dev" => {
settings.provider = Some(AssistantProviderContentV1::ZedDotDev {
default_model: CloudModel::from_id(&model).ok(),
});
}
Some(AssistantProviderContent::OpenAi {
default_model: model,
..
}) => {
if let LanguageModel::OpenAi(new_model) = new_model {
*model = Some(new_model);
}
"anthropic" => {
let (api_url, low_speed_timeout_in_seconds) = match &settings.provider {
Some(AssistantProviderContentV1::Anthropic {
api_url,
low_speed_timeout_in_seconds,
..
}) => (api_url.clone(), *low_speed_timeout_in_seconds),
_ => (None, None),
};
settings.provider = Some(AssistantProviderContentV1::Anthropic {
default_model: AnthropicModel::from_id(&model).ok(),
api_url,
low_speed_timeout_in_seconds,
});
}
Some(AssistantProviderContent::Anthropic {
default_model: model,
..
}) => {
if let LanguageModel::Anthropic(new_model) = new_model {
*model = Some(new_model);
}
"ollama" => {
let (api_url, low_speed_timeout_in_seconds) = match &settings.provider {
Some(AssistantProviderContentV1::Ollama {
api_url,
low_speed_timeout_in_seconds,
..
}) => (api_url.clone(), *low_speed_timeout_in_seconds),
_ => (None, None),
};
settings.provider = Some(AssistantProviderContentV1::Ollama {
default_model: Some(ollama::Model::new(&model)),
api_url,
low_speed_timeout_in_seconds,
});
}
Some(AssistantProviderContent::Ollama {
default_model: model,
..
}) => {
if let LanguageModel::Ollama(new_model) = new_model {
*model = Some(new_model);
}
"openai" => {
let (api_url, low_speed_timeout_in_seconds, available_models) =
match &settings.provider {
Some(AssistantProviderContentV1::OpenAi {
api_url,
low_speed_timeout_in_seconds,
available_models,
..
}) => (
api_url.clone(),
*low_speed_timeout_in_seconds,
available_models.clone(),
),
_ => (None, None, None),
};
settings.provider = Some(AssistantProviderContentV1::OpenAi {
default_model: open_ai::Model::from_id(&model).ok(),
api_url,
low_speed_timeout_in_seconds,
available_models,
});
}
provider => match new_model {
LanguageModel::Cloud(model) => {
*provider = Some(AssistantProviderContent::ZedDotDev {
default_model: Some(model),
})
}
LanguageModel::OpenAi(model) => {
*provider = Some(AssistantProviderContent::OpenAi {
default_model: Some(model),
api_url: None,
low_speed_timeout_in_seconds: None,
available_models: Some(Default::default()),
})
}
LanguageModel::Anthropic(model) => {
*provider = Some(AssistantProviderContent::Anthropic {
default_model: Some(model),
api_url: None,
low_speed_timeout_in_seconds: None,
})
}
LanguageModel::Ollama(model) => {
*provider = Some(AssistantProviderContent::Ollama {
default_model: Some(model),
api_url: None,
low_speed_timeout_in_seconds: None,
})
}
},
_ => {}
},
VersionedAssistantSettingsContent::V2(settings) => {
settings.default_model = Some(AssistantDefaultModel { provider, model });
}
},
AssistantSettingsContent::Legacy(settings) => {
if let LanguageModel::OpenAi(model) = new_model {
if let Ok(model) = open_ai::Model::from_id(&language_model.id().0) {
settings.default_open_ai_model = Some(model);
}
}
@@ -383,21 +325,78 @@ impl AssistantSettingsContent {
pub enum VersionedAssistantSettingsContent {
#[serde(rename = "1")]
V1(AssistantSettingsContentV1),
#[serde(rename = "2")]
V2(AssistantSettingsContentV2),
}
impl Default for VersionedAssistantSettingsContent {
fn default() -> Self {
Self::V1(AssistantSettingsContentV1 {
Self::V2(AssistantSettingsContentV2 {
enabled: None,
button: None,
dock: None,
default_width: None,
default_height: None,
provider: None,
default_model: None,
})
}
}
#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
pub struct AssistantSettingsContentV2 {
/// Whether the Assistant is enabled.
///
/// Default: true
enabled: Option<bool>,
/// Whether to show the assistant panel button in the status bar.
///
/// Default: true
button: Option<bool>,
/// Where to dock the assistant.
///
/// Default: right
dock: Option<AssistantDockPosition>,
/// Default width in pixels when the assistant is docked to the left or right.
///
/// Default: 640
default_width: Option<f32>,
/// Default height in pixels when the assistant is docked to the bottom.
///
/// Default: 320
default_height: Option<f32>,
/// The default model to use when creating new contexts.
default_model: Option<AssistantDefaultModel>,
}
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub struct AssistantDefaultModel {
#[schemars(schema_with = "providers_schema")]
pub provider: String,
pub model: String,
}
fn providers_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
schemars::schema::SchemaObject {
enum_values: Some(vec![
"anthropic".into(),
"ollama".into(),
"openai".into(),
"zed.dev".into(),
]),
..Default::default()
}
.into()
}
impl Default for AssistantDefaultModel {
fn default() -> Self {
Self {
provider: "openai".to_string(),
model: "gpt-4".to_string(),
}
}
}
#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
pub struct AssistantSettingsContentV1 {
/// Whether the Assistant is enabled.
@@ -424,7 +423,7 @@ pub struct AssistantSettingsContentV1 {
///
/// This can either be the internal `zed.dev` service or an external `openai` service,
/// each with their respective default models and configurations.
provider: Option<AssistantProviderContent>,
provider: Option<AssistantProviderContentV1>,
}
#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
@@ -467,6 +466,10 @@ impl Settings for AssistantSettings {
let mut settings = AssistantSettings::default();
for value in sources.defaults_and_customizations() {
if value.is_version_outdated() {
settings.using_outdated_settings_version = true;
}
let value = value.upgrade();
merge(&mut settings.enabled, value.enabled);
merge(&mut settings.button, value.button);
@@ -479,123 +482,10 @@ impl Settings for AssistantSettings {
&mut settings.default_height,
value.default_height.map(Into::into),
);
if let Some(provider) = value.provider.clone() {
match (&mut settings.provider, provider) {
(
AssistantProvider::ZedDotDev { model },
AssistantProviderContent::ZedDotDev {
default_model: model_override,
},
) => {
merge(model, model_override);
}
(
AssistantProvider::OpenAi {
model,
api_url,
low_speed_timeout_in_seconds,
available_models,
},
AssistantProviderContent::OpenAi {
default_model: model_override,
api_url: api_url_override,
low_speed_timeout_in_seconds: low_speed_timeout_in_seconds_override,
available_models: available_models_override,
},
) => {
merge(model, model_override);
merge(api_url, api_url_override);
merge(available_models, available_models_override);
if let Some(low_speed_timeout_in_seconds_override) =
low_speed_timeout_in_seconds_override
{
*low_speed_timeout_in_seconds =
Some(low_speed_timeout_in_seconds_override);
}
}
(
AssistantProvider::Ollama {
model,
api_url,
low_speed_timeout_in_seconds,
},
AssistantProviderContent::Ollama {
default_model: model_override,
api_url: api_url_override,
low_speed_timeout_in_seconds: low_speed_timeout_in_seconds_override,
},
) => {
merge(model, model_override);
merge(api_url, api_url_override);
if let Some(low_speed_timeout_in_seconds_override) =
low_speed_timeout_in_seconds_override
{
*low_speed_timeout_in_seconds =
Some(low_speed_timeout_in_seconds_override);
}
}
(
AssistantProvider::Anthropic {
model,
api_url,
low_speed_timeout_in_seconds,
},
AssistantProviderContent::Anthropic {
default_model: model_override,
api_url: api_url_override,
low_speed_timeout_in_seconds: low_speed_timeout_in_seconds_override,
},
) => {
merge(model, model_override);
merge(api_url, api_url_override);
if let Some(low_speed_timeout_in_seconds_override) =
low_speed_timeout_in_seconds_override
{
*low_speed_timeout_in_seconds =
Some(low_speed_timeout_in_seconds_override);
}
}
(provider, provider_override) => {
*provider = match provider_override {
AssistantProviderContent::ZedDotDev {
default_model: model,
} => AssistantProvider::ZedDotDev {
model: model.unwrap_or_default(),
},
AssistantProviderContent::OpenAi {
default_model: model,
api_url,
low_speed_timeout_in_seconds,
available_models,
} => AssistantProvider::OpenAi {
model: model.unwrap_or_default(),
api_url: api_url.unwrap_or_else(|| open_ai::OPEN_AI_API_URL.into()),
low_speed_timeout_in_seconds,
available_models: available_models.unwrap_or_default(),
},
AssistantProviderContent::Anthropic {
default_model: model,
api_url,
low_speed_timeout_in_seconds,
} => AssistantProvider::Anthropic {
model: model.unwrap_or_default(),
api_url: api_url
.unwrap_or_else(|| anthropic::ANTHROPIC_API_URL.into()),
low_speed_timeout_in_seconds,
},
AssistantProviderContent::Ollama {
default_model: model,
api_url,
low_speed_timeout_in_seconds,
} => AssistantProvider::Ollama {
model: model.unwrap_or_default(),
api_url: api_url.unwrap_or_else(|| ollama::OLLAMA_API_URL.into()),
low_speed_timeout_in_seconds,
},
};
}
}
}
merge(
&mut settings.default_model,
value.default_model.map(Into::into),
);
}
Ok(settings)
@@ -608,96 +498,103 @@ fn merge<T>(target: &mut T, value: Option<T>) {
}
}
#[cfg(test)]
mod tests {
use gpui::{AppContext, UpdateGlobal};
use settings::SettingsStore;
// #[cfg(test)]
// mod tests {
// use gpui::{AppContext, UpdateGlobal};
// use settings::SettingsStore;
use super::*;
// use super::*;
#[gpui::test]
fn test_deserialize_assistant_settings(cx: &mut AppContext) {
let store = settings::SettingsStore::test(cx);
cx.set_global(store);
// #[gpui::test]
// fn test_deserialize_assistant_settings(cx: &mut AppContext) {
// let store = settings::SettingsStore::test(cx);
// cx.set_global(store);
// Settings default to gpt-4-turbo.
AssistantSettings::register(cx);
assert_eq!(
AssistantSettings::get_global(cx).provider,
AssistantProvider::OpenAi {
model: OpenAiModel::FourOmni,
api_url: open_ai::OPEN_AI_API_URL.into(),
low_speed_timeout_in_seconds: None,
available_models: Default::default(),
}
);
// // Settings default to gpt-4-turbo.
// AssistantSettings::register(cx);
// assert_eq!(
// AssistantSettings::get_global(cx).provider,
// AssistantProvider::OpenAi {
// model: OpenAiModel::FourOmni,
// api_url: open_ai::OPEN_AI_API_URL.into(),
// low_speed_timeout_in_seconds: None,
// available_models: Default::default(),
// }
// );
// Ensure backward-compatibility.
SettingsStore::update_global(cx, |store, cx| {
store
.set_user_settings(
r#"{
"assistant": {
"openai_api_url": "test-url",
}
}"#,
cx,
)
.unwrap();
});
assert_eq!(
AssistantSettings::get_global(cx).provider,
AssistantProvider::OpenAi {
model: OpenAiModel::FourOmni,
api_url: "test-url".into(),
low_speed_timeout_in_seconds: None,
available_models: Default::default(),
}
);
SettingsStore::update_global(cx, |store, cx| {
store
.set_user_settings(
r#"{
"assistant": {
"default_open_ai_model": "gpt-4-0613"
}
}"#,
cx,
)
.unwrap();
});
assert_eq!(
AssistantSettings::get_global(cx).provider,
AssistantProvider::OpenAi {
model: OpenAiModel::Four,
api_url: open_ai::OPEN_AI_API_URL.into(),
low_speed_timeout_in_seconds: None,
available_models: Default::default(),
}
);
// // Ensure backward-compatibility.
// SettingsStore::update_global(cx, |store, cx| {
// store
// .set_user_settings(
// r#"{
// "assistant": {
// "openai_api_url": "test-url",
// }
// }"#,
// cx,
// )
// .unwrap();
// });
// assert_eq!(
// AssistantSettings::get_global(cx).provider,
// AssistantProvider::OpenAi {
// model: OpenAiModel::FourOmni,
// api_url: "test-url".into(),
// low_speed_timeout_in_seconds: None,
// available_models: Default::default(),
// }
// );
// SettingsStore::update_global(cx, |store, cx| {
// store
// .set_user_settings(
// r#"{
// "assistant": {
// "default_open_ai_model": "gpt-4-0613"
// }
// }"#,
// cx,
// )
// .unwrap();
// });
// assert_eq!(
// AssistantSettings::get_global(cx).provider,
// AssistantProvider::OpenAi {
// model: OpenAiModel::Four,
// api_url: open_ai::OPEN_AI_API_URL.into(),
// low_speed_timeout_in_seconds: None,
// available_models: Default::default(),
// }
// );
// The new version supports setting a custom model when using zed.dev.
SettingsStore::update_global(cx, |store, cx| {
store
.set_user_settings(
r#"{
"assistant": {
"version": "1",
"provider": {
"name": "zed.dev",
"default_model": "custom"
}
}
}"#,
cx,
)
.unwrap();
});
assert_eq!(
AssistantSettings::get_global(cx).provider,
AssistantProvider::ZedDotDev {
model: CloudModel::Custom("custom".into())
}
);
}
}
// // The new version supports setting a custom model when using zed.dev.
// SettingsStore::update_global(cx, |store, cx| {
// store
// .set_user_settings(
// r#"{
// "assistant": {
// "version": "1",
// "provider": {
// "name": "zed.dev",
// "default_model": {
// "custom": {
// "name": "custom-provider"
// }
// }
// }
// }
// }"#,
// cx,
// )
// .unwrap();
// });
// assert_eq!(
// AssistantSettings::get_global(cx).provider,
// AssistantProvider::ZedDotDev {
// model: CloudModel::Custom {
// name: "custom-provider".into(),
// max_tokens: None
// }
// }
// );
// }
// }

View File

@@ -1,373 +0,0 @@
mod anthropic;
mod cloud;
#[cfg(any(test, feature = "test-support"))]
mod fake;
mod ollama;
mod open_ai;
pub use anthropic::*;
pub use cloud::*;
#[cfg(any(test, feature = "test-support"))]
pub use fake::*;
pub use ollama::*;
pub use open_ai::*;
use parking_lot::RwLock;
use smol::lock::{Semaphore, SemaphoreGuardArc};
use crate::{
assistant_settings::{AssistantProvider, AssistantSettings},
LanguageModel, LanguageModelRequest,
};
use anyhow::Result;
use client::Client;
use futures::{future::BoxFuture, stream::BoxStream};
use gpui::{AnyView, AppContext, BorrowAppContext, Task, WindowContext};
use settings::{Settings, SettingsStore};
use std::time::Duration;
use std::{any::Any, sync::Arc};
/// Choose which model to use for openai provider.
/// If the model is not available, try to use the first available model, or fallback to the original model.
fn choose_openai_model(
model: &::open_ai::Model,
available_models: &[::open_ai::Model],
) -> ::open_ai::Model {
available_models
.iter()
.find(|&m| m == model)
.or_else(|| available_models.first())
.unwrap_or_else(|| model)
.clone()
}
pub fn init(client: Arc<Client>, cx: &mut AppContext) {
let provider = create_provider_from_settings(client.clone(), 0, cx);
cx.set_global(CompletionProvider::new(provider, Some(client)));
let mut settings_version = 0;
cx.observe_global::<SettingsStore>(move |cx| {
settings_version += 1;
cx.update_global::<CompletionProvider, _>(|provider, cx| {
provider.update_settings(settings_version, cx);
})
})
.detach();
}
pub struct CompletionResponse {
pub inner: BoxFuture<'static, Result<BoxStream<'static, Result<String>>>>,
_lock: SemaphoreGuardArc,
}
pub trait LanguageModelCompletionProvider: Send + Sync {
fn available_models(&self, cx: &AppContext) -> Vec<LanguageModel>;
fn settings_version(&self) -> usize;
fn is_authenticated(&self) -> bool;
fn authenticate(&self, cx: &AppContext) -> Task<Result<()>>;
fn authentication_prompt(&self, cx: &mut WindowContext) -> AnyView;
fn reset_credentials(&self, cx: &AppContext) -> Task<Result<()>>;
fn model(&self) -> LanguageModel;
fn count_tokens(
&self,
request: LanguageModelRequest,
cx: &AppContext,
) -> BoxFuture<'static, Result<usize>>;
fn complete(
&self,
request: LanguageModelRequest,
) -> BoxFuture<'static, Result<BoxStream<'static, Result<String>>>>;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
const MAX_CONCURRENT_COMPLETION_REQUESTS: usize = 4;
pub struct CompletionProvider {
provider: Arc<RwLock<dyn LanguageModelCompletionProvider>>,
client: Option<Arc<Client>>,
request_limiter: Arc<Semaphore>,
}
impl CompletionProvider {
pub fn new(
provider: Arc<RwLock<dyn LanguageModelCompletionProvider>>,
client: Option<Arc<Client>>,
) -> Self {
Self {
provider,
client,
request_limiter: Arc::new(Semaphore::new(MAX_CONCURRENT_COMPLETION_REQUESTS)),
}
}
pub fn available_models(&self, cx: &AppContext) -> Vec<LanguageModel> {
self.provider.read().available_models(cx)
}
pub fn settings_version(&self) -> usize {
self.provider.read().settings_version()
}
pub fn is_authenticated(&self) -> bool {
self.provider.read().is_authenticated()
}
pub fn authenticate(&self, cx: &AppContext) -> Task<Result<()>> {
self.provider.read().authenticate(cx)
}
pub fn authentication_prompt(&self, cx: &mut WindowContext) -> AnyView {
self.provider.read().authentication_prompt(cx)
}
pub fn reset_credentials(&self, cx: &AppContext) -> Task<Result<()>> {
self.provider.read().reset_credentials(cx)
}
pub fn model(&self) -> LanguageModel {
self.provider.read().model()
}
pub fn count_tokens(
&self,
request: LanguageModelRequest,
cx: &AppContext,
) -> BoxFuture<'static, Result<usize>> {
self.provider.read().count_tokens(request, cx)
}
pub fn complete(
&self,
request: LanguageModelRequest,
cx: &AppContext,
) -> Task<CompletionResponse> {
let rate_limiter = self.request_limiter.clone();
let provider = self.provider.clone();
cx.background_executor().spawn(async move {
let lock = rate_limiter.acquire_arc().await;
let response = provider.read().complete(request);
CompletionResponse {
inner: response,
_lock: lock,
}
})
}
}
impl gpui::Global for CompletionProvider {}
impl CompletionProvider {
pub fn global(cx: &AppContext) -> &Self {
cx.global::<Self>()
}
pub fn update_current_as<R, T: LanguageModelCompletionProvider + 'static>(
&mut self,
update: impl FnOnce(&mut T) -> R,
) -> Option<R> {
let mut provider = self.provider.write();
if let Some(provider) = provider.as_any_mut().downcast_mut::<T>() {
Some(update(provider))
} else {
None
}
}
pub fn update_settings(&mut self, version: usize, cx: &mut AppContext) {
let updated = match &AssistantSettings::get_global(cx).provider {
AssistantProvider::ZedDotDev { model } => self
.update_current_as::<_, CloudCompletionProvider>(|provider| {
provider.update(model.clone(), version);
}),
AssistantProvider::OpenAi {
model,
api_url,
low_speed_timeout_in_seconds,
available_models,
} => self.update_current_as::<_, OpenAiCompletionProvider>(|provider| {
provider.update(
choose_openai_model(&model, &available_models),
api_url.clone(),
low_speed_timeout_in_seconds.map(Duration::from_secs),
version,
);
}),
AssistantProvider::Anthropic {
model,
api_url,
low_speed_timeout_in_seconds,
} => self.update_current_as::<_, AnthropicCompletionProvider>(|provider| {
provider.update(
model.clone(),
api_url.clone(),
low_speed_timeout_in_seconds.map(Duration::from_secs),
version,
);
}),
AssistantProvider::Ollama {
model,
api_url,
low_speed_timeout_in_seconds,
} => self.update_current_as::<_, OllamaCompletionProvider>(|provider| {
provider.update(
model.clone(),
api_url.clone(),
low_speed_timeout_in_seconds.map(Duration::from_secs),
version,
cx,
);
}),
};
// Previously configured provider was changed to another one
if updated.is_none() {
if let Some(client) = self.client.clone() {
self.provider = create_provider_from_settings(client, version, cx);
} else {
log::warn!("completion provider cannot be created because client is not set");
}
}
}
}
fn create_provider_from_settings(
client: Arc<Client>,
settings_version: usize,
cx: &mut AppContext,
) -> Arc<RwLock<dyn LanguageModelCompletionProvider>> {
match &AssistantSettings::get_global(cx).provider {
AssistantProvider::ZedDotDev { model } => Arc::new(RwLock::new(
CloudCompletionProvider::new(model.clone(), client.clone(), settings_version, cx),
)),
AssistantProvider::OpenAi {
model,
api_url,
low_speed_timeout_in_seconds,
available_models,
} => Arc::new(RwLock::new(OpenAiCompletionProvider::new(
choose_openai_model(&model, &available_models),
api_url.clone(),
client.http_client(),
low_speed_timeout_in_seconds.map(Duration::from_secs),
settings_version,
))),
AssistantProvider::Anthropic {
model,
api_url,
low_speed_timeout_in_seconds,
} => Arc::new(RwLock::new(AnthropicCompletionProvider::new(
model.clone(),
api_url.clone(),
client.http_client(),
low_speed_timeout_in_seconds.map(Duration::from_secs),
settings_version,
))),
AssistantProvider::Ollama {
model,
api_url,
low_speed_timeout_in_seconds,
} => Arc::new(RwLock::new(OllamaCompletionProvider::new(
model.clone(),
api_url.clone(),
client.http_client(),
low_speed_timeout_in_seconds.map(Duration::from_secs),
settings_version,
cx,
))),
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use gpui::AppContext;
use parking_lot::RwLock;
use settings::SettingsStore;
use smol::stream::StreamExt;
use crate::{
completion_provider::MAX_CONCURRENT_COMPLETION_REQUESTS, CompletionProvider,
FakeCompletionProvider, LanguageModelRequest,
};
#[gpui::test]
fn test_rate_limiting(cx: &mut AppContext) {
SettingsStore::test(cx);
let fake_provider = FakeCompletionProvider::setup_test(cx);
let provider = CompletionProvider::new(Arc::new(RwLock::new(fake_provider.clone())), None);
// Enqueue some requests
for i in 0..MAX_CONCURRENT_COMPLETION_REQUESTS * 2 {
let response = provider.complete(
LanguageModelRequest {
temperature: i as f32 / 10.0,
..Default::default()
},
cx,
);
cx.background_executor()
.spawn(async move {
let response = response.await;
let mut stream = response.inner.await.unwrap();
while let Some(message) = stream.next().await {
message.unwrap();
}
})
.detach();
}
cx.background_executor().run_until_parked();
assert_eq!(
fake_provider.completion_count(),
MAX_CONCURRENT_COMPLETION_REQUESTS
);
// Get the first completion request that is in flight and mark it as completed.
let completion = fake_provider
.running_completions()
.into_iter()
.next()
.unwrap();
fake_provider.finish_completion(&completion);
// Ensure that the number of in-flight completion requests is reduced.
assert_eq!(
fake_provider.completion_count(),
MAX_CONCURRENT_COMPLETION_REQUESTS - 1
);
cx.background_executor().run_until_parked();
// Ensure that another completion request was allowed to acquire the lock.
assert_eq!(
fake_provider.completion_count(),
MAX_CONCURRENT_COMPLETION_REQUESTS
);
// Mark all completion requests as finished that are in flight.
for request in fake_provider.running_completions() {
fake_provider.finish_completion(&request);
}
assert_eq!(fake_provider.completion_count(), 0);
// Wait until the background tasks acquire the lock again.
cx.background_executor().run_until_parked();
assert_eq!(
fake_provider.completion_count(),
MAX_CONCURRENT_COMPLETION_REQUESTS - 1
);
// Finish all remaining completion requests.
for request in fake_provider.running_completions() {
fake_provider.finish_completion(&request);
}
cx.background_executor().run_until_parked();
assert_eq!(fake_provider.completion_count(), 0);
}
}

View File

@@ -1,208 +0,0 @@
use crate::{
assistant_settings::CloudModel, count_open_ai_tokens, CompletionProvider, LanguageModel,
LanguageModelCompletionProvider, LanguageModelRequest,
};
use anyhow::{anyhow, Result};
use client::{proto, Client};
use futures::{future::BoxFuture, stream::BoxStream, FutureExt, StreamExt, TryFutureExt};
use gpui::{AnyView, AppContext, Task};
use std::{future, sync::Arc};
use strum::IntoEnumIterator;
use ui::prelude::*;
pub struct CloudCompletionProvider {
client: Arc<Client>,
model: CloudModel,
settings_version: usize,
status: client::Status,
_maintain_client_status: Task<()>,
}
impl CloudCompletionProvider {
pub fn new(
model: CloudModel,
client: Arc<Client>,
settings_version: usize,
cx: &mut AppContext,
) -> Self {
let mut status_rx = client.status();
let status = *status_rx.borrow();
let maintain_client_status = cx.spawn(|mut cx| async move {
while let Some(status) = status_rx.next().await {
let _ = cx.update_global::<CompletionProvider, _>(|provider, _cx| {
provider.update_current_as::<_, Self>(|provider| {
provider.status = status;
});
});
}
});
Self {
client,
model,
settings_version,
status,
_maintain_client_status: maintain_client_status,
}
}
pub fn update(&mut self, model: CloudModel, settings_version: usize) {
self.model = model;
self.settings_version = settings_version;
}
}
impl LanguageModelCompletionProvider for CloudCompletionProvider {
fn available_models(&self, _cx: &AppContext) -> Vec<LanguageModel> {
let mut custom_model = if let CloudModel::Custom(custom_model) = self.model.clone() {
Some(custom_model)
} else {
None
};
CloudModel::iter()
.filter_map(move |model| {
if let CloudModel::Custom(_) = model {
Some(CloudModel::Custom(custom_model.take()?))
} else {
Some(model)
}
})
.map(LanguageModel::Cloud)
.collect()
}
fn settings_version(&self) -> usize {
self.settings_version
}
fn is_authenticated(&self) -> bool {
self.status.is_connected()
}
fn authenticate(&self, cx: &AppContext) -> Task<Result<()>> {
let client = self.client.clone();
cx.spawn(move |cx| async move { client.authenticate_and_connect(true, &cx).await })
}
fn authentication_prompt(&self, cx: &mut WindowContext) -> AnyView {
cx.new_view(|_cx| AuthenticationPrompt).into()
}
fn reset_credentials(&self, _cx: &AppContext) -> Task<Result<()>> {
Task::ready(Ok(()))
}
fn model(&self) -> LanguageModel {
LanguageModel::Cloud(self.model.clone())
}
fn count_tokens(
&self,
request: LanguageModelRequest,
cx: &AppContext,
) -> BoxFuture<'static, Result<usize>> {
match request.model {
LanguageModel::Cloud(CloudModel::Gpt4)
| LanguageModel::Cloud(CloudModel::Gpt4Turbo)
| LanguageModel::Cloud(CloudModel::Gpt4Omni)
| LanguageModel::Cloud(CloudModel::Gpt3Point5Turbo) => {
count_open_ai_tokens(request, cx.background_executor())
}
LanguageModel::Cloud(
CloudModel::Claude3_5Sonnet
| CloudModel::Claude3Opus
| CloudModel::Claude3Sonnet
| CloudModel::Claude3Haiku,
) => {
// Can't find a tokenizer for Claude 3, so for now just use the same as OpenAI's as an approximation.
count_open_ai_tokens(request, cx.background_executor())
}
LanguageModel::Cloud(CloudModel::Custom(model)) => {
let request = self.client.request(proto::CountTokensWithLanguageModel {
model,
messages: request
.messages
.iter()
.map(|message| message.to_proto())
.collect(),
});
async move {
let response = request.await?;
Ok(response.token_count as usize)
}
.boxed()
}
_ => future::ready(Err(anyhow!("invalid model"))).boxed(),
}
}
fn complete(
&self,
mut request: LanguageModelRequest,
) -> BoxFuture<'static, Result<BoxStream<'static, Result<String>>>> {
request.preprocess();
let request = proto::CompleteWithLanguageModel {
model: request.model.id().to_string(),
messages: request
.messages
.iter()
.map(|message| message.to_proto())
.collect(),
stop: request.stop,
temperature: request.temperature,
tools: Vec::new(),
tool_choice: None,
};
self.client
.request_stream(request)
.map_ok(|stream| {
stream
.filter_map(|response| async move {
match response {
Ok(mut response) => Some(Ok(response.choices.pop()?.delta?.content?)),
Err(error) => Some(Err(error)),
}
})
.boxed()
})
.boxed()
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}
struct AuthenticationPrompt;
impl Render for AuthenticationPrompt {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
const LABEL: &str = "Generate and analyze code with language models. You can dialog with the assistant in this panel or transform code inline.";
v_flex().gap_6().p_4().child(Label::new(LABEL)).child(
v_flex()
.gap_2()
.child(
Button::new("sign_in", "Sign in")
.icon_color(Color::Muted)
.icon(IconName::Github)
.icon_position(IconPosition::Start)
.style(ButtonStyle::Filled)
.full_width()
.on_click(|_, cx| {
CompletionProvider::global(cx)
.authenticate(cx)
.detach_and_log_err(cx);
}),
)
.child(
div().flex().w_full().items_center().child(
Label::new("Sign in to enable collaboration.")
.color(Color::Muted)
.size(LabelSize::Small),
),
),
)
}
}

View File

@@ -1,106 +0,0 @@
use anyhow::Result;
use collections::HashMap;
use futures::{channel::mpsc, future::BoxFuture, stream::BoxStream, FutureExt, StreamExt};
use gpui::{AnyView, AppContext, Task};
use std::sync::Arc;
use ui::WindowContext;
use crate::{LanguageModel, LanguageModelCompletionProvider, LanguageModelRequest};
#[derive(Clone, Default)]
pub struct FakeCompletionProvider {
current_completion_txs: Arc<parking_lot::Mutex<HashMap<String, mpsc::UnboundedSender<String>>>>,
}
impl FakeCompletionProvider {
pub fn setup_test(cx: &mut AppContext) -> Self {
use crate::CompletionProvider;
use parking_lot::RwLock;
let this = Self::default();
let provider = CompletionProvider::new(Arc::new(RwLock::new(this.clone())), None);
cx.set_global(provider);
this
}
pub fn running_completions(&self) -> Vec<LanguageModelRequest> {
self.current_completion_txs
.lock()
.keys()
.map(|k| serde_json::from_str(k).unwrap())
.collect()
}
pub fn completion_count(&self) -> usize {
self.current_completion_txs.lock().len()
}
pub fn send_completion(&self, request: &LanguageModelRequest, chunk: String) {
let json = serde_json::to_string(request).unwrap();
self.current_completion_txs
.lock()
.get(&json)
.unwrap()
.unbounded_send(chunk)
.unwrap();
}
pub fn finish_completion(&self, request: &LanguageModelRequest) {
self.current_completion_txs
.lock()
.remove(&serde_json::to_string(request).unwrap());
}
}
impl LanguageModelCompletionProvider for FakeCompletionProvider {
fn available_models(&self, _cx: &AppContext) -> Vec<LanguageModel> {
vec![LanguageModel::default()]
}
fn settings_version(&self) -> usize {
0
}
fn is_authenticated(&self) -> bool {
true
}
fn authenticate(&self, _cx: &AppContext) -> Task<Result<()>> {
Task::ready(Ok(()))
}
fn authentication_prompt(&self, _cx: &mut WindowContext) -> AnyView {
unimplemented!()
}
fn reset_credentials(&self, _cx: &AppContext) -> Task<Result<()>> {
Task::ready(Ok(()))
}
fn model(&self) -> LanguageModel {
LanguageModel::default()
}
fn count_tokens(
&self,
_request: LanguageModelRequest,
_cx: &AppContext,
) -> BoxFuture<'static, Result<usize>> {
futures::future::ready(Ok(0)).boxed()
}
fn complete(
&self,
_request: LanguageModelRequest,
) -> BoxFuture<'static, Result<BoxStream<'static, Result<String>>>> {
let (tx, rx) = mpsc::unbounded();
self.current_completion_txs
.lock()
.insert(serde_json::to_string(&_request).unwrap(), tx);
async move { Ok(rx.map(Ok).boxed()) }.boxed()
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
use crate::{
assistant_settings::AssistantSettings, humanize_token_count, prompts::generate_content_prompt,
AssistantPanel, AssistantPanelEvent, CompletionProvider, Hunk, LanguageModelRequest,
LanguageModelRequestMessage, Role, StreamingDiff,
humanize_token_count, prompts::generate_content_prompt, AssistantPanel, AssistantPanelEvent,
Hunk, LanguageModelCompletionProvider, ModelSelector, StreamingDiff,
};
use anyhow::{anyhow, Context as _, Result};
use client::telemetry::Telemetry;
@@ -9,27 +8,36 @@ use collections::{hash_map, HashMap, HashSet, VecDeque};
use editor::{
actions::{MoveDown, MoveUp, SelectAll},
display_map::{
BlockContext, BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock,
BlockContext, BlockDisposition, BlockProperties, BlockStyle, CustomBlockId, RenderBlock,
ToDisplayPoint,
},
Anchor, AnchorRangeExt, Editor, EditorElement, EditorEvent, EditorMode, EditorStyle,
ExcerptRange, GutterDimensions, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint,
};
use fs::Fs;
use futures::{channel::mpsc, SinkExt, Stream, StreamExt};
use gpui::{
point, AppContext, EventEmitter, FocusHandle, FocusableView, FontStyle, Global, HighlightStyle,
Model, ModelContext, Subscription, Task, TextStyle, UpdateGlobal, View, ViewContext, WeakView,
WhiteSpace, WindowContext,
use futures::{
channel::mpsc,
future::LocalBoxFuture,
stream::{self, BoxStream},
SinkExt, Stream, StreamExt,
};
use language::{Buffer, Point, Selection, TransactionId};
use gpui::{
point, AppContext, EventEmitter, FocusHandle, FocusableView, Global, HighlightStyle, Model,
ModelContext, Subscription, Task, TextStyle, UpdateGlobal, View, ViewContext, WeakView,
WindowContext,
};
use language::{Buffer, IndentKind, Point, Selection, TransactionId};
use language_model::{LanguageModelRequest, LanguageModelRequestMessage, Role};
use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use rope::Rope;
use settings::{update_settings_file, Settings};
use settings::Settings;
use similar::TextDiff;
use smol::future::FutureExt;
use std::{
cmp, mem,
cmp,
future::Future,
mem,
ops::{Range, RangeInclusive},
pin::Pin,
sync::Arc,
@@ -37,7 +45,7 @@ use std::{
time::{Duration, Instant},
};
use theme::ThemeSettings;
use ui::{prelude::*, ContextMenu, PopoverMenu, Tooltip};
use ui::{prelude::*, IconButtonShape, Tooltip};
use util::RangeExt;
use workspace::{notifications::NotificationId, Toast, Workspace};
@@ -79,6 +87,7 @@ impl InlineAssistant {
editor: &View<Editor>,
workspace: Option<WeakView<Workspace>>,
assistant_panel: Option<&View<AssistantPanel>>,
initial_prompt: Option<String>,
cx: &mut WindowContext,
) {
let snapshot = editor.read(cx).buffer().read(cx).snapshot(cx);
@@ -130,11 +139,11 @@ impl InlineAssistant {
}
let assist_group_id = self.next_assist_group_id.post_inc();
let prompt_buffer = cx.new_model(|cx| Buffer::local("", cx));
let prompt_buffer =
cx.new_model(|cx| Buffer::local(initial_prompt.unwrap_or_default(), cx));
let prompt_buffer = cx.new_model(|cx| MultiBuffer::singleton(prompt_buffer, cx));
let mut assists = Vec::new();
let mut assist_blocks = Vec::new();
let mut assist_to_focus = None;
for range in codegen_ranges {
let assist_id = self.next_assist_id.post_inc();
@@ -142,6 +151,7 @@ impl InlineAssistant {
Codegen::new(
editor.read(cx).buffer().clone(),
range.clone(),
None,
self.telemetry.clone(),
cx,
)
@@ -174,42 +184,18 @@ impl InlineAssistant {
}
}
assist_blocks.push(BlockProperties {
style: BlockStyle::Sticky,
position: range.start,
height: prompt_editor.read(cx).height_in_lines,
render: build_assist_editor_renderer(&prompt_editor),
disposition: BlockDisposition::Above,
});
assist_blocks.push(BlockProperties {
style: BlockStyle::Sticky,
position: range.end,
height: 1,
render: Box::new(|cx| {
v_flex()
.h_full()
.w_full()
.border_t_1()
.border_color(cx.theme().status().info_border)
.into_any_element()
}),
disposition: BlockDisposition::Below,
});
assists.push((assist_id, prompt_editor));
}
let [prompt_block_id, end_block_id] =
self.insert_assist_blocks(editor, &range, &prompt_editor, cx);
let assist_block_ids = editor.update(cx, |editor, cx| {
editor.insert_blocks(assist_blocks, None, cx)
});
assists.push((assist_id, prompt_editor, prompt_block_id, end_block_id));
}
let editor_assists = self
.assists_by_editor
.entry(editor.downgrade())
.or_insert_with(|| EditorInlineAssists::new(&editor, cx));
let mut assist_group = InlineAssistGroup::new();
for ((assist_id, prompt_editor), block_ids) in
assists.into_iter().zip(assist_block_ids.chunks_exact(2))
{
for (assist_id, prompt_editor, prompt_block_id, end_block_id) in assists {
self.assists.insert(
assist_id,
InlineAssist::new(
@@ -218,8 +204,8 @@ impl InlineAssistant {
assistant_panel.is_some(),
editor,
&prompt_editor,
block_ids[0],
block_ids[1],
prompt_block_id,
end_block_id,
prompt_editor.read(cx).codegen.clone(),
workspace.clone(),
cx,
@@ -235,6 +221,128 @@ impl InlineAssistant {
}
}
#[allow(clippy::too_many_arguments)]
pub fn suggest_assist(
&mut self,
editor: &View<Editor>,
mut range: Range<Anchor>,
initial_prompt: String,
initial_insertion: Option<String>,
workspace: Option<WeakView<Workspace>>,
assistant_panel: Option<&View<AssistantPanel>>,
cx: &mut WindowContext,
) -> InlineAssistId {
let assist_group_id = self.next_assist_group_id.post_inc();
let prompt_buffer = cx.new_model(|cx| Buffer::local(&initial_prompt, cx));
let prompt_buffer = cx.new_model(|cx| MultiBuffer::singleton(prompt_buffer, cx));
let assist_id = self.next_assist_id.post_inc();
let buffer = editor.read(cx).buffer().clone();
let prepend_transaction_id = initial_insertion.and_then(|initial_insertion| {
buffer.update(cx, |buffer, cx| {
buffer.start_transaction(cx);
buffer.edit([(range.start..range.start, initial_insertion)], None, cx);
buffer.end_transaction(cx)
})
});
range.start = range.start.bias_left(&buffer.read(cx).read(cx));
range.end = range.end.bias_right(&buffer.read(cx).read(cx));
let codegen = cx.new_model(|cx| {
Codegen::new(
editor.read(cx).buffer().clone(),
range.clone(),
prepend_transaction_id,
self.telemetry.clone(),
cx,
)
});
let gutter_dimensions = Arc::new(Mutex::new(GutterDimensions::default()));
let prompt_editor = cx.new_view(|cx| {
PromptEditor::new(
assist_id,
gutter_dimensions.clone(),
self.prompt_history.clone(),
prompt_buffer.clone(),
codegen.clone(),
editor,
assistant_panel,
workspace.clone(),
self.fs.clone(),
cx,
)
});
let [prompt_block_id, end_block_id] =
self.insert_assist_blocks(editor, &range, &prompt_editor, cx);
let editor_assists = self
.assists_by_editor
.entry(editor.downgrade())
.or_insert_with(|| EditorInlineAssists::new(&editor, cx));
let mut assist_group = InlineAssistGroup::new();
self.assists.insert(
assist_id,
InlineAssist::new(
assist_id,
assist_group_id,
assistant_panel.is_some(),
editor,
&prompt_editor,
prompt_block_id,
end_block_id,
prompt_editor.read(cx).codegen.clone(),
workspace.clone(),
cx,
),
);
assist_group.assist_ids.push(assist_id);
editor_assists.assist_ids.push(assist_id);
self.assist_groups.insert(assist_group_id, assist_group);
assist_id
}
fn insert_assist_blocks(
&self,
editor: &View<Editor>,
range: &Range<Anchor>,
prompt_editor: &View<PromptEditor>,
cx: &mut WindowContext,
) -> [CustomBlockId; 2] {
let assist_blocks = vec![
BlockProperties {
style: BlockStyle::Sticky,
position: range.start,
height: prompt_editor.read(cx).height_in_lines,
render: build_assist_editor_renderer(prompt_editor),
disposition: BlockDisposition::Above,
},
BlockProperties {
style: BlockStyle::Sticky,
position: range.end,
height: 1,
render: Box::new(|cx| {
v_flex()
.h_full()
.w_full()
.border_t_1()
.border_color(cx.theme().status().info_border)
.into_any_element()
}),
disposition: BlockDisposition::Below,
},
];
editor.update(cx, |editor, cx| {
let block_ids = editor.insert_blocks(assist_blocks, None, cx);
[block_ids[0], block_ids[1]]
})
}
fn handle_prompt_editor_focus_in(&mut self, assist_id: InlineAssistId, cx: &mut WindowContext) {
let assist = &self.assists[&assist_id];
let Some(decorations) = assist.decorations.as_ref() else {
@@ -379,6 +487,14 @@ impl InlineAssistant {
cx.propagate();
}
fn handle_editor_release(&mut self, editor: WeakView<Editor>, cx: &mut WindowContext) {
if let Some(editor_assists) = self.assists_by_editor.get_mut(&editor) {
for assist_id in editor_assists.assist_ids.clone() {
self.finish_assist(assist_id, true, cx);
}
}
}
fn handle_editor_change(&mut self, editor: View<Editor>, cx: &mut WindowContext) {
let Some(editor_assists) = self.assists_by_editor.get(&editor.downgrade()) else {
return;
@@ -698,7 +814,7 @@ impl InlineAssistant {
assist_group.assist_ids.clone()
}
fn start_assist(&mut self, assist_id: InlineAssistId, cx: &mut WindowContext) {
pub fn start_assist(&mut self, assist_id: InlineAssistId, cx: &mut WindowContext) {
let assist = if let Some(assist) = self.assists.get_mut(&assist_id) {
assist
} else {
@@ -727,16 +843,32 @@ impl InlineAssistant {
self.prompt_history.pop_front();
}
assist.codegen.update(cx, |codegen, cx| codegen.undo(cx));
let codegen = assist.codegen.clone();
let request = self.request_for_inline_assist(assist_id, cx);
cx.spawn(|mut cx| async move {
let request = request.await?;
codegen.update(&mut cx, |codegen, cx| codegen.start(request, cx))?;
anyhow::Ok(())
})
.detach_and_log_err(cx);
let telemetry_id = LanguageModelCompletionProvider::read_global(cx)
.active_model()
.map(|m| m.telemetry_id())
.unwrap_or_default();
let chunks: LocalBoxFuture<Result<BoxStream<Result<String>>>> =
if user_prompt.trim().to_lowercase() == "delete" {
async { Ok(stream::empty().boxed()) }.boxed_local()
} else {
let request = self.request_for_inline_assist(assist_id, cx);
let mut cx = cx.to_async();
async move {
let request = request.await?;
let chunks = cx
.update(|cx| {
LanguageModelCompletionProvider::read_global(cx)
.stream_completion(request, cx)
})?
.await?;
Ok(chunks.boxed())
}
.boxed_local()
};
codegen.update(cx, |codegen, cx| {
codegen.start(telemetry_id, chunks, cx);
});
}
fn request_for_inline_assist(
@@ -745,8 +877,8 @@ impl InlineAssistant {
cx: &mut WindowContext,
) -> Task<Result<LanguageModelRequest>> {
cx.spawn(|mut cx| async move {
let (user_prompt, context_request, project_name, buffer, range, model) = cx
.read_global(|this: &InlineAssistant, cx: &WindowContext| {
let (user_prompt, context_request, project_name, buffer, range) =
cx.read_global(|this: &InlineAssistant, cx: &WindowContext| {
let assist = this.assists.get(&assist_id).context("invalid assist")?;
let decorations = assist.decorations.as_ref().context("invalid assist")?;
let editor = assist.editor.upgrade().context("invalid assist")?;
@@ -780,15 +912,7 @@ impl InlineAssistant {
});
let buffer = editor.read(cx).buffer().read(cx).snapshot(cx);
let range = assist.codegen.read(cx).range.clone();
let model = CompletionProvider::global(cx).model();
anyhow::Ok((
user_prompt,
context_request,
project_name,
buffer,
range,
model,
))
anyhow::Ok((user_prompt, context_request, project_name, buffer, range))
})??;
let language = buffer.language_at(range.start);
@@ -847,7 +971,6 @@ impl InlineAssistant {
});
Ok(LanguageModelRequest {
model,
messages,
stop: vec!["|END|>".to_string()],
temperature,
@@ -855,7 +978,7 @@ impl InlineAssistant {
})
}
fn stop_assist(&mut self, assist_id: InlineAssistId, cx: &mut WindowContext) {
pub fn stop_assist(&mut self, assist_id: InlineAssistId, cx: &mut WindowContext) {
let assist = if let Some(assist) = self.assists.get_mut(&assist_id) {
assist
} else {
@@ -1074,6 +1197,14 @@ impl EditorInlineAssists {
}
}),
_subscriptions: vec![
cx.observe_release(editor, {
let editor = editor.downgrade();
|_, cx| {
InlineAssistant::update_global(cx, |this, cx| {
this.handle_editor_release(editor, cx);
})
}
}),
cx.observe(editor, move |editor, cx| {
InlineAssistant::update_global(cx, |this, cx| {
this.handle_editor_change(editor, cx)
@@ -1138,7 +1269,7 @@ fn build_assist_editor_renderer(editor: &View<PromptEditor>) -> RenderBlock {
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Hash)]
struct InlineAssistId(usize);
pub struct InlineAssistId(usize);
impl InlineAssistId {
fn post_inc(&mut self) -> InlineAssistId {
@@ -1192,22 +1323,19 @@ impl EventEmitter<PromptEditorEvent> for PromptEditor {}
impl Render for PromptEditor {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let gutter_dimensions = *self.gutter_dimensions.lock();
let fs = self.fs.clone();
let buttons = match &self.codegen.read(cx).status {
CodegenStatus::Idle => {
vec![
IconButton::new("cancel", IconName::Close)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::for_action("Cancel Assist", &menu::Cancel, cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)),
),
IconButton::new("start", IconName::Sparkle)
IconButton::new("start", IconName::SparkleAlt)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.icon_size(IconSize::XSmall)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::for_action("Transform", &menu::Confirm, cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::StartRequested)),
@@ -1218,15 +1346,14 @@ impl Render for PromptEditor {
vec![
IconButton::new("cancel", IconName::Close)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::text("Cancel Assist", cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)),
),
IconButton::new("stop", IconName::Stop)
.icon_color(Color::Error)
.size(ButtonSize::None)
.icon_size(IconSize::XSmall)
.shape(IconButtonShape::Square)
.tooltip(|cx| {
Tooltip::with_meta(
"Interrupt Transformation",
@@ -1244,7 +1371,7 @@ impl Render for PromptEditor {
vec![
IconButton::new("cancel", IconName::Close)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::for_action("Cancel Assist", &menu::Cancel, cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)),
@@ -1252,8 +1379,7 @@ impl Render for PromptEditor {
if self.edited_since_done {
IconButton::new("restart", IconName::RotateCw)
.icon_color(Color::Info)
.icon_size(IconSize::XSmall)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| {
Tooltip::with_meta(
"Restart Transformation",
@@ -1268,7 +1394,7 @@ impl Render for PromptEditor {
} else {
IconButton::new("confirm", IconName::Check)
.icon_color(Color::Info)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::for_action("Confirm Assist", &menu::Confirm, cx))
.on_click(cx.listener(|_, _, cx| {
cx.emit(PromptEditorEvent::ConfirmRequested);
@@ -1295,57 +1421,32 @@ impl Render for PromptEditor {
.justify_center()
.gap_2()
.child(
PopoverMenu::new("model-switcher")
.menu(move |cx| {
ContextMenu::build(cx, |mut menu, cx| {
for model in CompletionProvider::global(cx).available_models(cx)
{
menu = menu.custom_entry(
{
let model = model.clone();
move |_| {
Label::new(model.display_name())
.into_any_element()
}
},
{
let fs = fs.clone();
let model = model.clone();
move |cx| {
let model = model.clone();
update_settings_file::<AssistantSettings>(
fs.clone(),
cx,
move |settings| settings.set_model(model),
);
}
},
);
}
menu
})
.into()
})
.trigger(
IconButton::new("context", IconName::Settings)
.size(ButtonSize::None)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
.tooltip(move |cx| {
Tooltip::with_meta(
format!(
"Using {}",
CompletionProvider::global(cx)
.model()
.display_name()
),
None,
"Click to Change Model",
cx,
)
}),
)
.anchor(gpui::AnchorCorner::BottomRight),
ModelSelector::new(
self.fs.clone(),
IconButton::new("context", IconName::SlidersAlt)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
.tooltip(move |cx| {
Tooltip::with_meta(
format!(
"Using {}",
LanguageModelCompletionProvider::read_global(cx)
.active_model()
.map(|model| model.name().0)
.unwrap_or_else(|| "No model selected".into()),
),
None,
"Change Model",
cx,
)
}),
)
.with_info_text(
"Inline edits use context\n\
from the currently selected\n\
assistant panel tab.",
),
)
.children(
if let CodegenStatus::Error(error) = &self.codegen.read(cx).status {
@@ -1369,7 +1470,7 @@ impl Render for PromptEditor {
.child(
h_flex()
.gap_2()
.pr_4()
.pr_6()
.children(self.render_token_count(cx))
.children(buttons),
)
@@ -1534,13 +1635,18 @@ impl PromptEditor {
})?
.await?;
let token_count = cx
.update(|cx| CompletionProvider::global(cx).count_tokens(request, cx))?
.await?;
this.update(&mut cx, |this, cx| {
this.token_count = Some(token_count);
cx.notify();
})
if let Some(token_count) = cx.update(|cx| {
LanguageModelCompletionProvider::read_global(cx).count_tokens(request, cx)
})? {
let token_count = token_count.await?;
this.update(&mut cx, |this, cx| {
this.token_count = Some(token_count);
cx.notify();
})
} else {
Ok(())
}
})
}
@@ -1663,7 +1769,7 @@ impl PromptEditor {
}
fn render_token_count(&self, cx: &mut ViewContext<Self>) -> Option<impl IntoElement> {
let model = CompletionProvider::global(cx).model();
let model = LanguageModelCompletionProvider::read_global(cx).active_model()?;
let token_count = self.token_count?;
let max_token_count = model.max_token_count();
@@ -1729,14 +1835,11 @@ impl PromptEditor {
},
font_family: settings.ui_font.family.clone(),
font_features: settings.ui_font.features.clone(),
font_fallbacks: settings.ui_font.fallbacks.clone(),
font_size: rems(0.875).into(),
font_weight: settings.ui_font.weight,
font_style: FontStyle::Normal,
line_height: relative(1.3),
background_color: None,
underline: None,
strikethrough: None,
white_space: WhiteSpace::Normal,
..Default::default()
};
EditorElement::new(
&self.editor,
@@ -1768,8 +1871,8 @@ impl InlineAssist {
include_context: bool,
editor: &View<Editor>,
prompt_editor: &View<PromptEditor>,
prompt_block_id: BlockId,
end_block_id: BlockId,
prompt_block_id: CustomBlockId,
end_block_id: CustomBlockId,
codegen: Model<Codegen>,
workspace: Option<WeakView<Workspace>>,
cx: &mut WindowContext,
@@ -1863,10 +1966,10 @@ impl InlineAssist {
}
struct InlineAssistDecorations {
prompt_block_id: BlockId,
prompt_block_id: CustomBlockId,
prompt_editor: View<PromptEditor>,
removed_line_block_ids: HashSet<BlockId>,
end_block_id: BlockId,
removed_line_block_ids: HashSet<CustomBlockId>,
end_block_id: CustomBlockId,
}
#[derive(Debug)]
@@ -1882,7 +1985,8 @@ pub struct Codegen {
range: Range<Anchor>,
edit_position: Anchor,
last_equal_ranges: Vec<Range<Anchor>>,
transaction_id: Option<TransactionId>,
prepend_transaction_id: Option<TransactionId>,
generation_transaction_id: Option<TransactionId>,
status: CodegenStatus,
generation: Task<()>,
diff: Diff,
@@ -1911,6 +2015,7 @@ impl Codegen {
pub fn new(
buffer: Model<MultiBuffer>,
range: Range<Anchor>,
prepend_transaction_id: Option<TransactionId>,
telemetry: Option<Arc<Telemetry>>,
cx: &mut ModelContext<Self>,
) -> Self {
@@ -1943,7 +2048,8 @@ impl Codegen {
range,
snapshot,
last_equal_ranges: Default::default(),
transaction_id: Default::default(),
prepend_transaction_id,
generation_transaction_id: None,
status: CodegenStatus::Idle,
generation: Task::ready(()),
diff: Diff::default(),
@@ -1959,8 +2065,13 @@ impl Codegen {
cx: &mut ModelContext<Self>,
) {
if let multi_buffer::Event::TransactionUndone { transaction_id } = event {
if self.transaction_id == Some(*transaction_id) {
self.transaction_id = None;
if self.generation_transaction_id == Some(*transaction_id) {
self.generation_transaction_id = None;
self.generation = Task::ready(());
cx.emit(CodegenEvent::Undone);
} else if self.prepend_transaction_id == Some(*transaction_id) {
self.prepend_transaction_id = None;
self.generation_transaction_id = None;
self.generation = Task::ready(());
cx.emit(CodegenEvent::Undone);
}
@@ -1971,7 +2082,12 @@ impl Codegen {
&self.last_equal_ranges
}
pub fn start(&mut self, prompt: LanguageModelRequest, cx: &mut ModelContext<Self>) {
pub fn start(
&mut self,
telemetry_id: String,
stream: impl 'static + Future<Output = Result<BoxStream<'static, Result<String>>>>,
cx: &mut ModelContext<Self>,
) {
let range = self.range.clone();
let snapshot = self.snapshot.clone();
let selected_text = snapshot
@@ -1979,21 +2095,37 @@ impl Codegen {
.collect::<Rope>();
let selection_start = range.start.to_point(&snapshot);
let suggested_line_indent = snapshot
.suggested_indents(selection_start.row..selection_start.row + 1, cx)
// Start with the indentation of the first line in the selection
let mut suggested_line_indent = snapshot
.suggested_indents(selection_start.row..=selection_start.row, cx)
.into_values()
.next()
.unwrap_or_else(|| snapshot.indent_size_for_line(MultiBufferRow(selection_start.row)));
let model_telemetry_id = prompt.model.telemetry_id();
let response = CompletionProvider::global(cx).complete(prompt, cx);
// If the first line in the selection does not have indentation, check the following lines
if suggested_line_indent.len == 0 && suggested_line_indent.kind == IndentKind::Space {
for row in selection_start.row..=range.end.to_point(&snapshot).row {
let line_indent = snapshot.indent_size_for_line(MultiBufferRow(row));
// Prefer tabs if a line in the selection uses tabs as indentation
if line_indent.kind == IndentKind::Tab {
suggested_line_indent.kind = IndentKind::Tab;
break;
}
}
}
let telemetry = self.telemetry.clone();
self.edit_position = range.start;
self.diff = Diff::default();
self.status = CodegenStatus::Pending;
if let Some(transaction_id) = self.generation_transaction_id.take() {
self.buffer
.update(cx, |buffer, cx| buffer.undo_transaction(transaction_id, cx));
}
self.generation = cx.spawn(|this, mut cx| {
async move {
let response = response.await;
let chunks = stream.await;
let generate = async {
let mut edit_start = range.start.to_offset(&snapshot);
@@ -2003,7 +2135,7 @@ impl Codegen {
let mut response_latency = None;
let request_start = Instant::now();
let diff = async {
let chunks = StripInvalidSpans::new(response.inner.await?);
let chunks = StripInvalidSpans::new(chunks?);
futures::pin_mut!(chunks);
let mut diff = StreamingDiff::new(selected_text.to_string());
@@ -2086,7 +2218,7 @@ impl Codegen {
telemetry.report_assistant_event(
None,
telemetry_events::AssistantKind::Inline,
model_telemetry_id,
telemetry_id,
response_latency,
error_message,
);
@@ -2136,7 +2268,7 @@ impl Codegen {
});
if let Some(transaction) = transaction {
if let Some(first_transaction) = this.transaction_id {
if let Some(first_transaction) = this.generation_transaction_id {
// Group all assistant edits into the first transaction.
this.buffer.update(cx, |buffer, cx| {
buffer.merge_transactions(
@@ -2146,7 +2278,7 @@ impl Codegen {
)
});
} else {
this.transaction_id = Some(transaction);
this.generation_transaction_id = Some(transaction);
this.buffer.update(cx, |buffer, cx| {
buffer.finalize_last_transaction(cx)
});
@@ -2189,7 +2321,12 @@ impl Codegen {
}
pub fn undo(&mut self, cx: &mut ModelContext<Self>) {
if let Some(transaction_id) = self.transaction_id.take() {
if let Some(transaction_id) = self.prepend_transaction_id.take() {
self.buffer
.update(cx, |buffer, cx| buffer.undo_transaction(transaction_id, cx));
}
if let Some(transaction_id) = self.generation_transaction_id.take() {
self.buffer
.update(cx, |buffer, cx| buffer.undo_transaction(transaction_id, cx));
}
@@ -2451,10 +2588,6 @@ fn merge_ranges(ranges: &mut Vec<Range<Anchor>>, buffer: &MultiBufferSnapshot) {
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::FakeCompletionProvider;
use super::*;
use futures::stream::{self};
use gpui::{Context, TestAppContext};
@@ -2463,9 +2596,11 @@ mod tests {
language_settings, tree_sitter_rust, Buffer, Language, LanguageConfig, LanguageMatcher,
Point,
};
use language_model::LanguageModelRegistry;
use rand::prelude::*;
use serde::Serialize;
use settings::SettingsStore;
use std::{future, sync::Arc};
#[derive(Serialize)]
pub struct DummyCompletionRequest {
@@ -2475,7 +2610,8 @@ mod tests {
#[gpui::test(iterations = 10)]
async fn test_transform_autoindent(cx: &mut TestAppContext, mut rng: StdRng) {
cx.set_global(cx.update(SettingsStore::test));
let provider = cx.update(|cx| FakeCompletionProvider::setup_test(cx));
cx.update(language_model::LanguageModelRegistry::test);
cx.update(completion::LanguageModelCompletionProvider::test);
cx.update(language_settings::init);
let text = indoc! {"
@@ -2493,14 +2629,17 @@ mod tests {
let snapshot = buffer.snapshot(cx);
snapshot.anchor_before(Point::new(1, 0))..snapshot.anchor_after(Point::new(4, 5))
});
let codegen = cx.new_model(|cx| Codegen::new(buffer.clone(), range, None, cx));
let codegen = cx.new_model(|cx| Codegen::new(buffer.clone(), range, None, None, cx));
let (chunks_tx, chunks_rx) = mpsc::unbounded();
codegen.update(cx, |codegen, cx| {
codegen.start(LanguageModelRequest::default(), cx)
codegen.start(
String::new(),
future::ready(Ok(chunks_rx.map(|chunk| Ok(chunk)).boxed())),
cx,
)
});
cx.background_executor.run_until_parked();
let mut new_text = concat!(
" let mut x = 0;\n",
" while x < 10 {\n",
@@ -2511,11 +2650,11 @@ mod tests {
let max_len = cmp::min(new_text.len(), 10);
let len = rng.gen_range(1..=max_len);
let (chunk, suffix) = new_text.split_at(len);
provider.send_completion(&LanguageModelRequest::default(), chunk.into());
chunks_tx.unbounded_send(chunk.to_string()).unwrap();
new_text = suffix;
cx.background_executor.run_until_parked();
}
provider.finish_completion(&LanguageModelRequest::default());
drop(chunks_tx);
cx.background_executor.run_until_parked();
assert_eq!(
@@ -2536,7 +2675,6 @@ mod tests {
cx: &mut TestAppContext,
mut rng: StdRng,
) {
let provider = cx.update(|cx| FakeCompletionProvider::setup_test(cx));
cx.set_global(cx.update(SettingsStore::test));
cx.update(language_settings::init);
@@ -2552,10 +2690,16 @@ mod tests {
let snapshot = buffer.snapshot(cx);
snapshot.anchor_before(Point::new(1, 6))..snapshot.anchor_after(Point::new(1, 6))
});
let codegen = cx.new_model(|cx| Codegen::new(buffer.clone(), range, None, cx));
let codegen = cx.new_model(|cx| Codegen::new(buffer.clone(), range, None, None, cx));
let request = LanguageModelRequest::default();
codegen.update(cx, |codegen, cx| codegen.start(request, cx));
let (chunks_tx, chunks_rx) = mpsc::unbounded();
codegen.update(cx, |codegen, cx| {
codegen.start(
String::new(),
future::ready(Ok(chunks_rx.map(|chunk| Ok(chunk)).boxed())),
cx,
)
});
cx.background_executor.run_until_parked();
@@ -2569,11 +2713,11 @@ mod tests {
let max_len = cmp::min(new_text.len(), 10);
let len = rng.gen_range(1..=max_len);
let (chunk, suffix) = new_text.split_at(len);
provider.send_completion(&LanguageModelRequest::default(), chunk.into());
chunks_tx.unbounded_send(chunk.to_string()).unwrap();
new_text = suffix;
cx.background_executor.run_until_parked();
}
provider.finish_completion(&LanguageModelRequest::default());
drop(chunks_tx);
cx.background_executor.run_until_parked();
assert_eq!(
@@ -2594,7 +2738,8 @@ mod tests {
cx: &mut TestAppContext,
mut rng: StdRng,
) {
let provider = cx.update(|cx| FakeCompletionProvider::setup_test(cx));
cx.update(LanguageModelRegistry::test);
cx.update(completion::LanguageModelCompletionProvider::test);
cx.set_global(cx.update(SettingsStore::test));
cx.update(language_settings::init);
@@ -2610,10 +2755,16 @@ mod tests {
let snapshot = buffer.snapshot(cx);
snapshot.anchor_before(Point::new(1, 2))..snapshot.anchor_after(Point::new(1, 2))
});
let codegen = cx.new_model(|cx| Codegen::new(buffer.clone(), range, None, cx));
let codegen = cx.new_model(|cx| Codegen::new(buffer.clone(), range, None, None, cx));
let request = LanguageModelRequest::default();
codegen.update(cx, |codegen, cx| codegen.start(request, cx));
let (chunks_tx, chunks_rx) = mpsc::unbounded();
codegen.update(cx, |codegen, cx| {
codegen.start(
String::new(),
future::ready(Ok(chunks_rx.map(|chunk| Ok(chunk)).boxed())),
cx,
)
});
cx.background_executor.run_until_parked();
@@ -2627,11 +2778,11 @@ mod tests {
let max_len = cmp::min(new_text.len(), 10);
let len = rng.gen_range(1..=max_len);
let (chunk, suffix) = new_text.split_at(len);
provider.send_completion(&LanguageModelRequest::default(), chunk.into());
chunks_tx.unbounded_send(chunk.to_string()).unwrap();
new_text = suffix;
cx.background_executor.run_until_parked();
}
provider.finish_completion(&LanguageModelRequest::default());
drop(chunks_tx);
cx.background_executor.run_until_parked();
assert_eq!(
@@ -2647,6 +2798,62 @@ mod tests {
);
}
#[gpui::test(iterations = 10)]
async fn test_autoindent_respects_tabs_in_selection(cx: &mut TestAppContext) {
cx.update(LanguageModelRegistry::test);
cx.update(completion::LanguageModelCompletionProvider::test);
cx.set_global(cx.update(SettingsStore::test));
cx.update(language_settings::init);
let text = indoc! {"
func main() {
\tx := 0
\tfor i := 0; i < 10; i++ {
\t\tx++
\t}
}
"};
let buffer = cx.new_model(|cx| Buffer::local(text, cx));
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let range = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
snapshot.anchor_before(Point::new(0, 0))..snapshot.anchor_after(Point::new(4, 2))
});
let codegen = cx.new_model(|cx| Codegen::new(buffer.clone(), range, None, None, cx));
let (chunks_tx, chunks_rx) = mpsc::unbounded();
codegen.update(cx, |codegen, cx| {
codegen.start(
String::new(),
future::ready(Ok(chunks_rx.map(|chunk| Ok(chunk)).boxed())),
cx,
)
});
let new_text = concat!(
"func main() {\n",
"\tx := 0\n",
"\tfor x < 10 {\n",
"\t\tx++\n",
"\t}", //
);
chunks_tx.unbounded_send(new_text.to_string()).unwrap();
drop(chunks_tx);
cx.background_executor.run_until_parked();
assert_eq!(
buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx).text()),
indoc! {"
func main() {
\tx := 0
\tfor x < 10 {
\t\tx++
\t}
}
"}
);
}
#[gpui::test]
async fn test_strip_invalid_spans_from_codeblock() {
assert_chunks("Lorem ipsum dolor", "Lorem ipsum dolor").await;

View File

@@ -1,82 +1,148 @@
use std::sync::Arc;
use crate::{assistant_settings::AssistantSettings, CompletionProvider, ToggleModelSelector};
use crate::{assistant_settings::AssistantSettings, LanguageModelCompletionProvider};
use fs::Fs;
use gpui::SharedString;
use language_model::LanguageModelRegistry;
use settings::update_settings_file;
use ui::{prelude::*, ButtonLike, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip};
use ui::{prelude::*, ContextMenu, PopoverMenu, PopoverMenuHandle, PopoverTrigger};
#[derive(IntoElement)]
pub struct ModelSelector {
handle: PopoverMenuHandle<ContextMenu>,
pub struct ModelSelector<T: PopoverTrigger> {
handle: Option<PopoverMenuHandle<ContextMenu>>,
fs: Arc<dyn Fs>,
trigger: T,
info_text: Option<SharedString>,
}
impl ModelSelector {
pub fn new(handle: PopoverMenuHandle<ContextMenu>, fs: Arc<dyn Fs>) -> Self {
ModelSelector { handle, fs }
impl<T: PopoverTrigger> ModelSelector<T> {
pub fn new(fs: Arc<dyn Fs>, trigger: T) -> Self {
ModelSelector {
handle: None,
fs,
trigger,
info_text: None,
}
}
pub fn with_handle(mut self, handle: PopoverMenuHandle<ContextMenu>) -> Self {
self.handle = Some(handle);
self
}
pub fn with_info_text(mut self, text: impl Into<SharedString>) -> Self {
self.info_text = Some(text.into());
self
}
}
impl RenderOnce for ModelSelector {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
PopoverMenu::new("model-switcher")
.with_handle(self.handle)
.menu(move |cx| {
ContextMenu::build(cx, |mut menu, cx| {
for model in CompletionProvider::global(cx).available_models(cx) {
impl<T: PopoverTrigger> RenderOnce for ModelSelector<T> {
fn render(self, _: &mut WindowContext) -> impl IntoElement {
let mut menu = PopoverMenu::new("model-switcher");
if let Some(handle) = self.handle {
menu = menu.with_handle(handle);
}
let info_text = self.info_text.clone();
menu.menu(move |cx| {
ContextMenu::build(cx, |mut menu, cx| {
if let Some(info_text) = info_text.clone() {
menu = menu
.custom_row(move |_cx| {
Label::new(info_text.clone())
.color(Color::Muted)
.into_any_element()
})
.separator();
}
for (index, provider) in LanguageModelRegistry::global(cx)
.read(cx)
.providers()
.enumerate()
{
if index > 0 {
menu = menu.separator();
}
menu = menu.header(provider.name().0);
let available_models = provider.provided_models(cx);
if available_models.is_empty() {
menu = menu.custom_entry(
{
let model = model.clone();
move |_| Label::new(model.display_name()).into_any_element()
move |_| {
h_flex()
.w_full()
.gap_1()
.child(Icon::new(IconName::Settings))
.child(Label::new("Configure"))
.into_any()
}
},
{
let fs = self.fs.clone();
let model = model.clone();
let provider = provider.id();
move |cx| {
let model = model.clone();
update_settings_file::<AssistantSettings>(
fs.clone(),
LanguageModelCompletionProvider::global(cx).update(
cx,
move |settings| settings.set_model(model),
|completion_provider, cx| {
completion_provider
.set_active_provider(provider.clone(), cx)
},
);
}
},
);
}
menu
})
.into()
})
.trigger(
ButtonLike::new("active-model")
.style(ButtonStyle::Subtle)
.child(
h_flex()
.w_full()
.gap_0p5()
.child(
div()
.overflow_x_hidden()
.flex_grow()
.whitespace_nowrap()
.child(
Label::new(
CompletionProvider::global(cx).model().display_name(),
let selected_model = LanguageModelCompletionProvider::read_global(cx)
.active_model()
.map(|m| m.id());
let selected_provider = LanguageModelCompletionProvider::read_global(cx)
.active_provider()
.map(|m| m.id());
for available_model in available_models {
menu = menu.custom_entry(
{
let id = available_model.id();
let provider_id = available_model.provider_id();
let model_name = available_model.name().0.clone();
let selected_model = selected_model.clone();
let selected_provider = selected_provider.clone();
move |_| {
h_flex()
.w_full()
.justify_between()
.child(Label::new(model_name.clone()))
.when(
selected_model.as_ref() == Some(&id)
&& selected_provider.as_ref() == Some(&provider_id),
|this| this.child(Icon::new(IconName::Check)),
)
.size(LabelSize::Small)
.color(Color::Muted),
),
)
.child(
Icon::new(IconName::ChevronDown)
.color(Color::Muted)
.size(IconSize::XSmall),
),
)
.tooltip(move |cx| {
Tooltip::for_action("Change Model", &ToggleModelSelector, cx)
}),
)
.attach(gpui::AnchorCorner::BottomLeft)
.into_any()
}
},
{
let fs = self.fs.clone();
let model = available_model.clone();
move |cx| {
let model = model.clone();
update_settings_file::<AssistantSettings>(
fs.clone(),
cx,
move |settings, _| settings.set_model(model),
);
}
},
);
}
}
menu
})
.into()
})
.trigger(self.trigger)
.attach(gpui::AnchorCorner::BottomLeft)
}
}

View File

@@ -1,8 +1,9 @@
use crate::{
slash_command::SlashCommandCompletionProvider, AssistantPanel, CompletionProvider,
InlineAssist, InlineAssistant, LanguageModelRequest, LanguageModelRequestMessage, Role,
slash_command::SlashCommandCompletionProvider, AssistantPanel, InlineAssist, InlineAssistant,
LanguageModelCompletionProvider,
};
use anyhow::{anyhow, Result};
use assets::Assets;
use chrono::{DateTime, Utc};
use collections::{HashMap, HashSet};
use editor::{actions::Tab, CurrentLineHighlight, Editor, EditorElement, EditorEvent, EditorStyle};
@@ -12,12 +13,13 @@ use futures::{
};
use fuzzy::StringMatchCandidate;
use gpui::{
actions, point, size, transparent_black, AppContext, BackgroundExecutor, Bounds, EventEmitter,
Global, HighlightStyle, PromptLevel, ReadGlobal, Subscription, Task, TextStyle,
actions, point, size, transparent_black, AppContext, AssetSource, BackgroundExecutor, Bounds,
EventEmitter, Global, HighlightStyle, PromptLevel, ReadGlobal, Subscription, Task, TextStyle,
TitlebarOptions, UpdateGlobal, View, WindowBounds, WindowHandle, WindowOptions,
};
use heed::{types::SerdeBincode, Database, RoTxn};
use language::{language_settings::SoftWrap, Buffer, LanguageRegistry};
use language_model::{LanguageModelRequest, LanguageModelRequestMessage, Role};
use parking_lot::RwLock;
use picker::{Picker, PickerDelegate};
use rope::Rope;
@@ -268,7 +270,7 @@ impl PickerDelegate for PromptPickerDelegate {
.flex_none()
.py_1()
.px_2()
.mx_2()
.mx_1()
.child(editor.clone())
}
}
@@ -627,17 +629,18 @@ impl PromptLibrary {
self.picker.update(cx, |picker, cx| picker.focus(cx));
}
pub fn inline_assist(&mut self, _: &InlineAssist, cx: &mut ViewContext<Self>) {
pub fn inline_assist(&mut self, action: &InlineAssist, cx: &mut ViewContext<Self>) {
let Some(active_prompt_id) = self.active_prompt_id else {
cx.propagate();
return;
};
let prompt_editor = &self.prompt_editors[&active_prompt_id].body_editor;
let provider = CompletionProvider::global(cx);
if provider.is_authenticated() {
let provider = LanguageModelCompletionProvider::read_global(cx);
let initial_prompt = action.prompt.clone();
if provider.is_authenticated(cx) {
InlineAssistant::update_global(cx, |assistant, cx| {
assistant.assist(&prompt_editor, None, None, cx)
assistant.assist(&prompt_editor, None, None, initial_prompt, cx)
})
} else {
for window in cx.windows() {
@@ -731,29 +734,29 @@ impl PromptLibrary {
const DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
cx.background_executor().timer(DEBOUNCE_TIMEOUT).await;
let token_count = cx
.update(|cx| {
let provider = CompletionProvider::global(cx);
let model = provider.model();
provider.count_tokens(
LanguageModelRequest {
model,
messages: vec![LanguageModelRequestMessage {
role: Role::System,
content: body.to_string(),
}],
stop: Vec::new(),
temperature: 1.,
},
cx,
)
})?
.await?;
this.update(&mut cx, |this, cx| {
let prompt_editor = this.prompt_editors.get_mut(&prompt_id).unwrap();
prompt_editor.token_count = Some(token_count);
cx.notify();
})
if let Some(token_count) = cx.update(|cx| {
LanguageModelCompletionProvider::read_global(cx).count_tokens(
LanguageModelRequest {
messages: vec![LanguageModelRequestMessage {
role: Role::System,
content: body.to_string(),
}],
stop: Vec::new(),
temperature: 1.,
},
cx,
)
})? {
let token_count = token_count.await?;
this.update(&mut cx, |this, cx| {
let prompt_editor = this.prompt_editors.get_mut(&prompt_id).unwrap();
prompt_editor.token_count = Some(token_count);
cx.notify();
})
} else {
Ok(())
}
}
.log_err()
});
@@ -766,6 +769,7 @@ impl PromptLibrary {
.capture_action(cx.listener(Self::focus_active_prompt))
.bg(cx.theme().colors().panel_background)
.h_full()
.px_1()
.w_1_3()
.overflow_x_hidden()
.child(
@@ -802,7 +806,7 @@ impl PromptLibrary {
let prompt_metadata = self.store.metadata(prompt_id)?;
let prompt_editor = &self.prompt_editors[&prompt_id];
let focus_handle = prompt_editor.body_editor.focus_handle(cx);
let current_model = CompletionProvider::global(cx).model();
let current_model = LanguageModelCompletionProvider::read_global(cx).active_model();
let settings = ThemeSettings::get_global(cx);
Some(
@@ -913,7 +917,11 @@ impl PromptLibrary {
format!(
"Model: {}",
current_model
.display_name()
.as_ref()
.map(|model| model
.name()
.0)
.unwrap_or_default()
),
cx,
)
@@ -1295,6 +1303,17 @@ impl PromptStore {
fn first(&self) -> Option<PromptMetadata> {
self.metadata_cache.read().metadata.first().cloned()
}
pub fn operations_prompt(&self) -> String {
String::from_utf8(
Assets
.load("prompts/operations.md")
.unwrap()
.unwrap()
.to_vec(),
)
.unwrap()
}
}
/// Wraps a shared future to a prompt store so it can be assigned as a context global.

View File

@@ -1,171 +0,0 @@
use language::Rope;
use std::ops::Range;
/// Search the given buffer for the given substring, ignoring any differences
/// in line indentation between the query and the buffer.
///
/// Returns a vector of ranges of byte offsets in the buffer corresponding
/// to the entire lines of the buffer.
pub fn fuzzy_search_lines(haystack: &Rope, needle: &str) -> Option<Range<usize>> {
const SIMILARITY_THRESHOLD: f64 = 0.8;
let mut best_match: Option<(Range<usize>, f64)> = None; // (range, score)
let mut haystack_lines = haystack.chunks().lines();
let mut haystack_line_start = 0;
while let Some(mut haystack_line) = haystack_lines.next() {
let next_haystack_line_start = haystack_line_start + haystack_line.len() + 1;
let mut advanced_to_next_haystack_line = false;
let mut matched = true;
let match_start = haystack_line_start;
let mut match_end = next_haystack_line_start;
let mut match_score = 0.0;
let mut needle_lines = needle.lines().peekable();
while let Some(needle_line) = needle_lines.next() {
let similarity = line_similarity(haystack_line, needle_line);
if similarity >= SIMILARITY_THRESHOLD {
match_end = haystack_lines.offset();
match_score += similarity;
if needle_lines.peek().is_some() {
if let Some(next_haystack_line) = haystack_lines.next() {
advanced_to_next_haystack_line = true;
haystack_line = next_haystack_line;
} else {
matched = false;
break;
}
} else {
break;
}
} else {
matched = false;
break;
}
}
if matched
&& best_match
.as_ref()
.map(|(_, best_score)| match_score > *best_score)
.unwrap_or(true)
{
best_match = Some((match_start..match_end, match_score));
}
if advanced_to_next_haystack_line {
haystack_lines.seek(next_haystack_line_start);
}
haystack_line_start = next_haystack_line_start;
}
best_match.map(|(range, _)| range)
}
/// Calculates the similarity between two lines, ignoring leading and trailing whitespace,
/// using the Jaro-Winkler distance.
///
/// Returns a value between 0.0 and 1.0, where 1.0 indicates an exact match.
fn line_similarity(line1: &str, line2: &str) -> f64 {
strsim::jaro_winkler(line1.trim(), line2.trim())
}
#[cfg(test)]
mod test {
use super::*;
use gpui::{AppContext, Context as _};
use language::Buffer;
use unindent::Unindent as _;
use util::test::marked_text_ranges;
#[gpui::test]
fn test_fuzzy_search_lines(cx: &mut AppContext) {
let (text, expected_ranges) = marked_text_ranges(
&r#"
fn main() {
if a() {
assert_eq!(
1 + 2,
does_not_match,
);
}
println!("hi");
assert_eq!(
1 + 2,
3,
); // this last line does not match
« assert_eq!(
1 + 2,
3,
);
»
« assert_eq!(
"something",
"else",
);
»
}
"#
.unindent(),
false,
);
let buffer = cx.new_model(|cx| Buffer::local(&text, cx));
let snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
let actual_range = fuzzy_search_lines(
snapshot.as_rope(),
&"
assert_eq!(
1 + 2,
3,
);
"
.unindent(),
)
.unwrap();
assert_eq!(actual_range, expected_ranges[0]);
let actual_range = fuzzy_search_lines(
snapshot.as_rope(),
&"
assert_eq!(
1 + 2,
3,
);
"
.unindent(),
)
.unwrap();
assert_eq!(actual_range, expected_ranges[0]);
let actual_range = fuzzy_search_lines(
snapshot.as_rope(),
&"
asst_eq!(
\"something\",
\"els\"
)
"
.unindent(),
)
.unwrap();
assert_eq!(actual_range, expected_ranges[1]);
let actual_range = fuzzy_search_lines(
snapshot.as_rope(),
&"
assert_eq!(
2 + 1,
3,
);
"
.unindent(),
);
assert_eq!(actual_range, None);
}
}

View File

@@ -27,6 +27,7 @@ pub mod now_command;
pub mod project_command;
pub mod prompt_command;
pub mod search_command;
pub mod symbols_command;
pub mod tabs_command;
pub mod term_command;

View File

@@ -33,7 +33,7 @@ impl DiagnosticsSlashCommand {
if query.is_empty() {
let workspace = workspace.read(cx);
let entries = workspace.recent_navigation_history(Some(10), cx);
let path_prefix: Arc<str> = "".into();
let path_prefix: Arc<str> = Arc::default();
Task::ready(
entries
.into_iter()
@@ -284,7 +284,7 @@ fn collect_diagnostics(
PathBuf::try_from(path)
.ok()
.and_then(|path| {
project.read(cx).worktrees().find_map(|worktree| {
project.read(cx).worktrees(cx).find_map(|worktree| {
let worktree = worktree.read(cx);
let worktree_root_path = Path::new(worktree.root_name());
let relative_path = path.strip_prefix(worktree_root_path).ok()?;

View File

@@ -1,14 +1,16 @@
use std::path::Path;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::Duration;
use anyhow::{anyhow, bail, Result};
use assistant_slash_command::{
ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
};
use gpui::{AppContext, Model, Task, WeakView};
use gpui::{AppContext, BackgroundExecutor, Model, Task, WeakView};
use indexed_docs::{
IndexedDocsRegistry, IndexedDocsStore, LocalProvider, PackageName, ProviderId, RustdocIndexer,
DocsDotRsProvider, IndexedDocsRegistry, IndexedDocsStore, LocalRustdocProvider, PackageName,
ProviderId,
};
use language::LspAdapterDelegate;
use project::{Project, ProjectPath};
@@ -22,7 +24,7 @@ impl DocsSlashCommand {
pub const NAME: &'static str = "docs";
fn path_to_cargo_toml(project: Model<Project>, cx: &mut AppContext) -> Option<Arc<Path>> {
let worktree = project.read(cx).worktrees().next()?;
let worktree = project.read(cx).worktrees(cx).next()?;
let worktree = worktree.read(cx);
let entry = worktree.entry_for_path("Cargo.toml")?;
let path = ProjectPath {
@@ -34,22 +36,22 @@ impl DocsSlashCommand {
))
}
/// Ensures that the rustdoc provider is registered.
/// Ensures that the indexed doc providers for Rust are registered.
///
/// Ideally we would do this sooner, but we need to wait until we're able to
/// access the workspace so we can read the project.
fn ensure_rustdoc_provider_is_registered(
fn ensure_rust_doc_providers_are_registered(
&self,
workspace: Option<WeakView<Workspace>>,
cx: &mut AppContext,
) {
let indexed_docs_registry = IndexedDocsRegistry::global(cx);
if indexed_docs_registry
.get_provider_store(ProviderId::rustdoc())
.get_provider_store(LocalRustdocProvider::id())
.is_none()
{
let index_provider_deps = maybe!({
let workspace = workspace.ok_or_else(|| anyhow!("no workspace"))?;
let workspace = workspace.clone().ok_or_else(|| anyhow!("no workspace"))?;
let workspace = workspace
.upgrade()
.ok_or_else(|| anyhow!("workspace was dropped"))?;
@@ -63,11 +65,80 @@ impl DocsSlashCommand {
});
if let Some((fs, cargo_workspace_root)) = index_provider_deps.log_err() {
indexed_docs_registry.register_provider(Box::new(RustdocIndexer::new(Box::new(
LocalProvider::new(fs, cargo_workspace_root),
))));
indexed_docs_registry.register_provider(Box::new(LocalRustdocProvider::new(
fs,
cargo_workspace_root,
)));
}
}
if indexed_docs_registry
.get_provider_store(DocsDotRsProvider::id())
.is_none()
{
let http_client = maybe!({
let workspace = workspace.ok_or_else(|| anyhow!("no workspace"))?;
let workspace = workspace
.upgrade()
.ok_or_else(|| anyhow!("workspace was dropped"))?;
let project = workspace.read(cx).project().clone();
anyhow::Ok(project.read(cx).client().http_client().clone())
});
if let Some(http_client) = http_client.log_err() {
indexed_docs_registry
.register_provider(Box::new(DocsDotRsProvider::new(http_client)));
}
}
}
/// Runs just-in-time indexing for a given package, in case the slash command
/// is run without any entries existing in the index.
fn run_just_in_time_indexing(
store: Arc<IndexedDocsStore>,
key: String,
package: PackageName,
executor: BackgroundExecutor,
) -> Task<()> {
executor.clone().spawn(async move {
let (prefix, needs_full_index) = if let Some((prefix, _)) = key.split_once('*') {
// If we have a wildcard in the search, we want to wait until
// we've completely finished indexing so we get a full set of
// results for the wildcard.
(prefix.to_string(), true)
} else {
(key, false)
};
// If we already have some entries, we assume that we've indexed the package before
// and don't need to do it again.
let has_any_entries = store
.any_with_prefix(prefix.clone())
.await
.unwrap_or_default();
if has_any_entries {
return ();
};
let index_task = store.clone().index(package.clone());
if needs_full_index {
_ = index_task.await;
} else {
loop {
executor.timer(Duration::from_millis(200)).await;
if store
.any_with_prefix(prefix.clone())
.await
.unwrap_or_default()
|| !store.is_indexing(&package)
{
break;
}
}
}
})
}
}
@@ -95,7 +166,7 @@ impl SlashCommand for DocsSlashCommand {
workspace: Option<WeakView<Workspace>>,
cx: &mut AppContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
self.ensure_rustdoc_provider_is_registered(workspace, cx);
self.ensure_rust_doc_providers_are_registered(workspace, cx);
let indexed_docs_registry = IndexedDocsRegistry::global(cx);
let args = DocsSlashCommandArgs::parse(&query);
@@ -121,6 +192,14 @@ impl SlashCommand for DocsSlashCommand {
match args {
DocsSlashCommandArgs::NoProvider => {
let providers = indexed_docs_registry.list_providers();
if providers.is_empty() {
return Ok(vec![ArgumentCompletion {
label: "No available docs providers.".to_string(),
new_text: String::new(),
run_command: false,
}]);
}
Ok(providers
.into_iter()
.map(|provider| ArgumentCompletion {
@@ -140,7 +219,7 @@ impl SlashCommand for DocsSlashCommand {
if index {
// We don't need to hold onto this task, as the `IndexedDocsStore` will hold it
// until it completes.
let _ = store.clone().index(package.as_str().into());
drop(store.clone().index(package.as_str().into()));
}
let items = store.search(package).await;
@@ -171,46 +250,72 @@ impl SlashCommand for DocsSlashCommand {
};
let args = DocsSlashCommandArgs::parse(argument);
let text = cx.background_executor().spawn({
let executor = cx.background_executor().clone();
let task = cx.background_executor().spawn({
let store = args
.provider()
.ok_or_else(|| anyhow!("no docs provider specified"))
.and_then(|provider| IndexedDocsStore::try_global(provider, cx));
async move {
match args {
let (provider, key) = match args.clone() {
DocsSlashCommandArgs::NoProvider => bail!("no docs provider specified"),
DocsSlashCommandArgs::SearchPackageDocs {
provider, package, ..
} => {
let store = store?;
let item_docs = store.load(package.clone()).await?;
anyhow::Ok((provider, package, item_docs.to_string()))
}
} => (provider, package),
DocsSlashCommandArgs::SearchItemDocs {
provider,
item_path,
..
} => {
let store = store?;
let item_docs = store.load(item_path.clone()).await?;
} => (provider, item_path),
};
anyhow::Ok((provider, item_path, item_docs.to_string()))
}
let store = store?;
if let Some(package) = args.package() {
Self::run_just_in_time_indexing(store.clone(), key.clone(), package, executor)
.await;
}
let (text, ranges) = if let Some((prefix, _)) = key.split_once('*') {
let docs = store.load_many_by_prefix(prefix.to_string()).await?;
let mut text = String::new();
let mut ranges = Vec::new();
for (key, docs) in docs {
let prev_len = text.len();
text.push_str(&docs.0);
text.push_str("\n");
ranges.push((key, prev_len..text.len()));
text.push_str("\n");
}
(text, ranges)
} else {
let item_docs = store.load(key.clone()).await?;
let text = item_docs.to_string();
let range = 0..text.len();
(text, vec![(key, range)])
};
anyhow::Ok((provider, text, ranges))
}
});
cx.foreground_executor().spawn(async move {
let (provider, path, text) = text.await?;
let range = 0..text.len();
let (provider, text, ranges) = task.await?;
Ok(SlashCommandOutput {
text,
sections: vec![SlashCommandOutputSection {
range,
icon: IconName::FileRust,
label: format!("docs ({provider}): {path}",).into(),
}],
sections: ranges
.into_iter()
.map(|(key, range)| SlashCommandOutputSection {
range,
icon: IconName::FileDoc,
label: format!("docs ({provider}): {key}",).into(),
})
.collect(),
run_commands_in_text: false,
})
})
@@ -221,7 +326,7 @@ fn is_item_path_delimiter(char: char) -> bool {
!char.is_alphanumeric() && char != '-' && char != '_'
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub(crate) enum DocsSlashCommandArgs {
NoProvider,
SearchPackageDocs {

View File

@@ -10,7 +10,7 @@ use assistant_slash_command::{
use futures::AsyncReadExt;
use gpui::{AppContext, Task, WeakView};
use html_to_markdown::{convert_html_to_markdown, markdown, TagHandler};
use http::{AsyncBody, HttpClient, HttpClientWithUrl};
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
use language::LspAdapterDelegate;
use ui::prelude::*;
use workspace::Workspace;
@@ -27,7 +27,7 @@ pub(crate) struct FetchSlashCommand;
impl FetchSlashCommand {
async fn build_message(http_client: Arc<HttpClientWithUrl>, url: &str) -> Result<String> {
let mut url = url.to_owned();
if !url.starts_with("https://") {
if !url.starts_with("https://") && !url.starts_with("http://") {
url = format!("https://{url}");
}

View File

@@ -29,7 +29,7 @@ impl FileSlashCommand {
let workspace = workspace.read(cx);
let project = workspace.project().read(cx);
let entries = workspace.recent_navigation_history(Some(10), cx);
let path_prefix: Arc<str> = "".into();
let path_prefix: Arc<str> = Arc::default();
Task::ready(
entries
.into_iter()
@@ -188,7 +188,7 @@ fn collect_files(
let project_handle = project.downgrade();
let snapshots = project
.read(cx)
.worktrees()
.worktrees(cx)
.map(|worktree| worktree.read(cx).snapshot())
.collect::<Vec<_>>();
cx.spawn(|mut cx| async move {

View File

@@ -23,7 +23,7 @@ impl SlashCommand for NowSlashCommand {
}
fn menu_text(&self) -> String {
"Insert current date and time".into()
"Insert Current Date and Time".into()
}
fn requires_argument(&self) -> bool {

View File

@@ -75,7 +75,7 @@ impl ProjectSlashCommand {
}
fn path_to_cargo_toml(project: Model<Project>, cx: &mut AppContext) -> Option<Arc<Path>> {
let worktree = project.read(cx).worktrees().next()?;
let worktree = project.read(cx).worktrees(cx).next()?;
let worktree = worktree.read(cx);
let entry = worktree.entry_for_path("Cargo.toml")?;
let path = ProjectPath {

View File

@@ -0,0 +1,89 @@
use super::{SlashCommand, SlashCommandOutput};
use anyhow::{anyhow, Context as _, Result};
use assistant_slash_command::{ArgumentCompletion, SlashCommandOutputSection};
use editor::Editor;
use gpui::{AppContext, Task, WeakView};
use language::LspAdapterDelegate;
use std::sync::Arc;
use std::{path::Path, sync::atomic::AtomicBool};
use ui::{IconName, WindowContext};
use workspace::Workspace;
pub(crate) struct OutlineSlashCommand;
impl SlashCommand for OutlineSlashCommand {
fn name(&self) -> String {
"symbols".into()
}
fn description(&self) -> String {
"insert symbols for active tab".into()
}
fn menu_text(&self) -> String {
"Insert Symbols for Active Tab".into()
}
fn complete_argument(
self: Arc<Self>,
_query: String,
_cancel: Arc<AtomicBool>,
_workspace: Option<WeakView<Workspace>>,
_cx: &mut AppContext,
) -> Task<Result<Vec<ArgumentCompletion>>> {
Task::ready(Err(anyhow!("this command does not require argument")))
}
fn requires_argument(&self) -> bool {
false
}
fn run(
self: Arc<Self>,
_argument: Option<&str>,
workspace: WeakView<Workspace>,
_delegate: Arc<dyn LspAdapterDelegate>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let output = workspace.update(cx, |workspace, cx| {
let Some(active_item) = workspace.active_item(cx) else {
return Task::ready(Err(anyhow!("no active tab")));
};
let Some(buffer) = active_item
.downcast::<Editor>()
.and_then(|editor| editor.read(cx).buffer().read(cx).as_singleton())
else {
return Task::ready(Err(anyhow!("active tab is not an editor")));
};
let snapshot = buffer.read(cx).snapshot();
let path = snapshot.resolve_file_path(cx, true);
cx.background_executor().spawn(async move {
let outline = snapshot
.outline(None)
.context("no symbols for active tab")?;
let path = path.as_deref().unwrap_or(Path::new("untitled"));
let mut outline_text = format!("Symbols for {}:\n", path.display());
for item in &outline.path_candidates {
outline_text.push_str("- ");
outline_text.push_str(&item.string);
outline_text.push('\n');
}
Ok(SlashCommandOutput {
sections: vec![SlashCommandOutputSection {
range: 0..outline_text.len(),
icon: IconName::ListTree,
label: path.to_string_lossy().to_string().into(),
}],
text: outline_text,
run_commands_in_text: false,
})
})
});
output.unwrap_or_else(|error| Task::ready(Err(error)))
}
}

View File

@@ -31,7 +31,7 @@ impl SlashCommand for TermSlashCommand {
}
fn menu_text(&self) -> String {
"Insert terminal output".into()
"Insert Terminal Output".into()
}
fn requires_argument(&self) -> bool {

View File

@@ -1,7 +1,6 @@
use crate::{
assistant_settings::AssistantSettings, humanize_token_count,
prompts::generate_terminal_assistant_prompt, AssistantPanel, AssistantPanelEvent,
CompletionProvider, LanguageModelRequest, LanguageModelRequestMessage, Role,
humanize_token_count, prompts::generate_terminal_assistant_prompt, AssistantPanel,
AssistantPanelEvent, LanguageModelCompletionProvider, ModelSelector,
};
use anyhow::{Context as _, Result};
use client::telemetry::Telemetry;
@@ -13,11 +12,12 @@ use editor::{
use fs::Fs;
use futures::{channel::mpsc, SinkExt, StreamExt};
use gpui::{
AppContext, Context, EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight, Global,
Model, ModelContext, Subscription, Task, TextStyle, UpdateGlobal, View, WeakView, WhiteSpace,
AppContext, Context, EventEmitter, FocusHandle, FocusableView, Global, Model, ModelContext,
Subscription, Task, TextStyle, UpdateGlobal, View, WeakView,
};
use language::Buffer;
use settings::{update_settings_file, Settings};
use language_model::{LanguageModelRequest, LanguageModelRequestMessage, Role};
use settings::Settings;
use std::{
cmp,
sync::Arc,
@@ -26,7 +26,7 @@ use std::{
use terminal::Terminal;
use terminal_view::TerminalView;
use theme::ThemeSettings;
use ui::{prelude::*, ContextMenu, PopoverMenu, Tooltip};
use ui::{prelude::*, IconButtonShape, Tooltip};
use util::ResultExt;
use workspace::{notifications::NotificationId, Toast, Workspace};
@@ -73,11 +73,13 @@ impl TerminalInlineAssistant {
terminal_view: &View<TerminalView>,
workspace: Option<WeakView<Workspace>>,
assistant_panel: Option<&View<AssistantPanel>>,
initial_prompt: Option<String>,
cx: &mut WindowContext,
) {
let terminal = terminal_view.read(cx).terminal().clone();
let assist_id = self.next_assist_id.post_inc();
let prompt_buffer = cx.new_model(|cx| Buffer::local("", cx));
let prompt_buffer =
cx.new_model(|cx| Buffer::local(initial_prompt.unwrap_or_default(), cx));
let prompt_buffer = cx.new_model(|cx| MultiBuffer::singleton(prompt_buffer, cx));
let codegen = cx.new_model(|_| Codegen::new(terminal, self.telemetry.clone()));
@@ -212,8 +214,6 @@ impl TerminalInlineAssistant {
) -> Result<LanguageModelRequest> {
let assist = self.assists.get(&assist_id).context("invalid assist")?;
let model = CompletionProvider::global(cx).model();
let shell = std::env::var("SHELL").ok();
let working_directory = assist
.terminal
@@ -265,7 +265,6 @@ impl TerminalInlineAssistant {
});
Ok(LanguageModelRequest {
model,
messages,
stop: Vec::new(),
temperature: 1.0,
@@ -448,22 +447,19 @@ impl EventEmitter<PromptEditorEvent> for PromptEditor {}
impl Render for PromptEditor {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let fs = self.fs.clone();
let buttons = match &self.codegen.read(cx).status {
CodegenStatus::Idle => {
vec![
IconButton::new("cancel", IconName::Close)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::for_action("Cancel Assist", &menu::Cancel, cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)),
),
IconButton::new("start", IconName::Sparkle)
IconButton::new("start", IconName::SparkleAlt)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.icon_size(IconSize::XSmall)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::for_action("Generate", &menu::Confirm, cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::StartRequested)),
@@ -474,15 +470,14 @@ impl Render for PromptEditor {
vec![
IconButton::new("cancel", IconName::Close)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::text("Cancel Assist", cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)),
),
IconButton::new("stop", IconName::Stop)
.icon_color(Color::Error)
.size(ButtonSize::None)
.icon_size(IconSize::XSmall)
.shape(IconButtonShape::Square)
.tooltip(|cx| {
Tooltip::with_meta(
"Interrupt Generation",
@@ -500,7 +495,7 @@ impl Render for PromptEditor {
vec![
IconButton::new("cancel", IconName::Close)
.icon_color(Color::Muted)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| Tooltip::for_action("Cancel Assist", &menu::Cancel, cx))
.on_click(
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)),
@@ -508,8 +503,7 @@ impl Render for PromptEditor {
if self.edited_since_done {
IconButton::new("restart", IconName::RotateCw)
.icon_color(Color::Info)
.icon_size(IconSize::XSmall)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| {
Tooltip::with_meta(
"Restart Generation",
@@ -524,7 +518,7 @@ impl Render for PromptEditor {
} else {
IconButton::new("confirm", IconName::Play)
.icon_color(Color::Info)
.size(ButtonSize::None)
.shape(IconButtonShape::Square)
.tooltip(|cx| {
Tooltip::for_action("Execute generated command", &menu::Confirm, cx)
})
@@ -552,59 +546,27 @@ impl Render for PromptEditor {
.w_12()
.justify_center()
.gap_2()
.child(
PopoverMenu::new("model-switcher")
.menu(move |cx| {
ContextMenu::build(cx, |mut menu, cx| {
for model in CompletionProvider::global(cx).available_models(cx)
{
menu = menu.custom_entry(
{
let model = model.clone();
move |_| {
Label::new(model.display_name())
.into_any_element()
}
},
{
let fs = fs.clone();
let model = model.clone();
move |cx| {
let model = model.clone();
update_settings_file::<AssistantSettings>(
fs.clone(),
cx,
move |settings| settings.set_model(model),
);
}
},
);
}
menu
})
.into()
})
.trigger(
IconButton::new("context", IconName::Settings)
.size(ButtonSize::None)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
.tooltip(move |cx| {
Tooltip::with_meta(
format!(
"Using {}",
CompletionProvider::global(cx)
.model()
.display_name()
),
None,
"Click to Change Model",
cx,
)
}),
)
.anchor(gpui::AnchorCorner::BottomRight),
)
.child(ModelSelector::new(
self.fs.clone(),
IconButton::new("context", IconName::Settings)
.shape(IconButtonShape::Square)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
.tooltip(move |cx| {
Tooltip::with_meta(
format!(
"Using {}",
LanguageModelCompletionProvider::read_global(cx)
.active_model()
.map(|model| model.name().0)
.unwrap_or_else(|| "No model selected".into()),
),
None,
"Change Model",
cx,
)
}),
))
.children(
if let CodegenStatus::Error(error) = &self.codegen.read(cx).status {
let error_message = SharedString::from(error.to_string());
@@ -745,13 +707,18 @@ impl PromptEditor {
inline_assistant.request_for_inline_assist(assist_id, cx)
})??;
let token_count = cx
.update(|cx| CompletionProvider::global(cx).count_tokens(request, cx))?
.await?;
this.update(&mut cx, |this, cx| {
this.token_count = Some(token_count);
cx.notify();
})
if let Some(token_count) = cx.update(|cx| {
LanguageModelCompletionProvider::read_global(cx).count_tokens(request, cx)
})? {
let token_count = token_count.await?;
this.update(&mut cx, |this, cx| {
this.token_count = Some(token_count);
cx.notify();
})
} else {
Ok(())
}
})
}
@@ -876,7 +843,7 @@ impl PromptEditor {
}
fn render_token_count(&self, cx: &mut ViewContext<Self>) -> Option<impl IntoElement> {
let model = CompletionProvider::global(cx).model();
let model = LanguageModelCompletionProvider::read_global(cx).active_model()?;
let token_count = self.token_count?;
let max_token_count = model.max_token_count();
@@ -942,14 +909,11 @@ impl PromptEditor {
},
font_family: settings.ui_font.family.clone(),
font_features: settings.ui_font.features.clone(),
font_fallbacks: settings.ui_font.fallbacks.clone(),
font_size: rems(0.875).into(),
font_weight: FontWeight::NORMAL,
font_style: FontStyle::Normal,
font_weight: settings.ui_font.weight,
line_height: relative(1.3),
background_color: None,
underline: None,
strikethrough: None,
white_space: WhiteSpace::Normal,
..Default::default()
};
EditorElement::new(
&self.editor,
@@ -983,7 +947,7 @@ impl TerminalTransaction {
}
pub fn push(&mut self, hunk: String, cx: &mut AppContext) {
// Ensure that the assistant cannot accidently execute commands that are streamed into the terminal
// Ensure that the assistant cannot accidentally execute commands that are streamed into the terminal
let input = hunk.replace(CARRIAGE_RETURN, " ");
self.terminal
.update(cx, |terminal, _| terminal.input(input));
@@ -1025,8 +989,12 @@ impl Codegen {
self.transaction = Some(TerminalTransaction::start(self.terminal.clone()));
let telemetry = self.telemetry.clone();
let model_telemetry_id = prompt.model.telemetry_id();
let response = CompletionProvider::global(cx).complete(prompt, cx);
let model_telemetry_id = LanguageModelCompletionProvider::read_global(cx)
.active_model()
.map(|m| m.telemetry_id())
.unwrap_or_default();
let response =
LanguageModelCompletionProvider::read_global(cx).stream_completion(prompt, cx);
self.generation = cx.spawn(|this, mut cx| async move {
let response = response.await;
@@ -1037,8 +1005,8 @@ impl Codegen {
let mut response_latency = None;
let request_start = Instant::now();
let task = async {
let mut response = response.inner.await?;
while let Some(chunk) = response.next().await {
let mut chunks = response?;
while let Some(chunk) = chunks.next().await {
if response_latency.is_none() {
response_latency = Some(request_start.elapsed());
}

View File

@@ -1,85 +0,0 @@
# Assistant Tooling
Bringing Language Model tool calling to GPUI.
This unlocks:
- **Structured Extraction** of model responses
- **Validation** of model inputs
- **Execution** of chosen tools
## Overview
Language Models can produce structured outputs that are perfect for calling functions. The most famous of these is OpenAI's tool calling. When making a chat completion you can pass a list of tools available to the model. The model will choose `0..n` tools to help them complete a user's task. It's up to _you_ to create the tools that the model can call.
> **User**: "Hey I need help with implementing a collapsible panel in GPUI"
>
> **Assistant**: "Sure, I can help with that. Let me see what I can find."
>
> `tool_calls: ["name": "query_codebase", arguments: "{ 'query': 'GPUI collapsible panel' }"]`
>
> `result: "['crates/gpui/src/panel.rs:12: impl Panel { ... }', 'crates/gpui/src/panel.rs:20: impl Panel { ... }']"`
>
> **Assistant**: "Here are some excerpts from the GPUI codebase that might help you."
This library is designed to facilitate this interaction mode by allowing you to go from `struct` to `tool` with two simple traits, `LanguageModelTool` and `ToolView`.
## Using the Tool Registry
```rust
let mut tool_registry = ToolRegistry::new();
tool_registry
.register(WeatherTool { api_client },
})
.unwrap(); // You can only register one tool per name
let completion = cx.update(|cx| {
CompletionProvider::get(cx).complete(
model_name,
messages,
Vec::new(),
1.0,
// The definitions get passed directly to OpenAI when you want
// the model to be able to call your tool
tool_registry.definitions(),
)
});
let mut stream = completion?.await?;
let mut message = AssistantMessage::new();
while let Some(delta) = stream.next().await {
// As messages stream in, you'll get both assistant content
if let Some(content) = &delta.content {
message
.body
.update(cx, |message, cx| message.append(&content, cx));
}
// And tool calls!
for tool_call_delta in delta.tool_calls {
let index = tool_call_delta.index as usize;
if index >= message.tool_calls.len() {
message.tool_calls.resize_with(index + 1, Default::default);
}
let tool_call = &mut message.tool_calls[index];
// Build up an ID
if let Some(id) = &tool_call_delta.id {
tool_call.id.push_str(id);
}
tool_registry.update_tool_call(
tool_call,
tool_call_delta.name.as_deref(),
tool_call_delta.arguments.as_deref(),
cx,
);
}
}
```
Once the stream of tokens is complete, you can exexute the tool call by calling `tool_registry.execute_tool_call(tool_call, cx)`, which returns a `Task<Result<()>>`.
As the tokens stream in and tool calls are executed, your `ToolView` will get updates. Render each tool call by passing that `tool_call` in to `tool_registry.render_tool_call(tool_call, cx)`. The final message for the model can be pulled by calling `self.tool_registry.content_for_tool_call( tool_call, &mut project_context, cx, )`.

View File

@@ -1,13 +0,0 @@
mod attachment_registry;
mod project_context;
mod tool_registry;
pub use attachment_registry::{
AttachmentOutput, AttachmentRegistry, LanguageModelAttachment, SavedUserAttachment,
UserAttachment,
};
pub use project_context::ProjectContext;
pub use tool_registry::{
LanguageModelTool, SavedToolFunctionCall, ToolFunctionCall, ToolFunctionDefinition,
ToolRegistry, ToolView,
};

View File

@@ -1,234 +0,0 @@
use crate::ProjectContext;
use anyhow::{anyhow, Result};
use collections::HashMap;
use futures::future::join_all;
use gpui::{AnyView, Render, Task, View, WindowContext};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::value::RawValue;
use std::{
any::TypeId,
sync::{
atomic::{AtomicBool, Ordering::SeqCst},
Arc,
},
};
use util::ResultExt as _;
pub struct AttachmentRegistry {
registered_attachments: HashMap<TypeId, RegisteredAttachment>,
}
pub trait AttachmentOutput {
fn generate(&self, project: &mut ProjectContext, cx: &mut WindowContext) -> String;
}
pub trait LanguageModelAttachment {
type Output: DeserializeOwned + Serialize + 'static;
type View: Render + AttachmentOutput;
fn name(&self) -> Arc<str>;
fn run(&self, cx: &mut WindowContext) -> Task<Result<Self::Output>>;
fn view(&self, output: Result<Self::Output>, cx: &mut WindowContext) -> View<Self::View>;
}
/// A collected attachment from running an attachment tool
pub struct UserAttachment {
pub view: AnyView,
name: Arc<str>,
serialized_output: Result<Box<RawValue>, String>,
generate_fn: fn(AnyView, &mut ProjectContext, cx: &mut WindowContext) -> String,
}
#[derive(Serialize, Deserialize)]
pub struct SavedUserAttachment {
name: Arc<str>,
serialized_output: Result<Box<RawValue>, String>,
}
/// Internal representation of an attachment tool to allow us to treat them dynamically
struct RegisteredAttachment {
name: Arc<str>,
enabled: AtomicBool,
call: Box<dyn Fn(&mut WindowContext) -> Task<Result<UserAttachment>>>,
deserialize: Box<dyn Fn(&SavedUserAttachment, &mut WindowContext) -> Result<UserAttachment>>,
}
impl AttachmentRegistry {
pub fn new() -> Self {
Self {
registered_attachments: HashMap::default(),
}
}
pub fn register<A: LanguageModelAttachment + 'static>(&mut self, attachment: A) {
let attachment = Arc::new(attachment);
let call = Box::new({
let attachment = attachment.clone();
move |cx: &mut WindowContext| {
let result = attachment.run(cx);
let attachment = attachment.clone();
cx.spawn(move |mut cx| async move {
let result: Result<A::Output> = result.await;
let serialized_output =
result
.as_ref()
.map_err(ToString::to_string)
.and_then(|output| {
Ok(RawValue::from_string(
serde_json::to_string(output).map_err(|e| e.to_string())?,
)
.unwrap())
});
let view = cx.update(|cx| attachment.view(result, cx))?;
Ok(UserAttachment {
name: attachment.name(),
view: view.into(),
generate_fn: generate::<A>,
serialized_output,
})
})
}
});
let deserialize = Box::new({
let attachment = attachment.clone();
move |saved_attachment: &SavedUserAttachment, cx: &mut WindowContext| {
let serialized_output = saved_attachment.serialized_output.clone();
let output = match &serialized_output {
Ok(serialized_output) => {
Ok(serde_json::from_str::<A::Output>(serialized_output.get())?)
}
Err(error) => Err(anyhow!("{error}")),
};
let view = attachment.view(output, cx).into();
Ok(UserAttachment {
name: saved_attachment.name.clone(),
view,
serialized_output,
generate_fn: generate::<A>,
})
}
});
self.registered_attachments.insert(
TypeId::of::<A>(),
RegisteredAttachment {
name: attachment.name(),
call,
deserialize,
enabled: AtomicBool::new(true),
},
);
return;
fn generate<T: LanguageModelAttachment>(
view: AnyView,
project: &mut ProjectContext,
cx: &mut WindowContext,
) -> String {
view.downcast::<T::View>()
.unwrap()
.update(cx, |view, cx| T::View::generate(view, project, cx))
}
}
pub fn set_attachment_tool_enabled<A: LanguageModelAttachment + 'static>(
&self,
is_enabled: bool,
) {
if let Some(attachment) = self.registered_attachments.get(&TypeId::of::<A>()) {
attachment.enabled.store(is_enabled, SeqCst);
}
}
pub fn is_attachment_tool_enabled<A: LanguageModelAttachment + 'static>(&self) -> bool {
if let Some(attachment) = self.registered_attachments.get(&TypeId::of::<A>()) {
attachment.enabled.load(SeqCst)
} else {
false
}
}
pub fn call<A: LanguageModelAttachment + 'static>(
&self,
cx: &mut WindowContext,
) -> Task<Result<UserAttachment>> {
let Some(attachment) = self.registered_attachments.get(&TypeId::of::<A>()) else {
return Task::ready(Err(anyhow!("no attachment tool")));
};
(attachment.call)(cx)
}
pub fn call_all_attachment_tools(
self: Arc<Self>,
cx: &mut WindowContext<'_>,
) -> Task<Result<Vec<UserAttachment>>> {
let this = self.clone();
cx.spawn(|mut cx| async move {
let attachment_tasks = cx.update(|cx| {
let mut tasks = Vec::new();
for attachment in this
.registered_attachments
.values()
.filter(|attachment| attachment.enabled.load(SeqCst))
{
tasks.push((attachment.call)(cx))
}
tasks
})?;
let attachments = join_all(attachment_tasks.into_iter()).await;
Ok(attachments
.into_iter()
.filter_map(|attachment| attachment.log_err())
.collect())
})
}
pub fn serialize_user_attachment(
&self,
user_attachment: &UserAttachment,
) -> SavedUserAttachment {
SavedUserAttachment {
name: user_attachment.name.clone(),
serialized_output: user_attachment.serialized_output.clone(),
}
}
pub fn deserialize_user_attachment(
&self,
saved_user_attachment: SavedUserAttachment,
cx: &mut WindowContext,
) -> Result<UserAttachment> {
if let Some(registered_attachment) = self
.registered_attachments
.values()
.find(|attachment| attachment.name == saved_user_attachment.name)
{
(registered_attachment.deserialize)(&saved_user_attachment, cx)
} else {
Err(anyhow!(
"no attachment tool for name {}",
saved_user_attachment.name
))
}
}
}
impl UserAttachment {
pub fn generate(&self, output: &mut ProjectContext, cx: &mut WindowContext) -> Option<String> {
let result = (self.generate_fn)(self.view.clone(), output, cx);
if result.is_empty() {
None
} else {
Some(result)
}
}
}

View File

@@ -1,296 +0,0 @@
use anyhow::{anyhow, Result};
use gpui::{AppContext, Model, Task, WeakModel};
use project::{Fs, Project, ProjectPath, Worktree};
use std::{cmp::Ordering, fmt::Write as _, ops::Range, sync::Arc};
use sum_tree::TreeMap;
pub struct ProjectContext {
files: TreeMap<ProjectPath, PathState>,
project: WeakModel<Project>,
fs: Arc<dyn Fs>,
}
#[derive(Debug, Clone)]
enum PathState {
PathOnly,
EntireFile,
Excerpts { ranges: Vec<Range<usize>> },
}
impl ProjectContext {
pub fn new(project: WeakModel<Project>, fs: Arc<dyn Fs>) -> Self {
Self {
files: TreeMap::default(),
fs,
project,
}
}
pub fn add_path(&mut self, project_path: ProjectPath) {
if self.files.get(&project_path).is_none() {
self.files.insert(project_path, PathState::PathOnly);
}
}
pub fn add_excerpts(&mut self, project_path: ProjectPath, new_ranges: &[Range<usize>]) {
let previous_state = self
.files
.get(&project_path)
.unwrap_or(&PathState::PathOnly);
let mut ranges = match previous_state {
PathState::EntireFile => return,
PathState::PathOnly => Vec::new(),
PathState::Excerpts { ranges } => ranges.to_vec(),
};
for new_range in new_ranges {
let ix = ranges.binary_search_by(|probe| {
if probe.end < new_range.start {
Ordering::Less
} else if probe.start > new_range.end {
Ordering::Greater
} else {
Ordering::Equal
}
});
match ix {
Ok(mut ix) => {
let existing = &mut ranges[ix];
existing.start = existing.start.min(new_range.start);
existing.end = existing.end.max(new_range.end);
while ix + 1 < ranges.len() && ranges[ix + 1].start <= ranges[ix].end {
ranges[ix].end = ranges[ix].end.max(ranges[ix + 1].end);
ranges.remove(ix + 1);
}
while ix > 0 && ranges[ix - 1].end >= ranges[ix].start {
ranges[ix].start = ranges[ix].start.min(ranges[ix - 1].start);
ranges.remove(ix - 1);
ix -= 1;
}
}
Err(ix) => {
ranges.insert(ix, new_range.clone());
}
}
}
self.files
.insert(project_path, PathState::Excerpts { ranges });
}
pub fn add_file(&mut self, project_path: ProjectPath) {
self.files.insert(project_path, PathState::EntireFile);
}
pub fn generate_system_message(&self, cx: &mut AppContext) -> Task<Result<String>> {
let project = self
.project
.upgrade()
.ok_or_else(|| anyhow!("project dropped"));
let files = self.files.clone();
let fs = self.fs.clone();
cx.spawn(|cx| async move {
let project = project?;
let mut result = "project structure:\n".to_string();
let mut last_worktree: Option<Model<Worktree>> = None;
for (project_path, path_state) in files.iter() {
if let Some(worktree) = &last_worktree {
if worktree.read_with(&cx, |tree, _| tree.id())? != project_path.worktree_id {
last_worktree = None;
}
}
let worktree;
if let Some(last_worktree) = &last_worktree {
worktree = last_worktree.clone();
} else if let Some(tree) = project.read_with(&cx, |project, cx| {
project.worktree_for_id(project_path.worktree_id, cx)
})? {
worktree = tree;
last_worktree = Some(worktree.clone());
let worktree_name =
worktree.read_with(&cx, |tree, _cx| tree.root_name().to_string())?;
writeln!(&mut result, "# {}", worktree_name).unwrap();
} else {
continue;
}
let worktree_abs_path = worktree.read_with(&cx, |tree, _cx| tree.abs_path())?;
let path = &project_path.path;
writeln!(&mut result, "## {}", path.display()).unwrap();
match path_state {
PathState::PathOnly => {}
PathState::EntireFile => {
let text = fs.load(&worktree_abs_path.join(&path)).await?;
writeln!(&mut result, "~~~\n{text}\n~~~").unwrap();
}
PathState::Excerpts { ranges } => {
let text = fs.load(&worktree_abs_path.join(&path)).await?;
writeln!(&mut result, "~~~").unwrap();
// Assumption: ranges are in order, not overlapping
let mut prev_range_end = 0;
for range in ranges {
if range.start > prev_range_end {
writeln!(&mut result, "...").unwrap();
prev_range_end = range.end;
}
let mut start = range.start;
let mut end = range.end.min(text.len());
while !text.is_char_boundary(start) {
start += 1;
}
while !text.is_char_boundary(end) {
end -= 1;
}
result.push_str(&text[start..end]);
if !result.ends_with('\n') {
result.push('\n');
}
}
if prev_range_end < text.len() {
writeln!(&mut result, "...").unwrap();
}
writeln!(&mut result, "~~~").unwrap();
}
}
}
Ok(result)
})
}
}
#[cfg(test)]
mod tests {
use std::path::Path;
use super::*;
use gpui::TestAppContext;
use project::FakeFs;
use serde_json::json;
use settings::SettingsStore;
use unindent::Unindent as _;
#[gpui::test]
async fn test_system_message_generation(cx: &mut TestAppContext) {
init_test(cx);
let file_3_contents = r#"
fn test1() {}
fn test2() {}
fn test3() {}
"#
.unindent();
let fs = FakeFs::new(cx.executor());
fs.insert_tree(
"/code",
json!({
"root1": {
"lib": {
"file1.rs": "mod example;",
"file2.rs": "",
},
"test": {
"file3.rs": file_3_contents,
}
},
"root2": {
"src": {
"main.rs": ""
}
}
}),
)
.await;
let project = Project::test(
fs.clone(),
["/code/root1".as_ref(), "/code/root2".as_ref()],
cx,
)
.await;
let worktree_ids = project.read_with(cx, |project, cx| {
project
.worktrees()
.map(|worktree| worktree.read(cx).id())
.collect::<Vec<_>>()
});
let mut ax = ProjectContext::new(project.downgrade(), fs);
ax.add_file(ProjectPath {
worktree_id: worktree_ids[0],
path: Path::new("lib/file1.rs").into(),
});
let message = cx
.update(|cx| ax.generate_system_message(cx))
.await
.unwrap();
assert_eq!(
r#"
project structure:
# root1
## lib/file1.rs
~~~
mod example;
~~~
"#
.unindent(),
message
);
ax.add_excerpts(
ProjectPath {
worktree_id: worktree_ids[0],
path: Path::new("test/file3.rs").into(),
},
&[
file_3_contents.find("fn test2").unwrap()
..file_3_contents.find("fn test3").unwrap(),
],
);
let message = cx
.update(|cx| ax.generate_system_message(cx))
.await
.unwrap();
assert_eq!(
r#"
project structure:
# root1
## lib/file1.rs
~~~
mod example;
~~~
## test/file3.rs
~~~
...
fn test2() {}
...
~~~
"#
.unindent(),
message
);
}
fn init_test(cx: &mut TestAppContext) {
cx.update(|cx| {
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
Project::init_settings(cx);
});
}
}

View File

@@ -1,526 +0,0 @@
use crate::ProjectContext;
use anyhow::{anyhow, Result};
use gpui::{AnyElement, AnyView, IntoElement, Render, Task, View, WindowContext};
use repair_json::repair;
use schemars::{schema::RootSchema, schema_for, JsonSchema};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::value::RawValue;
use std::{
any::TypeId,
collections::HashMap,
fmt::Display,
mem,
sync::atomic::{AtomicBool, Ordering::SeqCst},
};
use ui::ViewContext;
pub struct ToolRegistry {
registered_tools: HashMap<String, RegisteredTool>,
}
#[derive(Default)]
pub struct ToolFunctionCall {
pub id: String,
pub name: String,
pub arguments: String,
state: ToolFunctionCallState,
}
#[derive(Default)]
enum ToolFunctionCallState {
#[default]
Initializing,
NoSuchTool,
KnownTool(Box<dyn InternalToolView>),
ExecutedTool(Box<dyn InternalToolView>),
}
trait InternalToolView {
fn view(&self) -> AnyView;
fn generate(&self, project: &mut ProjectContext, cx: &mut WindowContext) -> String;
fn try_set_input(&self, input: &str, cx: &mut WindowContext);
fn execute(&self, cx: &mut WindowContext) -> Task<Result<()>>;
fn serialize_output(&self, cx: &mut WindowContext) -> Result<Box<RawValue>>;
fn deserialize_output(&self, raw_value: &RawValue, cx: &mut WindowContext) -> Result<()>;
}
#[derive(Default, Serialize, Deserialize)]
pub struct SavedToolFunctionCall {
id: String,
name: String,
arguments: String,
state: SavedToolFunctionCallState,
}
#[derive(Default, Serialize, Deserialize)]
enum SavedToolFunctionCallState {
#[default]
Initializing,
NoSuchTool,
KnownTool,
ExecutedTool(Box<RawValue>),
}
#[derive(Clone, Debug, PartialEq)]
pub struct ToolFunctionDefinition {
pub name: String,
pub description: String,
pub parameters: RootSchema,
}
pub trait LanguageModelTool {
type View: ToolView;
/// Returns the name of the tool.
///
/// This name is exposed to the language model to allow the model to pick
/// which tools to use. As this name is used to identify the tool within a
/// tool registry, it should be unique.
fn name(&self) -> String;
/// Returns the description of the tool.
///
/// This can be used to _prompt_ the model as to what the tool does.
fn description(&self) -> String;
/// Returns the OpenAI Function definition for the tool, for direct use with OpenAI's API.
fn definition(&self) -> ToolFunctionDefinition {
let root_schema = schema_for!(<Self::View as ToolView>::Input);
ToolFunctionDefinition {
name: self.name(),
description: self.description(),
parameters: root_schema,
}
}
/// A view of the output of running the tool, for displaying to the user.
fn view(&self, cx: &mut WindowContext) -> View<Self::View>;
}
pub trait ToolView: Render {
/// The input type that will be passed in to `execute` when the tool is called
/// by the language model.
type Input: DeserializeOwned + JsonSchema;
/// The output returned by executing the tool.
type SerializedState: DeserializeOwned + Serialize;
fn generate(&self, project: &mut ProjectContext, cx: &mut ViewContext<Self>) -> String;
fn set_input(&mut self, input: Self::Input, cx: &mut ViewContext<Self>);
fn execute(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>>;
fn serialize(&self, cx: &mut ViewContext<Self>) -> Self::SerializedState;
fn deserialize(
&mut self,
output: Self::SerializedState,
cx: &mut ViewContext<Self>,
) -> Result<()>;
}
struct RegisteredTool {
enabled: AtomicBool,
type_id: TypeId,
build_view: Box<dyn Fn(&mut WindowContext) -> Box<dyn InternalToolView>>,
definition: ToolFunctionDefinition,
}
impl ToolRegistry {
pub fn new() -> Self {
Self {
registered_tools: HashMap::new(),
}
}
pub fn set_tool_enabled<T: 'static + LanguageModelTool>(&self, is_enabled: bool) {
for tool in self.registered_tools.values() {
if tool.type_id == TypeId::of::<T>() {
tool.enabled.store(is_enabled, SeqCst);
return;
}
}
}
pub fn is_tool_enabled<T: 'static + LanguageModelTool>(&self) -> bool {
for tool in self.registered_tools.values() {
if tool.type_id == TypeId::of::<T>() {
return tool.enabled.load(SeqCst);
}
}
false
}
pub fn definitions(&self) -> Vec<ToolFunctionDefinition> {
self.registered_tools
.values()
.filter(|tool| tool.enabled.load(SeqCst))
.map(|tool| tool.definition.clone())
.collect()
}
pub fn update_tool_call(
&self,
call: &mut ToolFunctionCall,
name: Option<&str>,
arguments: Option<&str>,
cx: &mut WindowContext,
) {
if let Some(name) = name {
call.name.push_str(name);
}
if let Some(arguments) = arguments {
if call.arguments.is_empty() {
if let Some(tool) = self.registered_tools.get(&call.name) {
let view = (tool.build_view)(cx);
call.state = ToolFunctionCallState::KnownTool(view);
} else {
call.state = ToolFunctionCallState::NoSuchTool;
}
}
call.arguments.push_str(arguments);
if let ToolFunctionCallState::KnownTool(view) = &call.state {
if let Ok(repaired_arguments) = repair(call.arguments.clone()) {
view.try_set_input(&repaired_arguments, cx)
}
}
}
}
pub fn execute_tool_call(
&self,
tool_call: &mut ToolFunctionCall,
cx: &mut WindowContext,
) -> Option<Task<Result<()>>> {
if let ToolFunctionCallState::KnownTool(view) = mem::take(&mut tool_call.state) {
let task = view.execute(cx);
tool_call.state = ToolFunctionCallState::ExecutedTool(view);
Some(task)
} else {
None
}
}
pub fn render_tool_call(
&self,
tool_call: &ToolFunctionCall,
_cx: &mut WindowContext,
) -> Option<AnyElement> {
match &tool_call.state {
ToolFunctionCallState::NoSuchTool => {
Some(ui::Label::new("No such tool").into_any_element())
}
ToolFunctionCallState::Initializing => None,
ToolFunctionCallState::KnownTool(view) | ToolFunctionCallState::ExecutedTool(view) => {
Some(view.view().into_any_element())
}
}
}
pub fn content_for_tool_call(
&self,
tool_call: &ToolFunctionCall,
project_context: &mut ProjectContext,
cx: &mut WindowContext,
) -> String {
match &tool_call.state {
ToolFunctionCallState::Initializing => String::new(),
ToolFunctionCallState::NoSuchTool => {
format!("No such tool: {}", tool_call.name)
}
ToolFunctionCallState::KnownTool(view) | ToolFunctionCallState::ExecutedTool(view) => {
view.generate(project_context, cx)
}
}
}
pub fn serialize_tool_call(
&self,
call: &ToolFunctionCall,
cx: &mut WindowContext,
) -> Result<SavedToolFunctionCall> {
Ok(SavedToolFunctionCall {
id: call.id.clone(),
name: call.name.clone(),
arguments: call.arguments.clone(),
state: match &call.state {
ToolFunctionCallState::Initializing => SavedToolFunctionCallState::Initializing,
ToolFunctionCallState::NoSuchTool => SavedToolFunctionCallState::NoSuchTool,
ToolFunctionCallState::KnownTool(_) => SavedToolFunctionCallState::KnownTool,
ToolFunctionCallState::ExecutedTool(view) => {
SavedToolFunctionCallState::ExecutedTool(view.serialize_output(cx)?)
}
},
})
}
pub fn deserialize_tool_call(
&self,
call: &SavedToolFunctionCall,
cx: &mut WindowContext,
) -> Result<ToolFunctionCall> {
let Some(tool) = self.registered_tools.get(&call.name) else {
return Err(anyhow!("no such tool {}", call.name));
};
Ok(ToolFunctionCall {
id: call.id.clone(),
name: call.name.clone(),
arguments: call.arguments.clone(),
state: match &call.state {
SavedToolFunctionCallState::Initializing => ToolFunctionCallState::Initializing,
SavedToolFunctionCallState::NoSuchTool => ToolFunctionCallState::NoSuchTool,
SavedToolFunctionCallState::KnownTool => {
log::error!("Deserialized tool that had not executed");
let view = (tool.build_view)(cx);
view.try_set_input(&call.arguments, cx);
ToolFunctionCallState::KnownTool(view)
}
SavedToolFunctionCallState::ExecutedTool(output) => {
let view = (tool.build_view)(cx);
view.try_set_input(&call.arguments, cx);
view.deserialize_output(output, cx)?;
ToolFunctionCallState::ExecutedTool(view)
}
},
})
}
pub fn register<T: 'static + LanguageModelTool>(&mut self, tool: T) -> Result<()> {
let name = tool.name();
let registered_tool = RegisteredTool {
type_id: TypeId::of::<T>(),
definition: tool.definition(),
enabled: AtomicBool::new(true),
build_view: Box::new(move |cx: &mut WindowContext| Box::new(tool.view(cx))),
};
let previous = self.registered_tools.insert(name.clone(), registered_tool);
if previous.is_some() {
return Err(anyhow!("already registered a tool with name {}", name));
}
return Ok(());
}
}
impl<T: ToolView> InternalToolView for View<T> {
fn view(&self) -> AnyView {
self.clone().into()
}
fn generate(&self, project: &mut ProjectContext, cx: &mut WindowContext) -> String {
self.update(cx, |view, cx| view.generate(project, cx))
}
fn try_set_input(&self, input: &str, cx: &mut WindowContext) {
if let Ok(input) = serde_json::from_str::<T::Input>(input) {
self.update(cx, |view, cx| {
view.set_input(input, cx);
cx.notify();
});
}
}
fn execute(&self, cx: &mut WindowContext) -> Task<Result<()>> {
self.update(cx, |view, cx| view.execute(cx))
}
fn serialize_output(&self, cx: &mut WindowContext) -> Result<Box<RawValue>> {
let output = self.update(cx, |view, cx| view.serialize(cx));
Ok(RawValue::from_string(serde_json::to_string(&output)?)?)
}
fn deserialize_output(&self, output: &RawValue, cx: &mut WindowContext) -> Result<()> {
let state = serde_json::from_str::<T::SerializedState>(output.get())?;
self.update(cx, |view, cx| view.deserialize(state, cx))?;
Ok(())
}
}
impl Display for ToolFunctionDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let schema = serde_json::to_string(&self.parameters).ok();
let schema = schema.unwrap_or("None".to_string());
write!(f, "Name: {}:\n", self.name)?;
write!(f, "Description: {}\n", self.description)?;
write!(f, "Parameters: {}", schema)
}
}
#[cfg(test)]
mod test {
use super::*;
use gpui::{div, prelude::*, Render, TestAppContext};
use gpui::{EmptyView, View};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Deserialize, Serialize, JsonSchema)]
struct WeatherQuery {
location: String,
unit: String,
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
struct WeatherResult {
location: String,
temperature: f64,
unit: String,
}
struct WeatherView {
input: Option<WeatherQuery>,
result: Option<WeatherResult>,
// Fake API call
current_weather: WeatherResult,
}
#[derive(Clone, Serialize)]
struct WeatherTool {
current_weather: WeatherResult,
}
impl WeatherView {
fn new(current_weather: WeatherResult) -> Self {
Self {
input: None,
result: None,
current_weather,
}
}
}
impl Render for WeatherView {
fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> impl IntoElement {
match self.result {
Some(ref result) => div()
.child(format!("temperature: {}", result.temperature))
.into_any_element(),
None => div().child("Calculating weather...").into_any_element(),
}
}
}
impl ToolView for WeatherView {
type Input = WeatherQuery;
type SerializedState = WeatherResult;
fn generate(&self, _output: &mut ProjectContext, _cx: &mut ViewContext<Self>) -> String {
serde_json::to_string(&self.result).unwrap()
}
fn set_input(&mut self, input: Self::Input, cx: &mut ViewContext<Self>) {
self.input = Some(input);
cx.notify();
}
fn execute(&mut self, _cx: &mut ViewContext<Self>) -> Task<Result<()>> {
let input = self.input.as_ref().unwrap();
let _location = input.location.clone();
let _unit = input.unit.clone();
let weather = self.current_weather.clone();
self.result = Some(weather);
Task::ready(Ok(()))
}
fn serialize(&self, _cx: &mut ViewContext<Self>) -> Self::SerializedState {
self.current_weather.clone()
}
fn deserialize(
&mut self,
output: Self::SerializedState,
_cx: &mut ViewContext<Self>,
) -> Result<()> {
self.current_weather = output;
Ok(())
}
}
impl LanguageModelTool for WeatherTool {
type View = WeatherView;
fn name(&self) -> String {
"get_current_weather".to_string()
}
fn description(&self) -> String {
"Fetches the current weather for a given location.".to_string()
}
fn view(&self, cx: &mut WindowContext) -> View<Self::View> {
cx.new_view(|_cx| WeatherView::new(self.current_weather.clone()))
}
}
#[gpui::test]
async fn test_openai_weather_example(cx: &mut TestAppContext) {
let (_, cx) = cx.add_window_view(|_cx| EmptyView);
let mut registry = ToolRegistry::new();
registry
.register(WeatherTool {
current_weather: WeatherResult {
location: "San Francisco".to_string(),
temperature: 21.0,
unit: "Celsius".to_string(),
},
})
.unwrap();
let definitions = registry.definitions();
assert_eq!(
definitions,
[ToolFunctionDefinition {
name: "get_current_weather".to_string(),
description: "Fetches the current weather for a given location.".to_string(),
parameters: serde_json::from_value(json!({
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "WeatherQuery",
"type": "object",
"properties": {
"location": {
"type": "string"
},
"unit": {
"type": "string"
}
},
"required": ["location", "unit"]
}))
.unwrap(),
}]
);
let mut call = ToolFunctionCall {
id: "the-id".to_string(),
name: "get_cur".to_string(),
..Default::default()
};
let task = cx.update(|cx| {
registry.update_tool_call(
&mut call,
Some("rent_weather"),
Some(r#"{"location": "San Francisco","#),
cx,
);
registry.update_tool_call(&mut call, None, Some(r#" "unit": "Celsius"}"#), cx);
registry.execute_tool_call(&mut call, cx).unwrap()
});
task.await.unwrap();
match &call.state {
ToolFunctionCallState::ExecutedTool(_view) => {}
_ => panic!(),
}
}
}

View File

@@ -18,11 +18,12 @@ client.workspace = true
db.workspace = true
editor.workspace = true
gpui.workspace = true
http.workspace = true
http_client.workspace = true
isahc.workspace = true
log.workspace = true
markdown_preview.workspace = true
menu.workspace = true
paths.workspace = true
release_channel.workspace = true
schemars.workspace = true
serde.workspace = true

View File

@@ -1,7 +1,7 @@
mod update_notification;
use anyhow::{anyhow, Context, Result};
use client::{Client, TelemetrySettings, ZED_APP_PATH};
use client::{Client, TelemetrySettings};
use db::kvp::KEY_VALUE_STORE;
use db::RELEASE_CHANNEL;
use editor::{Editor, MultiBuffer};
@@ -20,7 +20,7 @@ use smol::{fs, io::AsyncReadExt};
use settings::{Settings, SettingsSources, SettingsStore};
use smol::{fs::File, process::Command};
use http::{HttpClient, HttpClientWithUrl};
use http_client::{HttpClient, HttpClientWithUrl};
use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
use std::{
env::{
@@ -28,7 +28,7 @@ use std::{
consts::{ARCH, OS},
},
ffi::OsString,
path::PathBuf,
path::{Path, PathBuf},
sync::Arc,
time::Duration,
};
@@ -288,7 +288,12 @@ fn view_release_notes_locally(workspace: &mut Workspace, cx: &mut ViewContext<Wo
Some(tab_description),
cx,
);
workspace.add_item_to_active_pane(Box::new(view.clone()), None, cx);
workspace.add_item_to_active_pane(
Box::new(view.clone()),
None,
true,
cx,
);
cx.notify();
})
.log_err();
@@ -354,7 +359,6 @@ impl AutoUpdater {
return;
}
self.status = AutoUpdateStatus::Checking;
cx.notify();
self.pending_poll = Some(cx.spawn(|this, mut cx| async move {
@@ -380,29 +384,65 @@ impl AutoUpdater {
cx.notify();
}
async fn update(this: Model<Self>, mut cx: AsyncAppContext) -> Result<()> {
let (client, current_version) = this.read_with(&cx, |this, _| {
(this.http_client.clone(), this.current_version)
})?;
pub async fn get_latest_remote_server_release(
os: &str,
arch: &str,
mut release_channel: ReleaseChannel,
cx: &mut AsyncAppContext,
) -> Result<PathBuf> {
let this = cx.update(|cx| {
cx.default_global::<GlobalAutoUpdate>()
.0
.clone()
.ok_or_else(|| anyhow!("auto-update not initialized"))
})??;
let asset = match OS {
"linux" => format!("zed-linux-{}.tar.gz", ARCH),
"macos" => "Zed.dmg".into(),
_ => return Err(anyhow!("auto-update not supported for OS {:?}", OS)),
};
if release_channel == ReleaseChannel::Dev {
release_channel = ReleaseChannel::Nightly;
}
let release = Self::get_latest_release(
&this,
"zed-remote-server",
os,
arch,
Some(release_channel),
cx,
)
.await?;
let servers_dir = paths::remote_servers_dir();
let channel_dir = servers_dir.join(release_channel.dev_name());
let platform_dir = channel_dir.join(format!("{}-{}", os, arch));
let version_path = platform_dir.join(format!("{}.gz", release.version));
smol::fs::create_dir_all(&platform_dir).await.ok();
let client = this.read_with(cx, |this, _| this.http_client.clone())?;
if smol::fs::metadata(&version_path).await.is_err() {
log::info!("downloading zed-remote-server {os} {arch}");
download_remote_server_binary(&version_path, release, client, cx).await?;
}
Ok(version_path)
}
async fn get_latest_release(
this: &Model<Self>,
asset: &str,
os: &str,
arch: &str,
release_channel: Option<ReleaseChannel>,
cx: &mut AsyncAppContext,
) -> Result<JsonRelease> {
let client = this.read_with(cx, |this, _| this.http_client.clone())?;
let mut url_string = client.build_url(&format!(
"/api/releases/latest?asset={}&os={}&arch={}",
asset, OS, ARCH
asset, os, arch
));
cx.update(|cx| {
if let Some(param) = ReleaseChannel::try_global(cx)
.and_then(|release_channel| release_channel.release_query_param())
{
url_string += "&";
url_string += param;
}
})?;
if let Some(param) = release_channel.and_then(|c| c.release_query_param()) {
url_string += "&";
url_string += param;
}
let mut response = client.get(&url_string, Default::default(), true).await?;
@@ -413,8 +453,34 @@ impl AutoUpdater {
.await
.context("error reading release")?;
let release: JsonRelease =
serde_json::from_slice(body.as_slice()).context("error deserializing release")?;
if !response.status().is_success() {
Err(anyhow!(
"failed to fetch release: {:?}",
String::from_utf8_lossy(&body),
))?;
}
serde_json::from_slice(body.as_slice()).with_context(|| {
format!(
"error deserializing release {:?}",
String::from_utf8_lossy(&body),
)
})
}
async fn update(this: Model<Self>, mut cx: AsyncAppContext) -> Result<()> {
let (client, current_version, release_channel) = this.update(&mut cx, |this, cx| {
this.status = AutoUpdateStatus::Checking;
cx.notify();
(
this.http_client.clone(),
this.current_version,
ReleaseChannel::try_global(cx),
)
})?;
let release =
Self::get_latest_release(&this, "zed", OS, ARCH, release_channel, &mut cx).await?;
let should_download = match *RELEASE_CHANNEL {
ReleaseChannel::Nightly => cx
@@ -441,19 +507,21 @@ impl AutoUpdater {
let temp_dir = tempfile::Builder::new()
.prefix("zed-auto-update")
.tempdir()?;
let downloaded_asset = download_release(&temp_dir, release, &asset, client, &cx).await?;
let filename = match OS {
"macos" => Ok("Zed.dmg"),
"linux" => Ok("zed.tar.gz"),
_ => Err(anyhow!("not supported: {:?}", OS)),
}?;
let downloaded_asset = temp_dir.path().join(filename);
download_release(&downloaded_asset, release, client, &cx).await?;
this.update(&mut cx, |this, cx| {
this.status = AutoUpdateStatus::Installing;
cx.notify();
})?;
// We store the path of our current binary, before we install, since installation might
// delete it. Once deleted, it's hard to get the path to our binary on Linux.
// So we cache it here, which allows us to then restart later on.
let binary_path = cx.update(|cx| cx.app_path())??;
match OS {
let binary_path = match OS {
"macos" => install_release_macos(&temp_dir, downloaded_asset, &cx).await,
"linux" => install_release_linux(&temp_dir, downloaded_asset, &cx).await,
_ => Err(anyhow!("not supported: {:?}", OS)),
@@ -500,14 +568,38 @@ impl AutoUpdater {
}
}
async fn download_release(
temp_dir: &tempfile::TempDir,
async fn download_remote_server_binary(
target_path: &PathBuf,
release: JsonRelease,
target_filename: &str,
client: Arc<HttpClientWithUrl>,
cx: &AsyncAppContext,
) -> Result<PathBuf> {
let target_path = temp_dir.path().join(target_filename);
) -> Result<()> {
let mut target_file = File::create(&target_path).await?;
let (installation_id, release_channel, telemetry) = cx.update(|cx| {
let installation_id = Client::global(cx).telemetry().installation_id();
let release_channel =
ReleaseChannel::try_global(cx).map(|release_channel| release_channel.display_name());
let telemetry = TelemetrySettings::get_global(cx).metrics;
(installation_id, release_channel, telemetry)
})?;
let request_body = AsyncBody::from(serde_json::to_string(&UpdateRequestBody {
installation_id,
release_channel,
telemetry,
})?);
let mut response = client.get(&release.url, request_body, true).await?;
smol::io::copy(response.body_mut(), &mut target_file).await?;
Ok(())
}
async fn download_release(
target_path: &Path,
release: JsonRelease,
client: Arc<HttpClientWithUrl>,
cx: &AsyncAppContext,
) -> Result<()> {
let mut target_file = File::create(&target_path).await?;
let (installation_id, release_channel, telemetry) = cx.update(|cx| {
@@ -529,16 +621,17 @@ async fn download_release(
smol::io::copy(response.body_mut(), &mut target_file).await?;
log::info!("downloaded update. path:{:?}", target_path);
Ok(target_path)
Ok(())
}
async fn install_release_linux(
temp_dir: &tempfile::TempDir,
downloaded_tar_gz: PathBuf,
cx: &AsyncAppContext,
) -> Result<()> {
) -> Result<PathBuf> {
let channel = cx.update(|cx| ReleaseChannel::global(cx).dev_name())?;
let home_dir = PathBuf::from(env::var("HOME").context("no HOME env var set")?);
let running_app_path = cx.update(|cx| cx.app_path())??;
let extracted = temp_dir.path().join("zed");
fs::create_dir_all(&extracted)
@@ -569,7 +662,16 @@ async fn install_release_linux(
let app_folder_name = format!("zed{}.app", suffix);
let from = extracted.join(&app_folder_name);
let to = home_dir.join(".local");
let mut to = home_dir.join(".local");
let expected_suffix = format!("{}/libexec/zed-editor", app_folder_name);
if let Some(prefix) = running_app_path
.to_str()
.and_then(|str| str.strip_suffix(&expected_suffix))
{
to = PathBuf::from(prefix);
}
let output = Command::new("rsync")
.args(&["-av", "--delete"])
@@ -586,17 +688,15 @@ async fn install_release_linux(
String::from_utf8_lossy(&output.stderr)
);
Ok(())
Ok(to.join(expected_suffix))
}
async fn install_release_macos(
temp_dir: &tempfile::TempDir,
downloaded_dmg: PathBuf,
cx: &AsyncAppContext,
) -> Result<()> {
let running_app_path = ZED_APP_PATH
.clone()
.map_or_else(|| cx.update(|cx| cx.app_path())?, Ok)?;
) -> Result<PathBuf> {
let running_app_path = cx.update(|cx| cx.app_path())??;
let running_app_filename = running_app_path
.file_name()
.ok_or_else(|| anyhow!("invalid running app path"))?;
@@ -644,5 +744,5 @@ async fn install_release_macos(
String::from_utf8_lossy(&output.stderr)
);
Ok(())
Ok(running_app_path)
}

View File

@@ -113,29 +113,30 @@ impl ToolbarItemView for Breadcrumbs {
) -> ToolbarItemLocation {
cx.notify();
self.active_item = None;
if let Some(item) = active_pane_item {
let this = cx.view().downgrade();
self.subscription = Some(item.subscribe_to_item_events(
cx,
Box::new(move |event, cx| {
if let ItemEvent::UpdateBreadcrumbs = event {
this.update(cx, |this, cx| {
cx.notify();
if let Some(active_item) = this.active_item.as_ref() {
cx.emit(ToolbarItemEvent::ChangeLocation(
active_item.breadcrumb_location(cx),
))
}
})
.ok();
}
}),
));
self.active_item = Some(item.boxed_clone());
item.breadcrumb_location(cx)
} else {
ToolbarItemLocation::Hidden
}
let Some(item) = active_pane_item else {
return ToolbarItemLocation::Hidden;
};
let this = cx.view().downgrade();
self.subscription = Some(item.subscribe_to_item_events(
cx,
Box::new(move |event, cx| {
if let ItemEvent::UpdateBreadcrumbs = event {
this.update(cx, |this, cx| {
cx.notify();
if let Some(active_item) = this.active_item.as_ref() {
cx.emit(ToolbarItemEvent::ChangeLocation(
active_item.breadcrumb_location(cx),
))
}
})
.ok();
}
}),
));
self.active_item = Some(item.boxed_clone());
item.breadcrumb_location(cx)
}
fn pane_focus_update(&mut self, pane_focused: bool, _: &mut ViewContext<Self>) {

View File

@@ -51,4 +51,4 @@ language = { workspace = true, features = ["test-support"] }
live_kit_client = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
http = { workspace = true, features = ["test-support"] }
http_client = { workspace = true, features = ["test-support"] }

View File

@@ -493,7 +493,7 @@ impl Room {
// we leave the room and return an error.
if let Some(this) = this.upgrade() {
log::info!("reconnection failed, leaving room");
let _ = this.update(&mut cx, |this, cx| this.leave(cx))?;
let _ = this.update(&mut cx, |this, cx| this.leave(cx))?.await?;
}
Err(anyhow!(
"can't reconnect to room: client failed to re-establish connection"
@@ -526,7 +526,7 @@ impl Room {
rejoined_projects.push(proto::RejoinProject {
id: project_id,
worktrees: project
.worktrees()
.worktrees(cx)
.map(|worktree| {
let worktree = worktree.read(cx);
proto::RejoinWorktree {
@@ -942,7 +942,7 @@ impl Room {
this.pending_room_update.take();
if this.should_leave() {
log::info!("room is empty, leaving");
let _ = this.leave(cx);
let _ = this.leave(cx).detach();
}
this.user_store.update(cx, |user_store, cx| {

View File

@@ -40,4 +40,4 @@ rpc = { workspace = true, features = ["test-support"] }
client = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
http = { workspace = true, features = ["test-support"] }
http_client = { workspace = true, features = ["test-support"] }

View File

@@ -4,7 +4,7 @@ use super::*;
use client::{test::FakeServer, Client, UserStore};
use clock::FakeSystemClock;
use gpui::{AppContext, Context, Model, SemanticVersion, TestAppContext};
use http::FakeHttpClient;
use http_client::FakeHttpClient;
use rpc::proto::{self};
use settings::SettingsStore;

View File

@@ -11,6 +11,7 @@ pub struct IpcHandshake {
pub enum CliRequest {
Open {
paths: Vec<String>,
urls: Vec<String>,
wait: bool,
open_new_workspace: Option<bool>,
dev_server_token: Option<String>,

View File

@@ -5,6 +5,7 @@ use clap::Parser;
use cli::{ipc::IpcOneShotServer, CliRequest, CliResponse, IpcHandshake};
use parking_lot::Mutex;
use std::{
convert::Infallible,
env, fs, io,
path::{Path, PathBuf},
process::ExitStatus,
@@ -37,8 +38,7 @@ struct Args {
///
/// Use `path:line:row` syntax to open a file at a specific location.
/// Non-existing paths and directories will ignore `:line:row` suffix.
#[arg(value_parser = parse_path_with_position)]
paths_with_position: Vec<PathLikeWithPosition<PathBuf>>,
paths_with_position: Vec<String>,
/// Print Zed's version and the app path.
#[arg(short, long)]
version: bool,
@@ -53,12 +53,30 @@ struct Args {
dev_server_token: Option<String>,
}
fn parse_path_with_position(
argument_str: &str,
) -> Result<PathLikeWithPosition<PathBuf>, std::convert::Infallible> {
PathLikeWithPosition::parse_str(argument_str, |_, path_str| {
fn parse_path_with_position(argument_str: &str) -> Result<String, std::io::Error> {
let path_like = PathLikeWithPosition::parse_str::<Infallible>(argument_str, |_, path_str| {
Ok(Path::new(path_str).to_path_buf())
})
.unwrap();
let curdir = env::current_dir()?;
let canonicalized = path_like.map_path_like(|path| match fs::canonicalize(&path) {
Ok(path) => Ok(path),
Err(e) => {
if let Some(mut parent) = path.parent() {
if parent == Path::new("") {
parent = &curdir
}
match fs::canonicalize(parent) {
Ok(parent) => Ok(parent.join(path.file_name().unwrap())),
Err(_) => Err(e),
}
} else {
Err(e)
}
}
})?;
Ok(canonicalized.to_string(|path| path.display().to_string()))
}
fn main() -> Result<()> {
@@ -91,28 +109,6 @@ fn main() -> Result<()> {
return Ok(());
}
let curdir = env::current_dir()?;
let mut paths = vec![];
for path in args.paths_with_position {
let canonicalized = path.map_path_like(|path| match fs::canonicalize(&path) {
Ok(path) => Ok(path),
Err(e) => {
if let Some(mut parent) = path.parent() {
if parent == Path::new("") {
parent = &curdir;
}
match fs::canonicalize(parent) {
Ok(parent) => Ok(parent.join(path.file_name().unwrap())),
Err(_) => Err(e),
}
} else {
Err(e)
}
}
})?;
paths.push(canonicalized.to_string(|path| path.display().to_string()))
}
let (server, server_name) =
IpcOneShotServer::<IpcHandshake>::new().context("Handshake before Zed spawn")?;
let url = format!("zed-cli://{server_name}");
@@ -126,6 +122,20 @@ fn main() -> Result<()> {
};
let exit_status = Arc::new(Mutex::new(None));
let mut paths = vec![];
let mut urls = vec![];
for path in args.paths_with_position.iter() {
if path.starts_with("zed://")
|| path.starts_with("http://")
|| path.starts_with("https://")
|| path.starts_with("file://")
|| path.starts_with("ssh://")
{
urls.push(path.to_string());
} else {
paths.push(parse_path_with_position(path)?)
}
}
let sender: JoinHandle<anyhow::Result<()>> = thread::spawn({
let exit_status = exit_status.clone();
@@ -134,6 +144,7 @@ fn main() -> Result<()> {
let (tx, rx) = (handshake.requests, handshake.responses);
tx.send(CliRequest::Open {
paths,
urls,
wait: args.wait,
open_new_workspace,
dev_server_token: args.dev_server_token,

View File

@@ -18,7 +18,7 @@ test-support = ["clock/test-support", "collections/test-support", "gpui/test-sup
[dependencies]
anyhow.workspace = true
async-recursion = "0.3"
async-tungstenite = { version = "0.16", features = ["async-std", "async-native-tls"] }
async-tungstenite = { workspace = true, features = ["async-std", "async-native-tls"] }
chrono = { workspace = true, features = ["serde"] }
clock.workspace = true
collections.workspace = true
@@ -26,7 +26,7 @@ feature_flags.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
http.workspace = true
http_client.workspace = true
lazy_static.workspace = true
log.workspace = true
once_cell.workspace = true
@@ -60,12 +60,11 @@ gpui = { workspace = true, features = ["test-support"] }
rpc = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
util = { workspace = true, features = ["test-support"] }
http = { workspace = true, features = ["test-support"] }
http_client = { workspace = true, features = ["test-support"] }
[target.'cfg(target_os = "windows")'.dependencies]
windows.workspace = true
[target.'cfg(target_os = "macos")'.dependencies]
cocoa.workspace = true
isahc = { workspace = true, features = ["static-curl"] }
async-native-tls = { version = "0.5.0", features = ["vendored"] }

View File

@@ -7,22 +7,25 @@ pub mod user;
use anyhow::{anyhow, Context as _, Result};
use async_recursion::async_recursion;
use async_tungstenite::tungstenite::{
client::IntoClientRequest,
error::Error as WebsocketError,
http::{Request, StatusCode},
http::{HeaderValue, Request, StatusCode},
};
use clock::SystemClock;
use collections::HashMap;
use futures::{
channel::oneshot, future::LocalBoxFuture, AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt,
TryFutureExt as _, TryStreamExt,
channel::oneshot,
future::{BoxFuture, LocalBoxFuture},
AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt, TryFutureExt as _, TryStreamExt,
};
use gpui::{
actions, AnyModel, AnyWeakModel, AppContext, AsyncAppContext, Global, Model, Task, WeakModel,
};
use http::{HttpClient, HttpClientWithUrl};
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
use lazy_static::lazy_static;
use parking_lot::RwLock;
use postage::watch;
use proto::ProtoClient;
use rand::prelude::*;
use release_channel::{AppVersion, ReleaseChannel};
use rpc::proto::{AnyTypedEnvelope, EntityMessage, EnvelopedMessage, PeerId, RequestMessage};
@@ -231,7 +234,9 @@ pub enum EstablishConnectionError {
#[error("{0}")]
Other(#[from] anyhow::Error),
#[error("{0}")]
Http(#[from] http::Error),
Http(#[from] http_client::Error),
#[error("{0}")]
InvalidHeaderValue(#[from] async_tungstenite::tungstenite::http::header::InvalidHeaderValue),
#[error("{0}")]
Io(#[from] std::io::Error),
#[error("{0}")]
@@ -1157,19 +1162,24 @@ impl Client {
.ok()
.unwrap_or_default();
let request = Request::builder()
.header("Authorization", credentials.authorization_header())
.header("x-zed-protocol-version", rpc::PROTOCOL_VERSION)
.header("x-zed-app-version", app_version)
.header(
"x-zed-release-channel",
release_channel.map(|r| r.dev_name()).unwrap_or("unknown"),
);
let http = self.http.clone();
let credentials = credentials.clone();
let rpc_url = self.rpc_url(http, release_channel);
cx.background_executor().spawn(async move {
use HttpOrHttps::*;
#[derive(Debug)]
enum HttpOrHttps {
Http,
Https,
}
let mut rpc_url = rpc_url.await?;
let url_scheme = match rpc_url.scheme() {
"https" => Https,
"http" => Http,
_ => Err(anyhow!("invalid rpc url: {}", rpc_url))?,
};
let rpc_host = rpc_url
.host_str()
.zip(rpc_url.port_or_known_default())
@@ -1178,10 +1188,37 @@ impl Client {
log::info!("connected to rpc endpoint {}", rpc_url);
match rpc_url.scheme() {
"https" => {
rpc_url.set_scheme("wss").unwrap();
let request = request.uri(rpc_url.as_str()).body(())?;
rpc_url
.set_scheme(match url_scheme {
Https => "wss",
Http => "ws",
})
.unwrap();
// We call `into_client_request` to let `tungstenite` construct the WebSocket request
// for us from the RPC URL.
//
// Among other things, it will generate and set a `Sec-WebSocket-Key` header for us.
let mut request = rpc_url.into_client_request()?;
// We then modify the request to add our desired headers.
let request_headers = request.headers_mut();
request_headers.insert(
"Authorization",
HeaderValue::from_str(&credentials.authorization_header())?,
);
request_headers.insert(
"x-zed-protocol-version",
HeaderValue::from_str(&rpc::PROTOCOL_VERSION.to_string())?,
);
request_headers.insert("x-zed-app-version", HeaderValue::from_str(&app_version)?);
request_headers.insert(
"x-zed-release-channel",
HeaderValue::from_str(&release_channel.map(|r| r.dev_name()).unwrap_or("unknown"))?,
);
match url_scheme {
Https => {
let (stream, _) =
async_tungstenite::async_std::client_async_tls(request, stream).await?;
Ok(Connection::new(
@@ -1190,9 +1227,7 @@ impl Client {
.sink_map_err(|error| anyhow!(error)),
))
}
"http" => {
rpc_url.set_scheme("ws").unwrap();
let request = request.uri(rpc_url.as_str()).body(())?;
Http => {
let (stream, _) = async_tungstenite::client_async(request, stream).await?;
Ok(Connection::new(
stream
@@ -1200,7 +1235,6 @@ impl Client {
.sink_map_err(|error| anyhow!(error)),
))
}
_ => Err(anyhow!("invalid rpc url: {}", rpc_url))?,
}
})
}
@@ -1349,7 +1383,7 @@ impl Client {
let mut url = self.rpc_url(http.clone(), None).await?;
url.set_path("/user");
url.set_query(Some(&format!("github_login={login}")));
let request = Request::get(url.as_str())
let request: http_client::Request<AsyncBody> = Request::get(url.as_str())
.header("Authorization", format!("token {api_token}"))
.body("".into())?;
@@ -1408,6 +1442,11 @@ impl Client {
self.peer.send(self.connection_id()?, message)
}
pub fn send_dynamic(&self, envelope: proto::Envelope) -> Result<()> {
let connection_id = self.connection_id()?;
self.peer.send_dynamic(connection_id, envelope)
}
pub fn request<T: RequestMessage>(
&self,
request: T,
@@ -1606,6 +1645,20 @@ impl Client {
}
}
impl ProtoClient for Client {
fn request(
&self,
envelope: proto::Envelope,
request_type: &'static str,
) -> BoxFuture<'static, Result<proto::Envelope>> {
self.request_dynamic(envelope, request_type).boxed()
}
fn send(&self, envelope: proto::Envelope) -> Result<()> {
self.send_dynamic(envelope)
}
}
#[derive(Serialize, Deserialize)]
struct DevelopmentCredentials {
user_id: u64,
@@ -1762,7 +1815,7 @@ mod tests {
use clock::FakeSystemClock;
use gpui::{BackgroundExecutor, Context, TestAppContext};
use http::FakeHttpClient;
use http_client::FakeHttpClient;
use parking_lot::Mutex;
use proto::TypedEnvelope;
use settings::SettingsStore;

View File

@@ -6,7 +6,7 @@ use clock::SystemClock;
use collections::{HashMap, HashSet};
use futures::Future;
use gpui::{AppContext, BackgroundExecutor, Task};
use http::{self, HttpClient, HttpClientWithUrl, Method};
use http_client::{self, HttpClient, HttpClientWithUrl, Method};
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use release_channel::ReleaseChannel;
@@ -18,7 +18,7 @@ use sysinfo::{CpuRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System};
use telemetry_events::{
ActionEvent, AppEvent, AssistantEvent, AssistantKind, CallEvent, CpuEvent, EditEvent,
EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent,
MemoryEvent, SettingEvent,
MemoryEvent, ReplEvent, SettingEvent,
};
use tempfile::NamedTempFile;
#[cfg(not(debug_assertions))]
@@ -531,6 +531,21 @@ impl Telemetry {
}
}
pub fn report_repl_event(
self: &Arc<Self>,
kernel_language: String,
kernel_status: String,
repl_session_id: String,
) {
let event = Event::Repl(ReplEvent {
kernel_language,
kernel_status,
repl_session_id,
});
self.report_event(event)
}
fn report_event(self: &Arc<Self>, event: Event) {
let mut state = self.state.lock();
@@ -632,7 +647,7 @@ impl Telemetry {
let checksum = calculate_json_checksum(&json_bytes).unwrap_or("".to_string());
let request = http::Request::builder()
let request = http_client::Request::builder()
.method(Method::POST)
.uri(
this.http_client
@@ -661,7 +676,7 @@ mod tests {
use chrono::TimeZone;
use clock::FakeSystemClock;
use gpui::TestAppContext;
use http::FakeHttpClient;
use http_client::FakeHttpClient;
#[gpui::test]
fn test_telemetry_flush_on_max_queue_size(cx: &mut TestAppContext) {

View File

@@ -20,7 +20,7 @@ test-support = ["sqlite"]
[dependencies]
anthropic.workspace = true
anyhow.workspace = true
async-tungstenite = "0.16"
async-tungstenite.workspace = true
aws-config = { version = "1.1.5" }
aws-sdk-s3 = { version = "1.15.0" }
axum = { version = "0.6", features = ["json", "headers", "ws"] }
@@ -30,12 +30,12 @@ chrono.workspace = true
clock.workspace = true
clickhouse.workspace = true
collections.workspace = true
dashmap = "5.4"
dashmap.workspace = true
envy = "0.4.2"
futures.workspace = true
google_ai.workspace = true
hex.workspace = true
http.workspace = true
http_client.workspace = true
live_kit_server.workspace = true
log.workspace = true
nanoid.workspace = true
@@ -47,7 +47,7 @@ prost.workspace = true
rand.workspace = true
reqwest = { version = "0.11", features = ["json"] }
rpc.workspace = true
scrypt = "0.7"
scrypt = "0.11"
sea-orm = { version = "0.12.x", features = ["sqlx-postgres", "postgres-array", "runtime-tokio-rustls", "with-uuid"] }
semantic_version.workspace = true
semver.workspace = true
@@ -79,6 +79,7 @@ channel.workspace = true
client = { workspace = true, features = ["test-support"] }
collab_ui = { workspace = true, features = ["test-support"] }
collections = { workspace = true, features = ["test-support"] }
completion = { workspace = true, features = ["test-support"] }
ctor.workspace = true
editor = { workspace = true, features = ["test-support"] }
env_logger.workspace = true
@@ -89,6 +90,7 @@ git_hosting_providers.workspace = true
gpui = { workspace = true, features = ["test-support"] }
indoc.workspace = true
language = { workspace = true, features = ["test-support"] }
language_model = { workspace = true, features = ["test-support"] }
live_kit_client = { workspace = true, features = ["test-support"] }
lsp = { workspace = true, features = ["test-support"] }
menu.workspace = true
@@ -99,10 +101,13 @@ pretty_assertions.workspace = true
project = { workspace = true, features = ["test-support"] }
recent_projects = { workspace = true }
release_channel.workspace = true
remote = { workspace = true, features = ["test-support"] }
remote_server.workspace = true
dev_server_projects.workspace = true
rpc = { workspace = true, features = ["test-support"] }
sea-orm = { version = "0.12.x", features = ["sqlx-sqlite"] }
serde_json.workspace = true
session = { workspace = true, features = ["test-support"] }
settings = { workspace = true, features = ["test-support"] }
sqlx = { version = "0.7", features = ["sqlite"] }
theme.workspace = true

View File

@@ -414,5 +414,5 @@ CREATE TABLE dev_servers (
CREATE TABLE dev_server_projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
dev_server_id INTEGER NOT NULL REFERENCES dev_servers(id),
path TEXT NOT NULL
paths TEXT NOT NULL
);

View File

@@ -0,0 +1,4 @@
ALTER TABLE dev_server_projects ADD COLUMN paths JSONB NULL;
UPDATE dev_server_projects SET paths = to_json(ARRAY[path]);
ALTER TABLE dev_server_projects ALTER COLUMN paths SET NOT NULL;
ALTER TABLE dev_server_projects ALTER COLUMN path DROP NOT NULL;

View File

@@ -1,6 +1,5 @@
use anyhow::{anyhow, Context as _, Result};
use anyhow::{anyhow, Result};
use rpc::proto;
use util::ResultExt as _;
pub fn language_model_request_to_open_ai(
request: proto::CompleteWithLanguageModel,
@@ -21,25 +20,7 @@ pub fn language_model_request_to_open_ai(
proto::LanguageModelRole::LanguageModelAssistant => {
open_ai::RequestMessage::Assistant {
content: Some(message.content),
tool_calls: message
.tool_calls
.into_iter()
.filter_map(|call| {
Some(open_ai::ToolCall {
id: call.id,
content: match call.variant? {
proto::tool_call::Variant::Function(f) => {
open_ai::ToolCallContent::Function {
function: open_ai::FunctionContent {
name: f.name,
arguments: f.arguments,
},
}
}
},
})
})
.collect(),
tool_calls: Vec::new(),
}
}
proto::LanguageModelRole::LanguageModelSystem => {
@@ -47,12 +28,6 @@ pub fn language_model_request_to_open_ai(
content: message.content,
}
}
proto::LanguageModelRole::LanguageModelTool => open_ai::RequestMessage::Tool {
tool_call_id: message
.tool_call_id
.ok_or_else(|| anyhow!("tool message is missing tool call id"))?,
content: message.content,
},
};
Ok(openai_message)
@@ -61,32 +36,8 @@ pub fn language_model_request_to_open_ai(
stream: true,
stop: request.stop,
temperature: request.temperature,
tools: request
.tools
.into_iter()
.filter_map(|tool| {
Some(match tool.variant? {
proto::chat_completion_tool::Variant::Function(f) => {
open_ai::ToolDefinition::Function {
function: open_ai::FunctionDefinition {
name: f.name,
description: f.description,
parameters: if let Some(params) = &f.parameters {
Some(
serde_json::from_str(params)
.context("failed to deserialize tool parameters")
.log_err()?,
)
} else {
None
},
},
}
}
})
})
.collect(),
tool_choice: request.tool_choice,
tool_choice: None,
tools: Vec::new(),
})
}
@@ -118,9 +69,6 @@ pub fn language_model_request_message_to_google_ai(
proto::LanguageModelRole::LanguageModelUser => google_ai::Role::User,
proto::LanguageModelRole::LanguageModelAssistant => google_ai::Role::Model,
proto::LanguageModelRole::LanguageModelSystem => google_ai::Role::User,
proto::LanguageModelRole::LanguageModelTool => {
Err(anyhow!("we don't handle tool calls with google ai yet"))?
}
},
})
}

View File

@@ -1,3 +1,4 @@
pub mod contributors;
pub mod events;
pub mod extensions;
pub mod ips_file;
@@ -5,13 +6,13 @@ pub mod slack;
use crate::{
auth,
db::{ContributorSelector, User, UserId},
db::{User, UserId},
rpc, AppState, Error, Result,
};
use anyhow::anyhow;
use axum::{
body::Body,
extract::{self, Path, Query},
extract::{Path, Query},
http::{self, Request, StatusCode},
middleware::{self, Next},
response::IntoResponse,
@@ -19,7 +20,6 @@ use axum::{
Extension, Json, Router,
};
use axum_extra::response::ErasedJson;
use chrono::SecondsFormat;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tower::ServiceBuilder;
@@ -31,8 +31,7 @@ pub fn routes(rpc_server: Option<Arc<rpc::Server>>, state: Arc<AppState>) -> Rou
.route("/user", get(get_authenticated_user))
.route("/users/:id/access_tokens", post(create_access_token))
.route("/rpc_server_snapshot", get(get_rpc_server_snapshot))
.route("/contributors", get(get_contributors).post(add_contributor))
.route("/contributor", get(check_is_contributor))
.merge(contributors::router())
.layer(
ServiceBuilder::new()
.layer(Extension(state))
@@ -126,66 +125,6 @@ async fn get_rpc_server_snapshot(
Ok(ErasedJson::pretty(rpc_server.snapshot().await))
}
async fn get_contributors(Extension(app): Extension<Arc<AppState>>) -> Result<Json<Vec<String>>> {
Ok(Json(app.db.get_contributors().await?))
}
#[derive(Debug, Deserialize)]
struct CheckIsContributorParams {
github_user_id: Option<i32>,
github_login: Option<String>,
}
impl CheckIsContributorParams {
fn as_contributor_selector(self) -> Result<ContributorSelector> {
if let Some(github_user_id) = self.github_user_id {
return Ok(ContributorSelector::GitHubUserId { github_user_id });
}
if let Some(github_login) = self.github_login {
return Ok(ContributorSelector::GitHubLogin { github_login });
}
Err(anyhow!(
"must be one of `github_user_id` or `github_login`."
))?
}
}
#[derive(Debug, Serialize)]
struct CheckIsContributorResponse {
signed_at: Option<String>,
}
async fn check_is_contributor(
Extension(app): Extension<Arc<AppState>>,
Query(params): Query<CheckIsContributorParams>,
) -> Result<Json<CheckIsContributorResponse>> {
let params = params.as_contributor_selector()?;
Ok(Json(CheckIsContributorResponse {
signed_at: app
.db
.get_contributor_sign_timestamp(&params)
.await?
.map(|ts| ts.and_utc().to_rfc3339_opts(SecondsFormat::Millis, true)),
}))
}
async fn add_contributor(
Extension(app): Extension<Arc<AppState>>,
extract::Json(params): extract::Json<AuthenticatedUserParams>,
) -> Result<()> {
let initial_channel_id = app.config.auto_join_channel_id;
app.db
.add_contributor(
&params.github_login,
params.github_user_id,
params.github_email.as_deref(),
initial_channel_id,
)
.await
}
#[derive(Deserialize)]
struct CreateAccessTokenQueryParams {
public_key: String,

View File

@@ -0,0 +1,121 @@
use std::sync::{Arc, OnceLock};
use anyhow::anyhow;
use axum::{
extract::{self, Query},
routing::get,
Extension, Json, Router,
};
use chrono::{NaiveDateTime, SecondsFormat};
use serde::{Deserialize, Serialize};
use crate::api::AuthenticatedUserParams;
use crate::db::ContributorSelector;
use crate::{AppState, Result};
pub fn router() -> Router {
Router::new()
.route("/contributors", get(get_contributors).post(add_contributor))
.route("/contributor", get(check_is_contributor))
}
async fn get_contributors(Extension(app): Extension<Arc<AppState>>) -> Result<Json<Vec<String>>> {
Ok(Json(app.db.get_contributors().await?))
}
#[derive(Debug, Deserialize)]
struct CheckIsContributorParams {
github_user_id: Option<i32>,
github_login: Option<String>,
}
impl CheckIsContributorParams {
fn as_contributor_selector(self) -> Result<ContributorSelector> {
if let Some(github_user_id) = self.github_user_id {
return Ok(ContributorSelector::GitHubUserId { github_user_id });
}
if let Some(github_login) = self.github_login {
return Ok(ContributorSelector::GitHubLogin { github_login });
}
Err(anyhow!(
"must be one of `github_user_id` or `github_login`."
))?
}
}
#[derive(Debug, Serialize)]
struct CheckIsContributorResponse {
signed_at: Option<String>,
}
async fn check_is_contributor(
Extension(app): Extension<Arc<AppState>>,
Query(params): Query<CheckIsContributorParams>,
) -> Result<Json<CheckIsContributorResponse>> {
let params = params.as_contributor_selector()?;
if RenovateBot::is_renovate_bot(&params) {
return Ok(Json(CheckIsContributorResponse {
signed_at: Some(
RenovateBot::created_at()
.and_utc()
.to_rfc3339_opts(SecondsFormat::Millis, true),
),
}));
}
Ok(Json(CheckIsContributorResponse {
signed_at: app
.db
.get_contributor_sign_timestamp(&params)
.await?
.map(|ts| ts.and_utc().to_rfc3339_opts(SecondsFormat::Millis, true)),
}))
}
/// The Renovate bot GitHub user (`renovate[bot]`).
///
/// https://api.github.com/users/renovate[bot]
struct RenovateBot;
impl RenovateBot {
const LOGIN: &'static str = "renovate[bot]";
const USER_ID: i32 = 29139614;
/// Returns the `created_at` timestamp for the Renovate bot user.
fn created_at() -> &'static NaiveDateTime {
static CREATED_AT: OnceLock<NaiveDateTime> = OnceLock::new();
CREATED_AT.get_or_init(|| {
chrono::DateTime::parse_from_rfc3339("2017-06-02T07:04:12Z")
.expect("failed to parse 'created_at' for 'renovate[bot]'")
.naive_utc()
})
}
/// Returns whether the given contributor selector corresponds to the Renovate bot user.
fn is_renovate_bot(contributor: &ContributorSelector) -> bool {
match contributor {
ContributorSelector::GitHubLogin { github_login } => github_login == Self::LOGIN,
ContributorSelector::GitHubUserId { github_user_id } => {
github_user_id == &Self::USER_ID
}
}
}
}
async fn add_contributor(
Extension(app): Extension<Arc<AppState>>,
extract::Json(params): extract::Json<AuthenticatedUserParams>,
) -> Result<()> {
let initial_channel_id = app.config.auto_join_channel_id;
app.db
.add_contributor(
&params.github_login,
params.github_user_id,
params.github_email.as_deref(),
initial_channel_id,
)
.await
}

View File

@@ -16,7 +16,7 @@ use sha2::{Digest, Sha256};
use std::sync::{Arc, OnceLock};
use telemetry_events::{
ActionEvent, AppEvent, AssistantEvent, CallEvent, CpuEvent, EditEvent, EditorEvent, Event,
EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent, MemoryEvent,
EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent, MemoryEvent, ReplEvent,
SettingEvent,
};
use uuid::Uuid;
@@ -518,6 +518,13 @@ pub async fn post_events(
checksum_matched,
))
}
Event::Repl(event) => to_upload.repl_events.push(ReplEventRow::from_event(
event.clone(),
&wrapper,
&request_body,
first_event_at,
checksum_matched,
)),
}
}
@@ -542,6 +549,7 @@ struct ToUpload {
extension_events: Vec<ExtensionEventRow>,
edit_events: Vec<EditEventRow>,
action_events: Vec<ActionEventRow>,
repl_events: Vec<ReplEventRow>,
}
impl ToUpload {
@@ -617,6 +625,11 @@ impl ToUpload {
.await
.with_context(|| format!("failed to upload to table '{ACTION_EVENTS_TABLE}'"))?;
const REPL_EVENTS_TABLE: &str = "repl_events";
Self::upload_to_table(REPL_EVENTS_TABLE, &self.repl_events, clickhouse_client)
.await
.with_context(|| format!("failed to upload to table '{REPL_EVENTS_TABLE}'"))?;
Ok(())
}
@@ -625,22 +638,24 @@ impl ToUpload {
rows: &[T],
clickhouse_client: &clickhouse::Client,
) -> anyhow::Result<()> {
if !rows.is_empty() {
let mut insert = clickhouse_client.insert(table)?;
for event in rows {
insert.write(event).await?;
}
insert.end().await?;
let event_count = rows.len();
log::info!(
"wrote {event_count} {event_specifier} to '{table}'",
event_specifier = if event_count == 1 { "event" } else { "events" }
);
if rows.is_empty() {
return Ok(());
}
let mut insert = clickhouse_client.insert(table)?;
for event in rows {
insert.write(event).await?;
}
insert.end().await?;
let event_count = rows.len();
log::info!(
"wrote {event_count} {event_specifier} to '{table}'",
event_specifier = if event_count == 1 { "event" } else { "events" }
);
Ok(())
}
}
@@ -1189,6 +1204,62 @@ impl ExtensionEventRow {
}
}
#[derive(Serialize, Debug, clickhouse::Row)]
pub struct ReplEventRow {
// AppInfoBase
app_version: String,
major: Option<i32>,
minor: Option<i32>,
patch: Option<i32>,
checksum_matched: bool,
release_channel: String,
os_name: String,
os_version: String,
// ClientEventBase
installation_id: Option<String>,
session_id: Option<String>,
is_staff: Option<bool>,
time: i64,
// ReplEventRow
kernel_language: String,
kernel_status: String,
repl_session_id: String,
}
impl ReplEventRow {
fn from_event(
event: ReplEvent,
wrapper: &EventWrapper,
body: &EventRequestBody,
first_event_at: chrono::DateTime<chrono::Utc>,
checksum_matched: bool,
) -> Self {
let semver = body.semver();
let time =
first_event_at + chrono::Duration::milliseconds(wrapper.milliseconds_since_first_event);
Self {
app_version: body.app_version.clone(),
major: semver.map(|v| v.major() as i32),
minor: semver.map(|v| v.minor() as i32),
patch: semver.map(|v| v.patch() as i32),
checksum_matched,
release_channel: body.release_channel.clone().unwrap_or_default(),
os_name: body.os_name.clone(),
os_version: body.os_version.clone().unwrap_or_default(),
installation_id: body.installation_id.clone(),
session_id: body.session_id.clone(),
is_staff: body.is_staff,
time: time.timestamp_millis(),
kernel_language: event.kernel_language,
kernel_status: event.kernel_status,
repl_session_id: event.repl_session_id,
}
}
}
#[derive(Serialize, Debug, clickhouse::Row)]
pub struct EditEventRow {
// AppInfoBase

View File

@@ -43,11 +43,36 @@ async fn get_extensions(
Extension(app): Extension<Arc<AppState>>,
Query(params): Query<GetExtensionsParams>,
) -> Result<Json<GetExtensionsResponse>> {
let extensions = app
let mut extensions = app
.db
.get_extensions(params.filter.as_deref(), params.max_schema_version, 500)
.await?;
if let Some(filter) = params.filter.as_deref() {
let extension_id = filter.to_lowercase();
let mut exact_match = None;
extensions.retain(|extension| {
if extension.id.as_ref() == &extension_id {
exact_match = Some(extension.clone());
false
} else {
true
}
});
if exact_match.is_none() {
exact_match = app
.db
.get_extensions_by_ids(&[&extension_id], None)
.await?
.first()
.cloned();
}
if let Some(exact_match) = exact_match {
extensions.insert(0, exact_match);
}
};
if let Some(query) = params.filter.as_deref() {
let count = extensions.len();
tracing::info!(query, count, "extension_search")

Some files were not shown because too many files have changed in this diff Show More