Instead of a menagerie of macros for implementing `Action`, now there
are just two:
* `actions!(editor, [MoveLeft, MoveRight])`
* `#[derive(..., Action)]` with `#[action(namespace = editor)]`
In both contexts, `///` doc comments can be provided and will be used in
`JsonSchema`.
In both contexts, parameters can provided in `#[action(...)]`:
- `namespace = some_namespace` sets the namespace. In Zed this is
required.
- `name = "ActionName"` overrides the action's name. This must not
contain "::".
- `no_json` causes the `build` method to always error and
`action_json_schema` to return `None`
and allows actions not implement `serde::Serialize` and
`schemars::JsonSchema`.
- `no_register` skips registering the action. This is useful for
implementing the `Action` trait
while not supporting invocation by name or JSON deserialization.
- `deprecated_aliases = ["editor::SomeAction"]` specifies deprecated old
names for the action.
These action names should *not* correspond to any actions that are
registered. These old names
can then still be used to refer to invoke this action. In Zed, the
keymap JSON schema will
accept these old names and provide warnings.
- `deprecated = "Message about why this action is deprecation"`
specifies a deprecation message.
In Zed, the keymap JSON schema will cause this to be displayed as a
warning. This is a new feature.
Also makes the following changes since this seems like a good time to
make breaking changes:
* In `zed.rs` tests adds a test with an explicit list of namespaces. The
rationale for this is that there is otherwise no checking of `namespace
= ...` attributes.
* `Action::debug_name` renamed to `name_for_type`, since its only
difference with `name` was that it
* `Action::name` now returns `&'static str` instead of `&str` to match
the return of `name_for_type`. This makes the action trait more limited,
but the code was already assuming that `name_for_type` is the same as
`name`, and it requires `&'static`. So really this just makes the trait
harder to misuse.
* Various action reflection methods now use `&'static str` instead of
`SharedString`.
Release Notes:
- N/A
Closes#31728
This PR introduced new setting `"helix_mode"`. Enabling which will
enable the `vim_mode` along with `helix` behavior.
This solves issue where `vim`'s `default_mode` was being used to switch
between mode instead of opening in `default_mode`.
When `helix_mode` is enabled switcing to `Normal mode` will now switch
to `HelixNormal`
Release Notes:
- Fixed - escape key not switching to normal mode when default_mode is
insert
- Added - `helix_mode` setting to enable/disable helix key bindings
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#32787
Follow-up to #27519 and #32408
This PR fixes an issue where the mouse cursor would stay hidden after
typing in the editor.
Before #32408, we would rerender the editor on every mouse move. Now, we
(correctly) only do this if a rerender is actually required. This caused
a small regression for hiding the mouse cursor though: Due to the view
now being cached, we do not neccessarily update the mouse cursor style
so it is shown again. The boolean is updated but the view is not,
resulting in the cursor style being kept until another action is
performed. This is an issue with both Stable and Preview (due to some
other changes, the issue is slightly worse on Preview though, see
https://github.com/zed-industries/zed/pull/32596#issuecomment-2969258800
and
https://github.com/zed-industries/zed/pull/32596#issuecomment-2969357248
for some more context).
This PR ensures that the cursor is shown again by scheduling a redraw of
the editor whenever the boolean is updated.
The change should not cause any performance regressions: In most cases
where we want to hide the mouse, the editor is about to be rerendered
anyway, hence this would not change anything. For cases where we want to
show the cursor again, this ensures that we actually end up doing so by
rerendering the editor once.
Release Notes:
- Fixed an issue where the mouse cursor would sometimes stay hidden
after typing in editors with the `hide_mouse` setting enabled.
Follow-up for https://github.com/zed-industries/zed/pull/30671
Now, when clicking on an existing selection, the cursor will change on
`mouse_up` when `drag_and_drop_selection` is `true`. When
`drag_and_drop_selection` is `false`, it will change on `mouse_down`
(previous default).
Release Notes:
- N/A
Closes#4958
Release Notes:
- Added support for drag and drop text selection. It can be disabled by
setting `drag_and_drop_selection` to `false`.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
## Overview
This PR adds the minimap feature to the Zed editor, closely following
the [design from Visual Studio
Code](https://code.visualstudio.com/docs/getstarted/userinterface#_minimap).
When configured, a second instance of the editor will appear to the left
of the scrollbar. This instance is not interactive and it has a slimmed
down set of annotations, but it is otherwise just a zoomed-out version
of the main editor instance. A thumb shows the line boundaries of the
main viewport, as well as the progress through the document. Clicking on
a section of code in the minimap will jump the editor to that code.
Dragging the thumb will act like the scrollbar, moving sequentially
through the document.

## New settings
This adds a `minimap` section to the editor settings with the following
keys:
### `show`
When to show the minimap in the editor.
This setting can take three values:
1. Show the minimap if the editor's scrollbar is visible: `"auto"`
2. Always show the minimap: `"always"`
3. Never show the minimap: `"never"` (default)
### `thumb`
When to show the minimap thumb.
This setting can take two values:
1. Show the minimap thumb if the mouse is over the minimap: `"hover"`
2. Always show the minimap thumb: `"always"` (default)
### `width`
The width of the minimap in pixels.
Default: `100`
### `font_size`
The font size of the minimap in pixels.
Default: `2`
## Providing feedback
In order to keep the PR focused on development updates, please use the
discussion thread for feature suggestions and usability feedback: #26894
## Features left to add
- [x] fix scrolling performance
- [x] user settings for enable/disable, width, text size, etc.
- [x] show overview of visible lines in minimap
- [x] clicking on minimap should navigate to the corresponding section
of code
- ~[ ] more prominent highlighting in the minimap editor~
- ~[ ] override scrollbar auto setting to always when minimap is set to
always show~
Release Notes:
- Added minimap for high-level overview and quick navigation of editor
contents.
---------
Co-authored-by: MrSubidubi <dev@bahn.sh>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Nathan here: I also tacked on a bunch of UI refinement.
Release Notes:
- Introduced the ability to follow the agent around as it reads and
edits files.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Things this doesn't currently handle:
- [x] ~testing~
- ~we really need an snapshot test that takes a vscode settings file
with all options that we support, and verifies the zed settings file you
get from importing it, both from an empty starting file or one with lots
of conflicts. that way we can open said vscode settings file in vscode
to ensure that those options all still exist in the future.~
- Discussed this, we don't think this will meaningfully protect us from
future failures, and we will just do this as a manual validation step
before merging this PR. Any imports that have meaningfully complex
translation steps should still be tested.
- [x] confirmation (right now it just clobbers your settings file
silently)
- it'd be really cool if we could show a diff multibuffer of your
current settings with the result of the vscode import and let you pick
"hunks" to keep, but that's probably too much effort for this feature,
especially given that we expect most of the people using it to have an
empty/barebones zed config when they run the import.
- [x] ~UI in the "welcome" page~
- we're planning on redoing our welcome/walkthrough experience anyways,
but in the meantime it'd be nice to conditionally show a button there if
we see a user level vscode config
- we'll add it to the UI when we land the new walkthrough experience,
for now it'll be accessible through the action
- [ ] project-specific settings
- handling translation of `.vscode/settings.json` or `.code-workspace`
settings to `.zed/settings.json` will come in a future PR, along with UI
to prompt the user for those actions when opening a project with local
vscode settings for the first time
- [ ] extension settings
- we probably want to do a best-effort pass of popular extensions like
vim and git lens
- it's also possible to look for installed/enabled extensions with `code
--list-extensions`, but we'd have to maintain some sort of mapping of
those to our settings and/or extensions
- [ ] LSP settings
- these are tricky without access to the json schemas for various
language server extensions. we could probably manage to do translations
for a couple popular languages and avoid solving it in the general case.
- [ ] platform specific settings (`[macos].blah`)
- this is blocked on #16392 which I'm hoping to address soon
- [ ] language specific settings (`[rust].foo`)
- totally doable, just haven't gotten to it yet
~We may want to put this behind some kind of flag and/or not land it
until some of the above issues are addressed, given that we expect
people to only run this importer once there's an incentive to get it
right the first time. Maybe we land it alongside a keymap importer so
you don't have to go through separate imports for those?~
We are gonna land this as-is, all these unchecked items at the bottom
will be addressed in followup PRs, so maybe don't run the importer for
now if you have a large and complex VsCode settings file you'd like to
import.
Release Notes:
- Added a VSCode settings importer, available via a
`zed::ImportVsCodeSettings` action
---------
Co-authored-by: Mikayla Maki <mikayla@zed.dev>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Closes#4495
Release Notes:
- vim: add cursor shape settings for each vim mode
---
Add cursor shape settings for each vim mode to enable users to specify
them.
Example of `settings.json`:
```json
{
"vim_mode": true,
"vim": {
"cursor_shape": {
"normal": "hollow",
"insert": "bar",
"replace": "block",
"visual": "underline"
}
}
}
```
After this change is applied,
- The cursor shape specified by the user for each mode is used.
- In insert mode, the `vim > cursor_shape > insert` setting takes
precedence over the primary `cursor_shape` setting.
- If `vim > cursor_shape > insert` is not set, the primary
`cursor_shape` will be used in insert mode.
- The cursor shape will remain unchanged before and after this update
when the user does not set the `vim > cursor_shape` setting.
Video:
[screen-record.webm](https://github.com/user-attachments/assets/b87461a1-6b3a-4a77-a607-a340f106def5)
Closes https://github.com/zed-industries/zed/issues/19731
Adds `editor::GoToPreviousChange` and `editor::GoToNextChange` that work
the same as `vim::ChangeListOlder` and `vim::ChangeListNewer` as the
common logic was extracted and reused.
Release Notes:
- Added a way to navigate between changes with
`editor::GoToPreviousChange` and `editor::GoToNextChange`
This PR lightly refactors the `EditorMode::Full` exposing two new
methods: `is_full` and `set_mode`.
Motivation is to expose fields that modify the behavior when the editor
is in `Full` mode. By using is `mode.is_full()` instead of
`EditorMode::Full` we can introduce new fields without breaking other
places in the code.
Release Notes:
- N/A
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This brings in a bunch of helix bindings (many of them from
infogulch/zed-helix-keymap) and implements helix-style delete.
Release Notes:
- vim: Expanded default helix-style keybindings in HelixNormal mode
Closes#22398
Release Notes:
- vim: Adds `'` and `"` marks (last location jumped from in the current
buffer, and location when last exiting a buffer)
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#26884
Release Notes:
- vim: Added `:marks` which brings up list of current marks
- confirming on selected mark in the view jumps to that mark
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes https://github.com/zed-industries/zed/issues/13111
Release Notes:
- vim: Added global marks `'[A-Z]`
- vim: Added persistence for global (and local) marks. When re-opening
the same workspace your previous marks will be available.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#18157
Release Notes:
- vim: Added `:reg[isters]` to show the current values of registers
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#13881, and technically resolves#14927.
Release Notes:
- Added the ability to set the default Vim mode.
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Implements [vim-exchange](https://github.com/tommcdo/vim-exchange)
functionality.
Lets you swap the content of one selection/object/motion with another.
The default key bindings are the same as in exchange:
- `cx` to begin the exchange in normal mode. Visual mode does not have a
default binding due to conflicts.
- `cxx` selects the current line
- `cxc` clears the selection
- If the previous operation was an exchange, `.` will repeat that
operation.
Closes#22759
## Overlapping regions
According to the vim exchange readme:
> If one region is fully contained within the other, it will replace the
containing region.
Zed does the following:
- If one range is completely contained within another: the smaller
region replaces the larger region (as in exchange.vim)
- If the ranges only partially overlap, then we abort and cancel the
exchange. I don't think we can do anything sensible with that. Not sure
what the original does, evil-exchange aborts.
## Not implemented: cross-window exchange
Emacs's evil-exchange allows you to exchange across buffers. There is no
code to accommodate that in this PR. Personally, it'd never occurred to
me before working on this and I've never needed it. As such, I'll leave
that implementation for whomever needs it.
As an upside; this allows you to have concurrent exchange states per
buffer, which may come in handy.
## Bonus
Also adds "replace with register" for the full line with `grr` 🐕 This
was an oversight from a previous PR.
Release notes:
- Added an implementation of `vim-exchange`
- Fixed: Added missing default key binding for `Vim::CurrentLine` for
replace with register mode (`grr`)
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes #ISSUE
Before this, in Vim mode, as long as the window loses focus, regardless
of the current cursor shape, it will definitely switch to a hollow
cursor.
Release Notes:
- Fixed vim cursor shape hollow only in block
Closes https://github.com/zed-industries/zed/issues/23505
Now `zed::IncreaseBufferFontSize` (and all the same UI- and
Buffer-related settings) action is parameterized with `{ "persist": true
}` (default).
Using `"persist": false` brings back resizing behavior prior to
https://github.com/zed-industries/zed/pull/23265
Release Notes:
- Added a way to toggle font size without settings adjustments
* Overrides the action handler to switch to insert mode after jumps.
* Returns `vim::Tab` to its behavior from before #24418
Release Notes:
- N/A
Co-authored-by: Conrad <conrad@zed.dev>
- [x] snake case keymap properties
- [x] flatten actions
- [x] keymap migration + notfication
- [x] settings migration + notification
- [x] inline completions -> edit predictions
### future:
- keymap notification doesn't show up on start up, only on keymap save.
this is existing bug in zed, will be addressed in seperate PR.
Release Notes:
- Added a notification for deprecated settings and keymaps, allowing you
to migrate them with a single click. A backup of your existing keymap
and settings will be created in your home directory.
- Modified some keymap actions and settings for consistency.
---------
Co-authored-by: Piotr Osiewicz <piotr@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
* When an edit prediction is present in non-insertion modes, hide it but
show `tab Jump to edit`.
* Removes discarding of edit predictions when going from insert mode to
normal mode, instead just hide them in non-insertion modes.
* Removes zeta-specific showing of predictions in normal mode. This
behavior was only happening in special cases anyway - where the discard
of completions wasn't happening due to some other thing taking
precedence in `dismiss_menus_and_popups`.
Release Notes:
- N/A
---------
Co-authored-by: Conrad <conrad@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>
## Context
While looking through the client crate, I noticed that some of the old
functions and variables were still using gpui::model name that was
deprecated during the gpui3 transition. This PR renames those instances
of model to entity to be more inline with gpui3.
In addition, I also renamed `model` to `entity` in cases found by the
below search terms given by @someone13574
- model = cx.
- model: Entity
- model: &Entity
- OpenedModelHandle
- model.update
- model.upgrade
- model = .*\.root (regex)
- parent_model
- model = cx.new
- cx.spawn(move |model
Release Notes:
- N/A
Closes#23334
This does not follow the exact way that windows are resized in vim.
Normally the command is `ctrl-w >` however this PR uses just `ctrl->`.
This is because I could not find a good way to read in a count like `10
ctrl-w ctrl->`. This is not really a problem since `ctrl->` can be held
down, which, in my opinion, speeds up resizing. I think this is a good
compromise since it improves usability; however, I am concerned that
this is not intuitive. I am looking forward to feedback.
Release Notes:
- Added the following commands
- vim::ResizeLeftDock
- vim::ResizeRightDock
- vim::ResizeBottomDock
- Added keybinds
- `ctrl->` for widening left dock
- `ctrl-<` for narrowing left dock
There's still a bit more work to do on this, but this PR is compiling
(with warnings) after eliminating the key types. When the tasks below
are complete, this will be the new narrative for GPUI:
- `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit
of state, and if `T` implements `Render`, then `Entity<T>` implements
`Element`.
- `&mut App` This replaces `AppContext` and represents the app.
- `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It
is provided by the framework when updating an entity.
- `&mut Window` Broken out of `&mut WindowContext` which no longer
exists. Every method that once took `&mut WindowContext` now takes `&mut
Window, &mut App` and every method that took `&mut ViewContext<T>` now
takes `&mut Window, &mut Context<T>`
Not pictured here are the two other failed attempts. It's been quite a
month!
Tasks:
- [x] Remove `View`, `ViewContext`, `WindowContext` and thread through
`Window`
- [x] [@cole-miller @mikayla-maki] Redraw window when entities change
- [x] [@cole-miller @mikayla-maki] Get examples and Zed running
- [x] [@cole-miller @mikayla-maki] Fix Zed rendering
- [x] [@mikayla-maki] Fix todo! macros and comments
- [x] Fix a bug where the editor would not be redrawn because of view
caching
- [x] remove publicness window.notify() and replace with
`AppContext::notify`
- [x] remove `observe_new_window_models`, replace with
`observe_new_models` with an optional window
- [x] Fix a bug where the project panel would not be redrawn because of
the wrong refresh() call being used
- [x] Fix the tests
- [x] Fix warnings by eliminating `Window` params or using `_`
- [x] Fix conflicts
- [x] Simplify generic code where possible
- [x] Rename types
- [ ] Update docs
### issues post merge
- [x] Issues switching between normal and insert mode
- [x] Assistant re-rendering failure
- [x] Vim test failures
- [x] Mac build issue
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Joseph <joseph@zed.dev>
Co-authored-by: max <max@zed.dev>
Co-authored-by: Michael Sloan <michael@zed.dev>
Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local>
Co-authored-by: Mikayla <mikayla.c.maki@gmail.com>
Co-authored-by: joão <joao@zed.dev>
Co-Authored-By: Jon Walstedt <jon@walstedt.se>
Closes#22094
Release Notes:
- vim: Added support for ctrl-g
Co-authored-by: Jon Walstedt <jon@walstedt.se>
Closes#22885Closes#12565
This doesn't yet add history in the command palette, which is painfully
missing.
Release Notes:
- vim: Added `:!`, `:<range>!` and `:r!` support
- vim: Added `!` operator in normal/visual mode
Also:
* Adds `impl_internal_actions!` for deriving the `Action` trait without
registering.
* Removes some deserializers that immediately fail in favor of
`#[serde(skip)]` on fields where they were used. This also omits them
from the schema.
Release Notes:
- Keymap settings file now has more JSON schema information to inform
`json-language-server` completions and info, particularly for actions
that take input.
This fixes the issue described in this comment:
https://github.com/zed-industries/zed/pull/22439#issuecomment-2563896422
Essentially, we'd clip in the wrong direction when there were multi-line
inlay hints.
It also fixes inline completions for non-Zeta-providers showing up in
normal mode.
Release Notes:
- N/A
This is harmful for user experience and at best requires a user setting.
This was committed as part of
https://github.com/zed-industries/zed/pull/21739 however that change had
no relevant release notes and no relevant settings.
The issue #22343 shows how this can result in user experience
regression: deleting a text fragment can reinsert it back, and it's thus
unclear if the deletion has even worked. Maybe this can be reenabled in
some very restrictive setup, and put behind a setting, but it can't be
unconditional. Completions should activate when the user signals intent
of entering code - for example, if instead of `de` to delete a fragment,
I press `ce` to replace it, I would naturally expect inline completions
to show up.
Note: The linked PR added more code in vim crate to refresh inline
completions in normal mode. I'm keeping that code around in this commit,
so that this can be the minimal fix to the linked issue -- with the
assumption that maybe there's some way in the future to reenable this in
a subset of cases that don't result in confusing / broken UX. If that is
not true the code might need further cleanup. Let me know if you'd
rather see removal of those changes in this PR as well.
Closes#22343.
Release Notes:
- Fixes inline completions showing up in Vim normal mode.
The cursor shape now only changes to underline for operators that modify
text (like: delete, change, yank) while maintaining block shape for
navigation operators (like: find, till).
This better matches Vim/Nvim's behavior where the cursor only changes
shape when an operator that will modify text is pending.
Release Notes:
- vim: Improved cursor shape behavior to better match Vim
Closes#4642
- Added the ability to switch to helix normal mode, with an additional
helix visual mode.
- <kbd>ctrl</kbd><kbd>h</kbd> from Insert mode goes to Helix Normal
mode. <kbd> i </kbd> and <kbd> a </kbd> to go back.
- Need to find a way to perform the helix normal mode selection with
<kbd> w </kbd>, <kbd>e </kbd>, <kbd> b </kbd> as a first step. Need to
figure out how the mode will interoperate with the VIM mode as the new
additions are in the same crate.