Follow-up to #39649, possible fix for #39669
This implements an alternate strategy for showing/hiding the agent panel
in response to `disable_ai`. We don't load the panel at all if AI is
disabled at startup, and when the value of `disable_ai` changes, we load
the panel or destroy it as needed.
Release Notes:
- N/A
Prior we only logged the crate in `log_err`, which is not too helpful.
We now assemble the module path from the file system path.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Before this change the active theme and icon theme were retrofitted onto
the ThemeSettings.
Now they're in their own new global (GlobalTheme::theme(cx) and
GlobalTheme::icon_theme(cx))
This lets us remove cx from the settings traits, and tidy up a few other
things along the way.
Release Notes:
- N/A
Closes#5355
Release Notes:
- Fixed rendering glitches with files with more than 16 million lines
(that occured due to floating number rounding errors).
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
### Summary
* Auto-activates the active repository when opening a buffer.
* Prepares branching for future support of a user choice (e.g.,
`auto_activate_repo_on_open` flag).
### Release Notes
* **Improved**: Opening a buffer now automatically updates the active
repository.
Thanks to @Zertsov for #37932 which caused me to consider this
implementation approach.
One known issue with this is that it will not wait for actions that do
async work to complete. Supporting this would require quite a lot of
code change. It also doesn't affect the main usecase of sequencing
editor actions, since few are async.
Another caveat is that this is implemented as an action handler on
workspace and so won't work in other types of windows. This seems fine
for now, since action sequences don't seem useful in other window types.
The command palette isn't accessible in non-workspace windows.
Alternatives considered:
* Add `cx: &App` to `Action::build`. This would allow removal of the
special case in keymap parsing. Decided not to do this, since ideally
`build` is a pure function of the input json.
* Build it more directly into GPUI. The main advantage of this would be
the potential to handle non-workspace windows. Since it's possible to do
outside of GPUI, seems better to do so. While some aspects of the GPUI
action system are pretty directly informed by the specifics of Zed's
keymap files, it seems to avoid this as much as possible.
* Bake it more directly into keymap syntax like in #37932. While I think
it would be good for this to be a primitive in the JSON syntax, it seems
like it would better fit in a more comprehensive change to provide
better JSON structure. So in the meantime it seems better to keep the
structure the same and just add a new action.
- Another reason to not bake it in yet is that this provides a place to
document the caveat about async actions.
Closes#17710
Release Notes:
- Added support for action sequences in keymaps. Example:
`["action::Sequence", [ ["editor::SelectLargerSyntaxNode",
"editor::Copy", "editor::UndoSelection"]`
---------
Co-authored-by: Mitchel Vostrez <mitch@voz.dev>
The state of the child bounds is not up-to-date when `scroll_to_item`
gets triggered, causing the new tab to not scroll completely into view.
Closes#36317
Release Notes:
- Fix an issue where a new tab is only partially visible on creation.
Fixes two inconsistencies around the behavior of cmd-alt-click that mess
with my VSCode muscle memory:
- The definition is opened in a pane to the right of the current pane,
unless there exists an adjacent pane to the left and not to the right,
in which case it's opened in the pane on the left
- In case Go to Definition needs to open a multibuffer, cmd-alt-click
does not open it in an existing pane to the right of the current pane,
it always creates a new pane directly to the right of the current pane
This PR irons out this behavior by always going to the definition in the
pane directly to the right of the current one, creating one only if one
doesn't yet exist.
If changing `Workspace::adjacent_pane` to not consider an existing pane
to the left is undesirable then that logic could be moved somewhere
else, or we can make it user configurable if necessary. Also happy to
split this PR up if either of these changes is controversial 🙂
Before:
https://github.com/user-attachments/assets/395754cd-6ecb-40bf-ae61-ee8903eed4ae
After:
https://github.com/user-attachments/assets/002797b1-51a7-48e5-a8d0-100d3a5049eb
Release Notes:
- Made the behavior of cmd-alt-click more consistent
---------
Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
I was trying to use the new user toolchains but every time I clicked on
one I had added, it would delete it from the picker. Ironically, it
wouldn't delete it permanently when I tried to by clicking on the trash
can icon. Every time I reopened the workspace all user toolchains were
there.
Release Notes:
- Fixed selecting and deleting user toolchains.
Closes https://github.com/zed-industries/zed/issues/38690Closes#37353
### Background
On Windows, paths are normally separated by `\`, unlike mac and linux
where they are separated by `/`. When editing code in a project that
uses a different path style than your local system (e.g. remoting from
Windows to Linux, using WSL, and collaboration between windows and unix
users), the correct separator for a path may differ from the "native"
separator.
Previously, to work around this, Zed converted paths' separators in
numerous places. This was applied to both absolute and relative paths,
leading to incorrect conversions in some cases.
### Solution
Many code paths in Zed use paths that are *relative* to either a
worktree root or a git repository. This PR introduces a dedicated type
for these paths called `RelPath`, which stores the path in the same way
regardless of host platform, and offers `Path`-like manipulation APIs.
RelPath supports *displaying* the path using either separator, so that
we can display paths in a style that is determined at runtime based on
the current project.
The representation of absolute paths is left untouched, for now.
Absolute paths are different from relative paths because (except in
contexts where we know that the path refers to the local filesystem)
they should generally be treated as opaque strings. Currently we use a
mix of types for these paths (std::path::Path, String, SanitizedPath).
Release Notes:
- N/A
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Peter Tripp <petertripp@gmail.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
Closes https://github.com/zed-industries/zed/issues/38547
Release Notes:
- Reverted the ability to show/hide the titlebar. This caused rendering
bugs on
macOS, and we're preparing for the redesign which requires the toolbar
being present.
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
When we refactored settings to not pass JSON blobs around, we ended up
needing
to write *a lot* of code that just merged things (like json merge used
to do).
Use a derive macro to prevent typos in this logic.
Release Notes:
- N/A
Co-Authored-By: Ben K <ben@zed.dev>
Co-Authored-By: Anthony <anthony@zed.dev>
Co-Authored-By: Mikayla <mikayla@zed.dev>
Release Notes:
- settings: Major internal changes to settings. The primary user-facing
effect is that some settings which did not make sense in project
settings files are no-longer read from there. (For example the inline
blame settings)
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Co-authored-by: Anthony <anthony@zed.dev>
Closes#37473
### Background
Previously, we enabled foreign keys at all times for our sqlite database
that we use for client-side state.
The problem with this is that In sqlite, `alter table` is somewhat
limited, so for many migrations, you must *recreate* the table: create a
new table called e.g. `workspace__2`, then copy all of the data from
`workspaces` into `workspace__2`, then delete the old `workspaces` table
and rename `workspaces__2` to `workspaces`. The way foreign keys work in
sqlite, when we delete the old table, all of its associated records in
other tables will be deleted due to `on delete cascade` clauses.
Unfortunately, one of the types of associated records that can be
deleted are `editors`, which sometimes store unsaved text. It is very
bad to delete these records, as they are the *only* place that this
unsaved text is stored.
This has already happened multiple times as we have migrated tables as
we develop Zed, but I caused it to happened again in
https://github.com/zed-industries/zed/pull/36714.
### The Fix
The Sqlite docs recommend a multi-step approach to migrations where you:
* disable foreign keys
* start a transaction
* create a new table
* populate the new table with data from the old table
* delete the old table
* rename the new table to the old name
* run a foreign key check
* if it passes, commit the transaction
* enable foreign keys
In this PR, I've adjusted our sqlite migration code path to follow this
pattern more closely. Specifically, we disable foreign key checks before
running migrations, run a foreign key check before committing, and then
enable foreign key checks after the migrations are done.
In addition, I've added a generic query that we run *before* running the
foreign key check that explicitly deletes any rows that have dangling
foreign keys. This way, we avoid failing the migration (and breaking the
app) if a migration deletes data that *does* cause associated records to
need to be deleted.
But now, in the common case where we migrate old data in the new table
and keep the ids, all of the associated data will be preserved.
Release Notes:
- Fixed a bug where workspace state would be lost when upgrading from
Zed 0.201.x. or below.
- **toolchains: Add new state to toolchain selector**
- **Use toolchain term for Add Toolchain button**
- **Hoist out a meta function for toolchain listers**
Closes#27332
Release Notes:
- python: Users can now specify a custom path to their virtual
environment from within the picker.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-Authored-By: Brandan <b5@n0.computer>
Release Notes:
- Added a new action `terminal::Toggle` that is by default bound to
'ctrl-\`'. This copies the default behaviour from VSCode and Jetbrains
where the terminal opens and closes correctly. If you'd like the old
behaviour you can rebind 'ctrl-\`' to `terminal::ToggleFocus`
Co-authored-by: Brandan <b5@n0.computer>
In an effort to improve the experience while developing extensions and
improving themes, this PR updates the syntax tree views behavior
slightly.
Before, the view would always update to the current active editor whilst
being used. This was quite painful for improving extension scheme files,
as you would always have to change back and forth between editors to
have a view at the relevant syntax tree.
With this PR, the syntax tree view will now stay attached to the editor
it was opened in, similar to preview views. Once the view is shown, the
`UseActiveEditor` will become available in the command palette and
enable the user to update the view to the last focused editor. On file
close, the view will also be updated accordingly.
https://github.com/user-attachments/assets/922075e5-9da0-4c1d-9e1a-51e024bf41ea
A button is also shown whenever switching is possible.
Futhermore, improved the empty state of the view.
Lastly, a drive-by cleanup of the `show_action_types` method so there is
no need to call `iter()` when calling the method.
Release Notes:
- The syntax tree view will now stay attached to the buffer it was
opened in, similar to the Markdown preview. Use the `UseActiveEditor`
action when the view is shown to change it to the last focused editor.
This PR separates out the associated constant `KEY` from the `Settings`
trait into a new trait `SettingsKey`. This allows for the key trait to
be derived using attributes to specify the path so that the new
`SettingsUi` derive macro can use the same attributes to determine top
level settings paths thereby removing the need to duplicate the path in
both `Settings::KEY` and `#[settings_ui(path = "...")]`
Co-authored-by: Ben Kunkle <ben@zed.dev>
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
This PR cleans up some emitted events around the codebase. These events
are either never emitted or never listened for.
It seems better to re-implement these at some point should they again be
needed - this ensures that they will actually be fired in the cases
where they are needed as opposed to being there and getting unreliable
and stale (which is already the case for the majority of the events
removed here).
Lastly, this ensures the `CapabilitiesChanged` event is not fired too
often.
Release Notes:
- N/A
Closes #ISSUE
Initially, the `SettingsUi` trait was tied to `Settings`, however, given
that the `Settings::FileContent` type (which may be the same as the type
that implements `Settings`) will be the type that more directly maps to
the JSON structure (and therefore have the documentation, correct field
names (or `serde` rename attributes), etc) it makes more sense to have
the deriving of `SettingsUi` occur on the `FileContent` type rather than
the `Settings` type.
In order for this to work a relatively important change had to be made
to the derive macro, that being that it now "unwraps" options into their
inner type, so a field with type `Option<Foo>` where `Foo: SettingsUi`
will treat the field as if it were just `Foo`, expecting there to be a
default set in `default.json`. This imposes some restrictions on what
`Settings::FileContent` can be as seen in 1e19398 where `FileContent`
itself can't be optional without manually implementing `SettingsUi`, as
well as introducing some risk that if the `FileContent` type has
`serde(default)`, the default value will override the default value from
`default.json` in the UI even though it may differ (but it should!).
A future PR should probably replace the other settings with `FileContent
= Option<T>` (all of which currently have `T == bool`) with wrapper
structs and have `KEY = None` so the further niceties
`derive(SettingsUi)` will provide such as path renaming, custom UI, auto
naming and doc comment extraction can be used.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Follow-up to https://github.com/zed-industries/zed/pull/37035
In the WSL PR, `ssh_connection_id` was renamed to
`remote_connection_id`. However, that was not accounted for within the
`recent_workspaces_query`. This caused a query fail:
```
2025-08-30T14:45:44+02:00 ERROR [recent_projects] Prepare call failed for query:
SELECT
workspace_id,
paths,
paths_order,
ssh_connection_id
FROM
workspaces
WHERE
paths IS NOT NULL
OR ssh_connection_id IS NOT NULL
ORDER BY
timestamp DESC
Caused by:
Sqlite call failed with code 1 and message: Some("no such column: ssh_connection_id")
```
and resulted in no recent workspaces being shown within the recent
projects picker.
This change updates the column name to the new name and thus fixes the
error.
Release Notes:
- N/A
## Goal
This PR creates the initial settings ui structure with the primary goal
of making a settings UI that is
- Comprehensive: All settings are available through the UI
- Correct: Easy to understand the underlying JSON file from the UI
- Intuitive
- Easy to implement per setting so that UI is not a hindrance to future
settings changes
### Structure
The overall structure is settings layer -> data layer -> ui layer.
The settings layer is the pre-existing settings definitions, that
implement the `Settings` trait. The data layer is constructed from
settings primarily through the `SettingsUi` trait, and it's associated
derive macro. The data layer tracks the grouping of the settings, the
json path of the settings, and a data representation of how to render
the controls for the setting in the UI, that is either a marker value
for the component to use (avoiding a dependency on the `ui` crate) or a
custom render function.
Abstracting the data layer from the ui layer allows crates depending on
`settings` to implement their own UI without having to add additional UI
dependencies, thus avoiding circular dependencies. In cases where custom
UI is desired, and a creating a custom render function in the same crate
is infeasible due to circular dependencies, the current solution is to
implement a marker for the component in the `settings` crate, and then
handle the rendering of that component in `settings_ui`.
### Foundation
This PR creates a macro and a trait both called `SettingsUi`. The
`SettingsUi` trait is added as a new trait bound on the `Settings`
trait, this allows the type system to guarantee that all settings
implement UI functionality. The macro is used to derived the trait for
most types, and can be modified through attributes for unique cases as
well.
A derive-macro is used to generate the settings UI trait impl, allowing
it the UI generation to be generated from the static information in our
code base (`default.json`, Struct/Enum names, field names, `serde`
attributes, etc). This allows the UI to be auto-generated for the most
part, and ensures consistency across the UI.
#### Immediate Follow ups
- Add a new `SettingsPath` trait that will be a trait bound on
`SettingsUi` and `Settings`
- This trait will replace the `Settings::key` value to enable
`SettingsUi` to infer the json path of it's derived type
- Figure out how to render `Option<T> where T: SettingsUi` correctly
- Handle `serde` attributes in the `SettingsUi` proc macro to correctly
get json path from a type's field and identity
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Follow-up of https://github.com/zed-industries/zed/pull/36764
* Fix `anyhow!({e})` conversion lossing Collab error codes context when
opening a buffer remotely
* Use this context to only allow opening files that had not specific
Collab error code
Release Notes:
- N/A
This PR makes it so the channel list will still be shown while
reconnecting to Collab instead of showing the signed-out state.
In order to model the transitional states that occur while reconnecting,
we needed to introduce a new `Status::Reauthenticated` state that we go
through when signing in as part of a reconnect. This is because we
cannot tell from `Status::Authenticated` alone if we're authenticating
for the first time or reauthenticating.
Release Notes:
- N/A
Instead of manually constructing the venv we now ask the python
toolchain for the relevant information, unifying the approach of vent
inspection
Fixes https://github.com/zed-industries/zed/issues/27350
Release Notes:
- Improved the detection of python virtual environments for terminals
and tasks in remote projects.
Enables LSP log tracing in both remote collab and remote ssh
environments.
Server logs and server RPC traces can now be viewed remotely, and the
LSP button is now shown in such projects too.
Closes https://github.com/zed-industries/zed/issues/28557
Co-Authored-By: Kirill <kirill@zed.dev>
Co-Authored-By: Lukas <lukas@zed.dev>
Release Notes:
- Enabled LSP log tracing in both remote collab and remote ssh
environments
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Lukas Wirth <lukas@zed.dev>
This is a pure refactor that consolidates all SSH remoting logic such
that it should be straightforward to add another transport to the
remoting system.
Release Notes:
- N/A
---------
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>