Spent a bit in a deep dive into how to handle this and honestly the
situation is rather unfortunate. The core problem is that when we have a
panic anywhere we need to tear down the app, and we'd like to do that as
cleanly as possible, avoiding throwing any other panics along the way if
possible.
We've been seeing a number of panics being reported which are
nonsensical, seemingly pointing to being a fallout panic from a worker
thread panic-ing, at which point we would write multiple panics to the
panic file, and we could possibly upload either both or the wrong panic
causing a wild goose chase. Unfortunately I've been entirely unable to
reproduce the specific panic we've been seeing but I was able to read
through the code responsible and confirm that under specific situations
a panic on one worker can cause another worker or the main thread to
also panic.
An easy solution to this is just to ignore any panics after the first
one. I'm thinking that *hopefully* we can trust the first panic to reach
the panic hook first so that the flag doesn't accidentally filter out
the panic we actually care about.
That being said we were expecting that to have already been the case
about which panic gets written to the panic file first, the first one in
the file being the one we upload, which doesn't seem to have been the
case. I'm hoping it was IO silliness causing that and that the flag
shouldn't be race-y, however this is still a shot in the dark. 🤞
As for cleanly shutting down, there's not really much we can do. One
thread physically cannot cause another to unwind without somehow sending
a message which isn't super useful. The only way for a thread to shut
down all threads and the process is to go nuclear and abort/exit the
process. This will never unwind other threads, effectively having the
same effect on those threads as compiling with `panic = "abort"` would.
With some (mis)use of `std::panic::resume_unwind` we can at least say
that for whatever thread actually panic-ed we will unwind, and any other
threads that panic as a result will probably get at least partway
through unwinding. This is weird, almost a combination of panic
rewinding and aborting, and may actually be worse than just biting the
bullet and aborting immediately.
I'm really not a fan of where I've ended up but it does seem to at the
very least an improvement. The main question in my mind at this point is
whether it would be better to attempt to unwind what we can or go all in
on abort. I'd love some input on that.
Release Notes:
- Improved panic reporting when a background thread panics.
Linear:
https://linear.app/zed-industries/issue/Z-2578/zed-launches-very-slow-for-user
I was searching for the cause of a slow startup time reported in the
above issue, and I don't think I found it, but I did find two very
noticeable slow code paths while profiling, and fixed them.
### Notes
1. When starting the JSON language server, we provide it with a JSON
schema for our settings. For the `theme` setting, the JSON schema needs
to read all of the themes in the registry, to generate a list of valid
theme names. Previously, as part of this, we were deserializing each
theme from JSON, which took a lot of CPU. Now, we don't do that.
2. When an FS event occurs within a git repository, we reload the git
status for all entries in that git repository. Previously, we did that
via a separate `libgit2` call per FS entry (including ignored entries,
so many thousands in the case of the `zed` repo). Now we do one
`libgit2` call, asking for all of the statuses. Git carries an index of
all of the files with statuses, so this is fast.
Release Notes:
- Improved the the performance of starting up a JSON language server.
- Improved the performance of handling changes to git repositories, such
as changing branches or committing.
Closes https://github.com/zed-industries/community/issues/75
Closes https://github.com/zed-industries/community/issues/1749
The PR
* changes keybindings for `Editor && mode == auto_height` context:
before, `alt-enter` and `alt-shift-enter` added new lines in such
editors, including the one from buffer search.
New bindings are the same as in `Editor && mode == full` context.
* adds `search::SelectAllMatches` action and binds it to `Alt + Enter`
by default, to select all matches of a buffer search
The behavior mimics VSCode: we do not move the screen even if all
selections are out of the visible range (Cmd+G will navigate there) and
allow reselecting the results from both pane and search field, as long
as the search is not dismissed.
Release Notes:
- Added `search::SelectAllMatches` (`Alt + Enter` default) action to
place carets and select all buffer search results
([#75](https://github.com/zed-industries/community/issues/75),
[#1749](https://github.com/zed-industries/community/issues/1749)).
We're finally doing the thing.
TODO:
- [x] Choose an approach
- Decided to add a new element just for the pane axis, containing a
slimmed down copy of the flex code.
- [x] Wire through callbacks and pointers so that data goes where it
needs to
- [x] Do the flex juggling math on resize
- [x] Update the flexes when updating the split tree
- [x] Restore the active_pane_magnification setting
- [x] Serialize an axis' flexes
Release Notes:
- Made the center pane group splits resizable. Note that resizing is
disabled if the `active_pane_magnification` setting is changed from
default.
Deals with https://github.com/zed-industries/community/issues/752
Deals with https://github.com/zed-industries/community/issues/566
Currently, when converting from LSP to Zed objects, completions with
non-empty `additional_text_edits` are filtered out.
Later, all other completions form a list and the selected one gets the
`Editor::confirm_completion` call, which always queries an LSP
completion resolve request to get the `additional_text_edits` field.
Otherwise, `additional_text_edits` field is ignored entirely for the
rest of the completion lifetime — and we always pass the selected
completion through the resolve request.
The PR changes the logic, removing the `additional_text_edits` filtering
and instead of resolving every completion, now we check for
`additional_text_edits` in the completion before resolving: resolve
happens only if the data is absent.
Generally, feels like resolve has to happen before the completion
selection: LSP servers may send us markdown for completion documentation
preview pop ups and similar extra info.
Also, the server may lack resolve capabilities entirely, always sending
the request seems dangerous.
For now, the PR does not attempt to change either.
Release Notes:
- Brings rust-analyzer's postfix completions and others completions with
preresolved additional text edits
Match highlighting for recent projects picker was off, because the path
representation was compacted - for a path '/Users/hiro/Projects/zed' we
compact it to use a tilde instead of home directory. However, the
highlight positions were always calculated for a full path, leading to a
mismatch in highlights. This commit addresses this by running fuzzy
search on compacted paths instead of using long paths. This might lead
to a slight performance hit, but given that recent projects modal
shouldn't have that many items in the first place, it should be okay.
Z-2546
Release Notes:
- Fixed result highlighting in "Recent projects" modal.
Instead of storing `initialization_options` in every LSP adapter as
before, store previous LSP settings in `Project` entirely.
This way, we can later have use multiple different project
configurations per single LSP with its associated adapter.
Release Notes:
- N/A
Instead of storing `initialization_options` in every LSP adapter as
before, store previous LSP settings in `Project` entirely.
This way, we can later have use multiple different project
configurations per single LSP with its associated adapter.
co-authored-by: Max Brunsfeld <max@zed.dev>
Language servers mixed `initialization_options` from hardcodes and user
settings, fix that to ensure we restart servers on their settings
changes only.
Match highlighting for recent projects picker was off, because the path representation was compacted - for a path '/Users/hiro/Projects/zed' we compact it to use a tilde instead of home directory. However, the highlight positions were always calculated for a full path, leading to a mismatch in highlights.
This commit addresses this by running fuzzy search on compacted paths instead of using long paths. This might lead to a slight performance hit, but given that recent projects modal shouldn't have that many items in the first place, it should be okay.
Z-2546
Extract branch list into a separate vcs_menu crate akin to
recent_projects. Add current bind for a modal branch to branch popover's
tooltip.
Z-2555
Release Notes:
- N/A
As part of this I added `assert_shared_state()` to the
NeovimBackedTestContext so that it is more like a drop-in replacement
for the VimTestContext.
The remaining part of zed-industries/community#682 is adding bracket
matching to plain text. It looks like the current logic requires there
to be a tree sitter language for the language in order to support
bracket matching. I didn't fix this in this PR because I was unsure
whether to try and work around that, or to try and add a plain text tree
sitter language.
Release Notes:
- vim: support `{` and `}` for paragraph motion
([#470](https://github.com/zed-industries/community/issues/470)).
- vim: fix `%` at the end of the line
([#682](https://github.com/zed-industries/community/issues/682)).
Previously, we would only track whether the previous key down event
was a key equivalent. However, this could cause issues when pressing
certain keystrokes in rapid succession, e.g.:
- Pressing `shift-right` (to select a character)
- Pressing a character (with or without `shift` held down)
This would cause GPUI to ignore the second event because it was
preceded by a key equivalent event. With this commit, we track the
last key equivalent event, and skip the key down event only if it
matches the last key equivalent event.
Language servers such as typescript-language-servers report a single
work event, ending right after server's startup.
Other servers might send more similar event, also during startup.
The rest of the events are diagnostic-related and we filter them out.
React on such events with /refresh-like hint update, that will check
only the visible part of the editor for hints and might be replaced by
other /refresh requests, if needed.
We were updating the view's state but missed a `notify`, which caused
the `UniformList` responsible for rendering the saved conversations
to panic when some files were deleted.
Updates all collab sounds, add screen sharing sounds.
Release Notes:
- Improved collaboration sounds for joining and leaving a call, muting
and unmuting the mic.
- Added a sound when you start and stop screen sharing.
When you hit <escape> in the command palette, it first editor::Cancel
because the command palette is also a focused editor; this binding was
catching before the `menu::Cancel` that you probably want.
From looking at the uses of editor::Cancel it seems like the only way to
trigger this is with <escape> in an editor. Rather than trying to hook
into the existing editor cancel and add vim-specific behaviour, we'll
instead take responsibility for binding directly to <escape> when
necessary.
Fixes: zed-industries/community#1347
* Filter out queries for outdated buffers just before hint tasks spawn:
multicared edits might empit standalone events simultaneously
* Only spawn inlay update tasks for visible buffers with corresponding
language
* Do not spawn tasks for local projects' buffers without LSP servers
As part of an optimization in
https://github.com/zed-industries/zed/pull/2663, I changed the way that
the worktree ignores FS events within unloaded directories. But this
accidentally prevented us from detecting some events that occur inside
of `.git` directories.
In this PR, I've made further tweaks to which FS events we can ignore.
We now explicitly opt *in* to scanning `.git` (shallowly) directories
(even though they are ignored). Note that we still don't recursively
scan the git directory (including all of the files inside `objects`
etc). This seems like the correct amount of work to do, and from my
testing (and our unit tests that use the real FS and real git
repositories), it seems to work correctly.
Release Notes:
- Fixed a bug where Zed would not detect some git repository changes
(preview only).
Added .assert_shared_state() to NeovimBackedTestContext – although it's
not strictly necessary to show the expected behaviour in the test file
(as we can just compare to neovim's JSON recording), it makes it much
easier to understand what we're testing.
This PR adds a new mouse event type for catching when a click happens
outside of a given region.
This was added because I noticed a 'race condition' between the context
menu and the buttons which deploy a context menu. Buttons use on
an`on_click()` handler to deploy the context menu, but the context menu
was closing itself with an `on_down_out()` handler. This meant that the
order of operations was:
0. Context menu is open
1. User presses down on the button, _outside of the context menu_
2. `on_down_out()` is fired, closing the context menu
3. User releases the mouse
4. `click()` is fired, checks the state of the context menu, finds that
it's closed, and so opens it
You can see this behavior demonstrated with this video with a long-click
here:
https://github.com/zed-industries/zed/assets/2280405/588234c3-1567-477f-9a12-9e6a70643527
~~Switching from `on_down_out()` to `on_click_out()` means that the
click handler for the button can close the menu before the context menu
gets a chance to close itself.~~
~~However, GPUI does not have an `on_click_out()` event, hence this
PR.~~
~~Here's an example of the new behavior, with the same long-click
action:~~
https://github.com/zed-industries/zed/assets/2280405/a59f4d6f-db24-403f-a281-2c1148499413
Unfortunately, this `click_out` is the incorrect event for this to
happen on. This PR now adds a mechanism for delaying the firing of a
cancel action so that toggle buttons can signal that this on_down event
should not result in a menu closure.
Release Notes:
* Made context menus deployed from buttons toggle, instead of
hide-and-re-show, visibility on click