# Objective Closes #4868. Reintroduce automatic language detection for user-created untitled buffers without allowing it to override language choices made by users or owning surfaces. More details: + https://github.com/zed-industries/zed/pull/61201 + https://github.com/zed-industries/zed/pull/61351 ## Solution VS Code distinguishes between inferred and explicitly selected languages, and only continues automatic detection in the former state. This change introduces a buffer-local opt-in flag with the same purpose. It defaults to disabled and is enabled only for user-created untitled buffers and restored untitled buffers that did not persist a language. Choosing a language through the language picker disables detection, while automatically detected languages remain eligible for later redetection. Buffers whose language is assigned by their owning surface, such as Channel Notes, never opt in. Rather than adding persisted state or changing the database schema, restoration reuses the existing optional serialized language. An opted-in buffer that remains Plain Text is serialized without a language and resumes detection after restoration. Once automatic detection has selected a language, that language is serialized normally and restoration leaves detection disabled, effectively treating it as an explicit selection. This also matches VS Code's effective default after restoration. Candidate selection adopts VS Code's confidence-group filtering. Results below the minimum confidence are discarded, and candidate groups are accepted only after a clear confidence gap. The detector then selects the first available Zed language without eagerly loading every candidate. I then added a separate switching rule: Zed keeps the current language unless another candidate has a clear confidence advantage, reducing language changes as model scores fluctuate during editing. Model inference runs off-thread on a bounded sample, and stale results are discarded. I also evaluated penalizing YAML and using stricter global switching thresholds, but neither reliably resolves the ambiguity between Markdown and YAML. In the reproduction from #61351, Betlang assigns YAML more than 80% confidence during editing and peaks around 90%. This is reasonable from the content alone: `#` denotes a YAML comment, while `-` denotes a sequence item. Adding ordinary prose or a fenced code block shifts the model strongly toward Markdown. A fixed penalty would overfit this example and risk suppressing legitimate YAML detection. Since known-language buffers do not opt in and manual language selection takes precedence, I consider this level of ambiguity acceptable and prefer not to introduce language-specific score tuning. Model inference itself is fast. As noted in #61201: > In release builds on Linux with an Intel Core i5-13600KF, the `betlang::detect` call alone typically completes within 3 ms when processing the maximum sampled input. The main concern is the work surrounding inference. Without debouncing, rapid typing creates a snapshot and launches a background detection task on every keystroke, while the detected language may change before the user has finished typing. This change therefore adds a 200 ms debounce delay, allowing detection to run and update the language only after the user pauses. ## Testing Automated coverage verifies that short inputs remain Plain Text, sufficient Rust content is detected as Rust, replacing it with Go content triggers redetection, and manually selecting Plain Text prevents subsequent automatic changes. Restoration coverage verifies that a stored language keeps detection disabled, while an empty language-less untitled buffer resumes detection. Beyond the automated tests, I manually tested automatic language detection while editing untitled buffers. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase https://github.com/user-attachments/assets/103fc731-e12e-48d6-ae89-03978f1c9d74 --- Release Notes: - Added automatic language detection for untitled buffers. --------- Co-authored-by: Max Stevens <maxstevens2708@gmail.com> Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
21 KiB
title, description
| title | description |
|---|---|
| How to Migrate from VS Code to Zed | Guide for migrating from VS Code to Zed, including settings and keybindings. |
How to Migrate from VS Code to Zed
This guide explains how to move from VS Code to Zed without rebuilding your workflow.
It covers which settings import automatically, which shortcuts map cleanly, and which behaviors differ so you can adjust quickly.
Install Zed
Zed is available on macOS, Windows, and Linux.
For macOS, you can download it from zed.dev/download, or install via Homebrew:
brew install --cask zed
For most Linux users, the easiest way to install Zed is through our installation script:
curl -f https://zed.dev/install.sh | sh
After installation, you can launch Zed from your Applications folder (macOS) or directly from the terminal (Linux) using:
zed .
This opens the current directory in Zed.
Import Settings from VS Code
During setup, you have the option to import key settings from VS Code. Zed imports the following settings:
Settings Imported from VS Code
The following VS Code settings are automatically imported when you use Import Settings from VS Code:
Editor
| VS Code Setting | Zed Setting |
|---|---|
editor.fontFamily |
buffer_font_family |
editor.fontSize |
buffer_font_size |
editor.fontWeight |
buffer_font_weight |
editor.tabSize |
tab_size |
editor.insertSpaces |
hard_tabs (inverted) |
editor.wordWrap |
soft_wrap |
editor.wordWrapColumn |
preferred_line_length |
editor.cursorStyle |
cursor_shape |
editor.cursorBlinking |
cursor_blink |
editor.renderLineHighlight |
current_line_highlight |
editor.lineNumbers |
gutter.line_numbers, relative_line_numbers |
editor.showFoldingControls |
gutter.folds |
editor.minimap.enabled |
minimap.show |
editor.minimap.autohide |
minimap.show |
editor.minimap.showSlider |
minimap.thumb |
editor.minimap.maxColumn |
minimap.max_width_columns |
editor.stickyScroll.enabled |
sticky_scroll.enabled |
editor.scrollbar.horizontal |
scrollbar.axes.horizontal |
editor.scrollbar.vertical |
scrollbar.axes.vertical |
editor.mouseWheelScrollSensitivity |
scroll_sensitivity |
editor.fastScrollSensitivity |
fast_scroll_sensitivity |
editor.cursorSurroundingLines |
vertical_scroll_margin |
editor.hover.enabled |
hover_popover_enabled |
editor.hover.delay |
hover_popover_delay |
editor.hover.sticky |
hover_popover_sticky |
editor.hover.hidingDelay |
hover_popover_hiding_delay |
editor.parameterHints.enabled |
auto_signature_help |
workbench.editor.languageDetection |
language_detection |
editor.multiCursorModifier |
multi_cursor_modifier |
editor.selectionHighlight |
selection_highlight |
editor.roundedSelection |
rounded_selection |
editor.find.seedSearchStringFromSelection |
seed_search_query_from_cursor |
editor.rulers |
wrap_guides |
editor.renderWhitespace |
show_whitespaces |
editor.guides.indentation |
indent_guides.enabled |
editor.linkedEditing |
linked_edits |
editor.autoSurround |
use_auto_surround |
editor.formatOnSave |
format_on_save |
editor.formatOnPaste |
auto_indent_on_paste |
editor.formatOnType |
use_on_type_format |
editor.trimAutoWhitespace |
remove_trailing_whitespace_on_save |
editor.suggestOnTriggerCharacters |
show_completions_on_input |
editor.suggest.showWords |
completions.words |
editor.inlineSuggest.enabled |
show_edit_predictions |
Files & Workspace
| VS Code Setting | Zed Setting |
|---|---|
files.autoSave |
autosave |
files.autoSaveDelay |
autosave.milliseconds |
files.insertFinalNewline |
ensure_final_newline_on_save |
files.associations |
file_types |
files.watcherExclude |
file_scan_exclusions |
files.watcherInclude |
file_scan_inclusions |
files.simpleDialog.enable |
use_system_path_prompts |
search.smartCase |
use_smartcase_search |
search.useIgnoreFiles |
search.include_ignored |
Terminal
| VS Code Setting | Zed Setting |
|---|---|
terminal.integrated.fontFamily |
terminal.font_family |
terminal.integrated.fontSize |
terminal.font_size |
terminal.integrated.lineHeight |
terminal.line_height |
terminal.integrated.cursorStyle |
terminal.cursor_shape |
terminal.integrated.cursorBlinking |
terminal.blinking |
terminal.integrated.copyOnSelection |
terminal.copy_on_select |
terminal.integrated.scrollback |
terminal.max_scroll_history_lines |
terminal.integrated.macOptionIsMeta |
terminal.option_as_meta |
terminal.integrated.{platform}Exec |
terminal.shell |
terminal.integrated.env.{platform} |
terminal.env |
Tabs & Panels
| VS Code Setting | Zed Setting |
|---|---|
workbench.editor.showTabs |
tab_bar.show |
workbench.editor.showIcons |
tabs.file_icons |
workbench.editor.tabActionLocation |
tabs.close_position |
workbench.editor.tabActionCloseVisibility |
tabs.show_close_button |
workbench.editor.focusRecentEditorAfterClose |
tabs.activate_on_close |
workbench.editor.enablePreview |
preview_tabs.enabled |
workbench.editor.enablePreviewFromQuickOpen |
preview_tabs.enable_preview_from_file_finder |
workbench.editor.enablePreviewFromCodeNavigation |
preview_tabs.enable_preview_from_code_navigation |
workbench.editor.editorActionsLocation |
tab_bar.show_tab_bar_buttons |
workbench.editor.limit.enabled / value |
max_tabs |
workbench.editor.restoreViewState |
restore_on_file_reopen |
workbench.statusBar.visible |
status_bar.show |
Project Panel (File Explorer)
| VS Code Setting | Zed Setting |
|---|---|
explorer.compactFolders |
project_panel.auto_fold_dirs |
explorer.autoReveal |
project_panel.auto_reveal_entries |
explorer.excludeGitIgnore |
project_panel.hide_gitignore |
problems.decorations.enabled |
project_panel.show_diagnostics |
explorer.decorations.badges |
project_panel.git_status |
Git
| VS Code Setting | Zed Setting |
|---|---|
git.enabled |
git_panel.button |
git.defaultBranchName |
git_panel.fallback_branch_name |
git.decorations.enabled |
git.inline_blame, project_panel.git_status |
git.blame.editorDecoration.enabled |
git.inline_blame.enabled |
Window & Behavior
| VS Code Setting | Zed Setting |
|---|---|
window.confirmBeforeClose |
confirm_quit |
window.nativeTabs |
use_system_window_tabs |
window.closeWhenEmpty |
when_closing_with_no_tabs |
accessibility.dimUnfocused.enabled / opacity |
active_pane_modifiers.inactive_opacity |
Other
| VS Code Setting | Zed Setting |
|---|---|
http.proxy |
proxy |
npm.packageManager |
node.npm_path |
telemetry.telemetryLevel |
telemetry.metrics, telemetry.diagnostics |
outline.icons |
outline_panel.file_icons, outline_panel.folder_indicator |
chat.agent.enabled |
agent.enabled |
mcp |
context_servers |
Zed doesn’t import extensions or keybindings, but this import gets core editor behavior close to your VS Code setup. If you skip that step during setup, you can still import settings manually later via the command palette:
Cmd+Shift+P → {#action zed::ImportVsCodeSettings}
Set Up Editor Preferences
You can configure most settings in the Settings Editor ({#kb zed::OpenSettings}). For advanced settings, run {#action zed::OpenSettingsFile} from the Command Palette to edit your settings file directly.
Here’s how common VS Code settings translate:
| VS Code | Zed | Notes |
|---|---|---|
| editor.fontFamily | buffer_font_family | Zed uses Zed Mono by default |
| editor.fontSize | buffer_font_size | Set in pixels |
| editor.tabSize | tab_size | Can override per language |
| editor.insertSpaces | insert_spaces | Boolean |
| editor.formatOnSave | format_on_save | Works with formatter enabled |
| editor.wordWrap | soft_wrap | Supports optional wrap column |
Zed also supports per-project settings. You can find these in the Settings Editor as well.
Open or Create a Project
After setup, press Cmd+O (Ctrl+O on Linux) to open a folder. By default, new folders open in the current window's threads sidebar, letting you work on multiple projects without juggling windows. See Windows & Projects for details on managing multiple projects and opening in new windows.
To start a new project, create a directory using your terminal or file manager, then open it in Zed. The editor will treat that folder as the root of your project.
You can also launch Zed from the terminal inside any folder with:
zed .
Once inside a project, use Cmd+P to jump between files quickly. Cmd+Shift+P (Ctrl+Shift+P on Linux) opens the command palette for running actions / tasks, toggling settings, or starting a collaboration session.
Open buffers appear as tabs across the top. The Project Panel shows your file tree and Git status. Collapse it with Cmd+B for a distraction-free view.
Differences in Keybindings
If you chose the VS Code keymap during onboarding, most shortcuts should already feel familiar. Here’s a quick reference for where keybindings match and where they differ.
Common Shared Keybindings (Zed <> VS Code)
| Action | Shortcut |
|---|---|
| Find files | Cmd + P |
| Run a command | Cmd + Shift + P |
| Search text (project-wide) | Cmd + Shift + F |
| Find symbols (project-wide) | Cmd + T |
| Find symbols (file-wide) | Cmd + Shift + O |
| Toggle left dock | Cmd + B |
| Toggle bottom dock | Cmd + J |
| Open terminal | Ctrl + ~ |
| Open file tree explorer | Cmd + Shift + E |
| Close current buffer | Cmd + W |
| Close whole project | Cmd + Shift + W |
| Refactor: rename symbol | F2 |
| Change theme | Cmd + K, Cmd + T |
| Wrap text | Opt + Z |
| Navigate open tabs | Cmd + Opt + Arrow |
| Syntactic fold / unfold | Cmd + Opt + { or } |
Different Keybindings (Zed <> VS Code)
| Action | VS Code | Zed |
|---|---|---|
| Open recent project | Ctrl + R |
Cmd + Opt + O |
| Move lines up/down | Opt + Up/Down |
Cmd + Ctrl + Up/Down |
| Split panes | Cmd + \ |
Cmd + K, Arrow Keys |
| Expand Selection | Shift + Alt + Right |
Opt + Up |
Unique to Zed
| Action | Shortcut | Notes |
|---|---|---|
| Toggle right dock | Cmd + R or Cmd + Alt + B |
|
| Syntactic selection | Opt + Up/Down |
Selects code by structure (e.g., inside braces). |
How to Customize Keybindings
To edit your keybindings:
- Open the command palette (
Cmd+Shift+P) - Run {#action zed::OpenKeymap}
This opens a list of all available bindings. You can override individual shortcuts, remove conflicts, or build a layout that works better for your setup.
Zed also supports chords (multi-key sequences) like Cmd+K Cmd+C, like VS Code does.
Differences in User Interfaces
Projects and Windows
VS Code uses a dedicated Workspace concept, with multi-root folders, .code-workspace files, and a clear distinction between “a window” and “a workspace.”
Zed takes a different approach.
In Zed:
-
Multiple projects in one window: You can open multiple folders in the same window. Each appears in the threads sidebar on the left, and you can switch between them while preserving your layout and agent threads. See Windows & Projects.
-
No workspace file format: There’s no
.code-workspaceequivalent. Opening a folder is your project context. -
Add Folder to Project: If you want multiple folders in the same project (like VS Code’s multi-root), use File > Add Folder to Project. This adds another root to your current project’s file tree.
-
Per-project settings are optional: You can add a
.zed/settings.jsonfile inside a project to override global settings. -
You can start from a single file or an empty window: Zed doesn’t require you to open a folder to begin editing.
The result is flexibility without complexity: multiple projects per window via the sidebar, or multiple folders per project via Add Folder to Project.
Navigating in a Project
In VS Code, the standard entry point is opening a folder. From there, the left-hand panel is central to navigation. Zed takes a different approach:
- You can still open folders, but you don’t need to. Opening a single file or even starting with an empty workspace is valid.
- The Command Palette (
Cmd+Shift+P) and File Finder (Cmd+P) are primary navigation tools. The File Finder searches files, symbols, and commands across the workspace. - Instead of a persistent panel, Zed encourages you to:
- Fuzzy-find files by name (
Cmd+P) - Jump directly to symbols (
Cmd+Shift+O) - Use split panes and tabs for context, rather than keeping a large file tree open (though you can do this with the Project Panel if you prefer).
- Fuzzy-find files by name (
The UI keeps auxiliary panels out of the way so navigation stays centered on code.
Extensions vs. Marketplace
Zed does not offer as many extensions as VS Code. The available extensions are focused on language support, themes, syntax highlighting, and other core editing enhancements.
Several features that typically require extensions in VS Code are built into Zed:
- Real-time collaboration with voice and cursor sharing (no Live Share required)
- AI coding assistance (no Copilot extension needed)
- Built-in terminal panel
- Project-wide fuzzy search
- Task runner with JSON config
- Inline diagnostics and code actions via LSP
You won’t find one-to-one replacements for every VS Code extension, especially if you rely on tools for DevOps, containers, or test runners. Zed's extension catalog is still growing and remains smaller.
Collaboration in Zed vs. VS Code
Unlike VS Code, Zed doesn’t require an extension to collaborate. It’s built into the core experience.
- Open the Collab Panel in the left dock.
- Create a channel and invite your collaborators to join.
- Share your screen or your codebase directly.
Once connected, you’ll see each other's cursors, selections, and edits in real time. Voice chat is included, so you can talk as you work. There’s no need for separate tools or third-party logins.
Learn how Zed uses Zed to plan work and collaborate.
Using AI in Zed
If you’re used to GitHub Copilot in VS Code, you can do the same in Zed. You can also explore other agents through Zed Pro, or bring your own keys and connect without authentication. You can disable AI features entirely if you prefer.
Configuring GitHub Copilot
- Open Settings with
Cmd+,(macOS) orCtrl+,(Linux/Windows) - Navigate to AI → Edit Predictions
- Click Configure next to "Configure Providers"
- Under GitHub Copilot, click Sign in to GitHub
Once signed in, just start typing. Zed will offer suggestions inline for you to accept.
Additional AI Options
To use other AI models in Zed, you have several options:
- Use Zed’s hosted models, with higher rate limits. Requires authentication and access through Zed Pro.
- Bring your own API keys, no authentication needed
- Use External Agents like Claude Agent.
Advanced Config and Productivity Tweaks
Zed exposes advanced settings for power users who want to fine-tune their environment.
Here are a few useful tweaks:
Format on Save:
"format_on_save": "on"
Enable direnv support:
"load_direnv": "shell_hook"
Custom Tasks: Define build or run commands in your tasks.json (accessed via command palette: {#action zed::OpenTasks}):
[
{
"label": "build",
"command": "cargo build"
}
]
Bring over custom snippets Copy your VS Code snippet JSON directly into Zed's snippets folder ({#action snippets::ConfigureSnippets}).