Many editors such as vim and emacs support "modelines", a comment at the
beginning of the file that allows the file type to be explicitly
specified along with per-file specific settings
- The amount of configurations, style and settings mapping cannot be
handled in one go, so this opens up a lot of potential improvements.
- I left out the possiblity to have "zed" specific modelines for now,
but this could be potentially interesting.
- Mapping the mode or filetype to zed language names isn't obvious
either. We may want to make it configurable.
This is my first contribution to zed, be kind. I struggled a bit to find
the right place to add those settings. I use a similar approach as done
with editorconfig (merge_with_editorconfig). There might be better ways.
Closes#4762
Release Notes:
- Add basic emacs/vim modeline support.
Supersedes #41899, changes:
- limit reading to the first and last 1kb
- add documentation
- more variables handled
- add Arc around ModelineSettings to avoid extra cloning
- changed the way mode -> language mapping is done, thanks to
`modeline_aliases` language config
- drop vim ex: support
- made "Local Variables:" handling a separate commit, so we can drop it
easily
- various code style improvements
---------
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Fixes#51733
The previous fix in #32590 only filtered `.vscode` tasks at the modal
presentation layer, so they still appeared in other code paths and in
the used-tasks list. This moves the filtering into
`worktree_scenarios()` in the task inventory, so all consumers see the
correct behavior.
Changes:
- `InventoryFor::worktree_scenarios()` now skips `.vscode` entries when
`.zed` entries exist for the same worktree
- `used_and_current_resolved_tasks()` filters previously spawned
`.vscode` tasks from the used-tasks list
- Removes the now-redundant `.vscode` filter from the task picker modal
Release Notes:
- Fixed .vscode/tasks.json still being used when .zed/tasks.json is
present
Co-authored-by: moktamd <moktamd@users.noreply.github.com>
Closes#12628
Adds a `$ZED_LANGUAGE` task variable that resolves to the language name
of the active buffer (e.g., "Rust", "Python", "Shell Script"). This lets
tasks adapt behavior based on language without parsing file extensions.
Use cases from the issue:
- Pass syntax highlighting language to external tools (e.g., `rg --type
$ZED_LANGUAGE`)
- Adjust comment wrapping width per language
- Handle extensionless files and untitled buffers that have a language
assigned
VS Code provides equivalent functionality via
`${command:activeEditorLanguageId}`. Neovim exposes it as `&filetype`.
## Changes
- Added `Language` variant to `VariableName` in
`crates/task/src/task.rs`
- Populated from `buffer.language().name()` in
`BasicContextProvider::build_context`
(`crates/project/src/task_inventory.rs`), following the same pattern as
`File` and `Stem`
- Updated test fixtures in `crates/tasks_ui/src/tasks_ui.rs` to include
the new variable
- Added `ZED_LANGUAGE` to the variable list in `docs/src/tasks.md`
## Testing
Updated the existing `test_task_variables` test in `tasks_ui` to verify
`ZED_LANGUAGE` resolves to "Rust" and "TypeScript" for the respective
test buffers.
This contribution was developed with AI assistance (Claude Code).
Release Notes:
- Added `$ZED_LANGUAGE` task variable that exposes the current buffer's
language name
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Before, both rust-analyzer's LSPext tasks and tree-sitter tasks were
queried on the entire multi buffer range.
The PR moves all runnable-related logic into a submodule, and reworks
the logic to consider only the visible buffers.
Singleton buffers have their tasks resolved for the entire range still
(same as LSPext tasks work), multi buffers have their buffers' data
cached and reused.
Release Notes:
- Improved multi buffer's runnables resolution performance
Validate task variable names when the file is saved, immediately
displaying an error toast if any invalid `ZED_*` variables are found.
Valid tasks in the same file are still loaded and work normally.
- Add `task::task_template::TaskTemplate::unknown_variables()` to detect
invalid `ZED_` variable names
- Add `project::ToastLink` struct and optional `link` field to
`project::Event::Toast`
- Show documentation link in the error toast
Closes#23275
Release Notes:
- Fixed user-defined tasks with unresolved `ZED_*` variables being
silently omitted
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Many editors such as vim and emacs support "modelines", a comment at the
beginning of the file that allows the file type to be explicitly
specified along with per-file specific settings
- The amount of configurations, style and settings mapping cannot be
handled in one go, so this opens up a lot of potential improvements.
- I left out the possiblity to have "zed" specific modelines for now,
but this could be potentially interesting.
- Mapping the mode or filetype to zed language names isn't obvious
either. We may want to make it configurable.
This is my first contribution to zed, be kind. I struggled a bit to find
the right place to add those settings. I use a similar approach as done
with editorconfig (merge_with_editorconfig). There might be better ways.
Closes#4762
Release Notes:
- Add basic emacs/vim modeline support.
Supersedes #41899, changes:
- limit reading to the first and last 1kb
- add documentation
- more variables handled
- add Arc around ModelineSettings to avoid extra cloning
- changed the way mode -> language mapping is done, thanks to
`modeline_aliases` language config
- drop vim ex: support
- made "Local Variables:" handling a separate commit, so we can drop it
easily
- various code style improvements
---------
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Gist is we only need to block the foreground thread for reparsing if
immediate language changes are useful to the user. That is usually only
the case when they edit the buffer
Release Notes:
- Improved performance of large project searches and project diffs
Co-authored by: David Kleingeld <david@zed.dev>
This PR introduces a new `MultiBufferOffset` new type wrapping size. The
goal of this is to make it clear at the type level when we are
interacting with offsets of a multi buffer versus offsets of a language
/ text buffer. This improves readability of things quite a bit by making
it clear what kind of offsets one is working with while also reducing
accidental bugs by using the wrong kin of offset for the wrong API.
This PR also uncovered two minor bugs due to that.
Does not yet introduce the MultiBufferPoint equivalent, that is for a
follow up PR.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#39172
This refactors when we resolve UI keybindings in an effort to reduce
flickering whilst painting these: Previously, we would always resolve
these upon creating the binding. This could lead to cases where the
corresponding context was not yet available and no binding could be
resolved, even if the binding was then available on the next presented
frame. Following that, on the next rerender of whatever requested this
keybinding, the keybind for that context would then be found, we would
render that and then also win a layout shift in that process, as we went
from nothing rendered to something rendered between these frames.
With these changes, this now happens less often, because we only look
for the keybinding once the context can actually be resolved in the
window.
| Before | After |
| --- | --- |
|
https://github.com/user-attachments/assets/adebf8ac-217d-4c7f-ae5a-bab3aa0b0ee8
|
https://github.com/user-attachments/assets/70a82b4b-488f-4a9f-94d7-b6d0a49aada9
|
Also reduced cloning in the keymap editor in this process, since that
requiered changing due to this anyway.
Release Notes:
- Fixed some cases where keybinds would appear with a slight delay,
causing a flicker in the process
We've been considering removing workspace-hack for a couple reasons:
- Lukas ran into a situation where its build script seemed to be causing
spurious rebuilds. This seems more likely to be a cargo bug than an
issue with workspace-hack itself (given that it has an empty build
script), but we don't necessarily want to take the time to hunt that
down right now.
- Marshall mentioned hakari interacts poorly with automated crate
updates (in our case provided by rennovate) because you'd need to have
`cargo hakari generate && cargo hakari manage-deps` after their changes
and we prefer to not have actions that make commits.
Currently removing workspace-hack causes our workspace to grow from
~1700 to ~2000 crates being built (depending on platform), which is
mainly a problem when you're building the whole workspace or running
tests across the the normal and remote binaries (which is where
feature-unification nets us the most sharing). It doesn't impact
incremental times noticeably when you're just iterating on `-p zed`, and
we'll hopefully get these savings back in the future when
rust-lang/cargo#14774 (which re-implements the functionality of hakari)
is finished.
Release Notes:
- N/A
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#36280
Release Notes:
- Added additional context to debug task selection
Adding additional context when selecting a debug task to help with
projects that have multiple config files with similar names for tasks.
I think there is room for improvement, especially adding context for a
LanguageTask type. I started but it looked like it would need to add a
path value to that and wanted to make sure this was a good idea before
working on that.
Also any thoughts on the wording if you do like this format?
---
<img width="1246" height="696" alt="image"
src="https://github.com/user-attachments/assets/b42e3f45-cfdb-4cb1-8a7a-3c37f33f5ee2"
/>
---------
Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Anthony <hello@anthonyeid.me>
This removes around 900 unnecessary clones, ranging from cloning a few
ints all the way to large data structures and images.
A lot of these were fixed using `cargo clippy --fix --workspace
--all-targets`, however it often breaks other lints and needs to be run
again. This was then followed up with some manual fixing.
I understand this is a large diff, but all the changes are pretty
trivial. Rust is doing some heavy lifting here for us. Once I get it up
to speed with main, I'd appreciate this getting merged rather sooner
than later.
Release Notes:
- N/A
This PR is one step in a series of refactors to prepare for having
"remote" projects that do not use SSH. The main use cases for this are
WSL and dev containers.
Release Notes:
- N/A
This is really just a small beginning, as there are many other icons to
be revised and cleaned up. Our current set is a bit of a mess in terms
of dimension, spacing, stroke width, and terminology. I'm sure there are
more non-used icons I'm not covering here, too. We'll hopefully tackle
it all soon leading up to 1.0.
Closes https://github.com/zed-industries/zed/issues/35576
Release Notes:
- N/A
In #32656 I generalized the argument to change selections to allow
controling both the scroll and the nav history (and the completion
trigger).
To avoid conflicting with ongoing debugger cherry-picks I left the
argument as an `impl Into<>`, but I think it's clearer to make callers
specify what they want here.
I converted a lot of `None` arguments to `SelectionEffects::no_scroll()`
to be exactly compatible; but I think many people used none as an "i
don't care" value in which case Default::default() might be more
appropraite
Closes #ISSUE
Release Notes:
- N/A
In #32656 I generalized the argument to change selections to allow
controling both the scroll and the nav history (and the completion
trigger).
To avoid conflicting with ongoing debugger cherry-picks I left the
argument as an `impl Into<>`, but I think it's clearer to make callers
specify what they want here.
I converted a lot of `None` arguments to `SelectionEffects::no_scroll()`
to be exactly compatible; but I think many people used none as an "i
don't care" value in which case Default::default() might be more
appropraite
This PR makes all footer elements in the debugger session modal more
consistent, as well as fixes some weird UI quirks with leaking borders
and whatnot. Took the opportunity to do some light style clean up and
use `prelude::*` for UI imports.
Release Notes:
- N/A
Now, every JS/TS-related file will get their package.json script
contents added as tasks:
<img width="1020" alt="image"
src="https://github.com/user-attachments/assets/5bf80f80-fd72-4ba8-8ccf-418872895a25"
/>
To achieve that, `fn associated_tasks` from the `ContextProvider` was
made asynchronous and the related code adjusted.
Release Notes:
- Added initial `package.json` scripts task autodetection
---------
Co-authored-by: Piotr Osiewicz <piotr@zed.dev>
- [x] pass LSP tasks into list_debug_scenarios
- [x] load LSP tasks only once for both modals
- [x] align ordering
- [x] improve appearance of LSP debug task icons
- [ ] reconsider how `add_current_language_tasks` works
- [ ] add a test
Release Notes:
- Debugger Beta: Added debuggable LSP tasks to the "Debug" tab of the
new process modal.
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Release Notes:
- Debugger Beta: added a button to the quick action bar to start a debug
session or spawn a task, depending on which of these actions was taken
most recently.
- Debugger Beta: incorporated the tasks modal into the new session modal
as an additional tab.
---------
Co-authored-by: Julia Ryan <juliaryan3.14@gmail.com>
Co-authored-by: Julia Ryan <p1n3appl3@users.noreply.github.com>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Mikayla <mikayla@zed.dev>
This is my first contribution to zed, let me know if I missed anything.
There is no corresponding issue/discussion.
`$ZED_RELATIVE_DIR` can be used in cases where a task's command's
filesystem namespace (e.g. inside a container) is different than the
host, where absolute paths cannot work.
I modified `relative_path` to `relative_file` after the addition of
`relative_dir`.
For top-level files, where `relative_file.parent() == Some("")`, I use
`"."` for `$ZED_RELATIVE_DIR`, which is a valid relative path in both
*nix and windows.
Thank you for building zed, and open-sourcing it. I hope to contribute
more as I use it as my primary editor.
Release Notes:
- Added ZED_RELATIVE_DIR (path to current file's directory relative to
worktree root) task variable.
* stopped fetching LSP tasks for too long (but still use the hardcoded
value for the time being — the LSP tasks settings part is a simple bool
key and it's not very simple to fit in another value there)
* introduced `prefer_lsp` language task settings value, to control
whether in the gutter/modal/both/none LSP tasks are shown exclusively,
if possible
Release Notes:
- Added a way to prefer LSP tasks over Zed tasks
I added a test to this too as one of my first steps of improving
`NewSessionModal`'s test coverage.
Release Notes:
- debugger beta: Select saved debug config when opening debug.json from
`NewSessionModal`
## Preview

### TODO
- [x] Add scenario picker to new session modal
- [x] Make debugger start action open new session modal instead of task
modal
- [x] Fix `esc` not clearing the cancelling the new session modal while
it's in scenario or attach mode
- [x] Resolve debug scenario's correctly
Release Notes:
- N/A
Split `locator` out of DebugTaskDefinition to make it clearer when
location needs to happen.
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Cole Miller <m@cole-miller.net>
To make DAP work over SSH we want to create the binary
at the project level (so we can wrap it in an `ssh` invocation
transparently).
This means not pushing the adapter down into the session, and resolving
more information ahead-of-time.
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Piotr <piotr@zed.dev>
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Piotr <piotr@zed.dev>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Anthony <anthony@zed.dev>