Rename settings and keymap actions (#39970)

This PR renames the following actions to make it easier and prioritize
the UI version of interacting with them:

| Before | After |
|--------|--------|
| `OpenSettingsEditor` | `OpenSettings` |
| `OpenSettings` | `OpenSettingsFile` |
| `OpenKeymapEditor` | `OpenKeymap` |
| `OpenKeymap` | `OpenKeymapFile` | 

Release Notes:

- Rename actions to open settings (UI/window and JSON file) as well as
to open the keymap (editor tab and JSON file).
This commit is contained in:
Danilo Leal
2025-10-10 17:29:20 -03:00
committed by GitHub
parent 120faadef8
commit 18405dece8
15 changed files with 191 additions and 192 deletions
+3 -3
View File
@@ -30,8 +30,8 @@
"ctrl-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
"ctrl--": ["zed::DecreaseBufferFontSize", { "persist": false }],
"ctrl-0": ["zed::ResetBufferFontSize", { "persist": false }],
"ctrl-,": "zed::OpenSettingsEditor",
"ctrl-alt-,": "zed::OpenSettings",
"ctrl-,": "zed::OpenSettings",
"ctrl-alt-,": "zed::OpenSettingsFile",
"ctrl-q": "zed::Quit",
"f4": "debugger::Start",
"shift-f5": "debugger::Stop",
@@ -621,7 +621,7 @@
"ctrl-shift-f": "pane::DeploySearch",
"ctrl-shift-h": ["pane::DeploySearch", { "replace_enabled": true }],
"ctrl-shift-t": "pane::ReopenClosedItem",
"ctrl-k ctrl-s": "zed::OpenKeymapEditor",
"ctrl-k ctrl-s": "zed::OpenKeymap",
"ctrl-k ctrl-t": "theme_selector::Toggle",
"ctrl-alt-super-p": "settings_profile_selector::Toggle",
"ctrl-t": "project_symbols::Toggle",
+3 -3
View File
@@ -39,8 +39,8 @@
"cmd-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
"cmd--": ["zed::DecreaseBufferFontSize", { "persist": false }],
"cmd-0": ["zed::ResetBufferFontSize", { "persist": false }],
"cmd-,": "zed::OpenSettingsEditor",
"cmd-alt-,": "zed::OpenSettings",
"cmd-,": "zed::OpenSettings",
"cmd-alt-,": "zed::OpenSettingsFile",
"cmd-q": "zed::Quit",
"cmd-h": "zed::Hide",
"alt-cmd-h": "zed::HideOthers",
@@ -690,7 +690,7 @@
"cmd-shift-f": "pane::DeploySearch",
"cmd-shift-h": ["pane::DeploySearch", { "replace_enabled": true }],
"cmd-shift-t": "pane::ReopenClosedItem",
"cmd-k cmd-s": "zed::OpenKeymapEditor",
"cmd-k cmd-s": "zed::OpenKeymap",
"cmd-k cmd-t": "theme_selector::Toggle",
"ctrl-alt-cmd-p": "settings_profile_selector::Toggle",
"cmd-t": "project_symbols::Toggle",
+3 -3
View File
@@ -29,8 +29,8 @@
"ctrl-shift-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
"ctrl--": ["zed::DecreaseBufferFontSize", { "persist": false }],
"ctrl-0": ["zed::ResetBufferFontSize", { "persist": false }],
"ctrl-,": "zed::OpenSettingsEditor",
"ctrl-alt-,": "zed::OpenSettings",
"ctrl-,": "zed::OpenSettings",
"ctrl-alt-,": "zed::OpenSettingsFile",
"ctrl-q": "zed::Quit",
"f4": "debugger::Start",
"shift-f5": "debugger::Stop",
@@ -623,7 +623,7 @@
"ctrl-shift-f": "pane::DeploySearch",
"ctrl-shift-h": ["pane::DeploySearch", { "replace_enabled": true }],
"ctrl-shift-t": "pane::ReopenClosedItem",
"ctrl-k ctrl-s": "zed::OpenKeymapEditor",
"ctrl-k ctrl-s": "zed::OpenKeymap",
"ctrl-k ctrl-t": "theme_selector::Toggle",
"ctrl-alt-super-p": "settings_profile_selector::Toggle",
"ctrl-t": "project_symbols::Toggle",
+1 -1
View File
@@ -1,7 +1,7 @@
[
{
"bindings": {
"ctrl-alt-s": "zed::OpenSettings",
"ctrl-alt-s": "zed::OpenSettingsFile",
"ctrl-{": "pane::ActivatePreviousItem",
"ctrl-}": "pane::ActivateNextItem",
"shift-escape": null, // Unmap workspace::zoom
+1 -1
View File
@@ -24645,7 +24645,7 @@ impl Render for MissingEditPredictionKeybindingTooltip {
.items_end()
.w_full()
.child(Button::new("open-keymap", "Assign Keybinding").size(ButtonSize::Compact).on_click(|_ev, window, cx| {
window.dispatch_action(zed_actions::OpenKeymap.boxed_clone(), cx)
window.dispatch_action(zed_actions::OpenKeymapFile.boxed_clone(), cx)
}))
.child(Button::new("see-docs", "See Docs").size(ButtonSize::Compact).on_click(|_ev, _window, cx| {
cx.open_url("https://zed.dev/docs/completions#edit-predictions-missing-keybinding");
+4 -4
View File
@@ -38,7 +38,7 @@ use workspace::{
};
pub use ui_components::*;
use zed_actions::OpenKeymapEditor;
use zed_actions::OpenKeymap;
use crate::{
persistence::KEYBINDING_EDITORS,
@@ -77,7 +77,7 @@ pub fn init(cx: &mut App) {
let keymap_event_channel = KeymapEventChannel::new();
cx.set_global(keymap_event_channel);
cx.on_action(|_: &OpenKeymapEditor, cx| {
cx.on_action(|_: &OpenKeymap, cx| {
workspace::with_active_or_new_workspace(cx, move |workspace, window, cx| {
workspace
.with_local_workspace(window, cx, |workspace, window, cx| {
@@ -1700,7 +1700,7 @@ impl Render for KeymapEditor {
move |window, cx| {
Tooltip::for_action_in(
"View Default...",
&zed_actions::OpenKeymap,
&zed_actions::OpenKeymapFile,
&focus_handle,
window,
cx,
@@ -1714,7 +1714,7 @@ impl Render for KeymapEditor {
.style(ButtonStyle::Outlined)
.on_click(|_, window, cx| {
window.dispatch_action(
zed_actions::OpenKeymap.boxed_clone(),
zed_actions::OpenKeymapFile.boxed_clone(),
cx,
);
})
@@ -207,7 +207,7 @@ impl Render for KeyContextView {
.on_click(|_, _, cx| cx.open_url("https://zed.dev/docs/key-bindings")),
)
.child(
Button::new("view_default_keymap", "View default keymap")
Button::new("view_default_keymap", "View Default Keymap")
.style(ButtonStyle::Filled)
.key_binding(ui::KeyBinding::for_action(
&zed_actions::OpenDefaultKeymap,
@@ -219,11 +219,11 @@ impl Render for KeyContextView {
}),
)
.child(
Button::new("edit_your_keymap", "Edit your keymap")
Button::new("edit_your_keymap", "Edit Keymap File")
.style(ButtonStyle::Filled)
.key_binding(ui::KeyBinding::for_action(&zed_actions::OpenKeymap, window, cx))
.key_binding(ui::KeyBinding::for_action(&zed_actions::OpenKeymapFile, window, cx))
.on_click(|_, window, cx| {
window.dispatch_action(zed_actions::OpenKeymap.boxed_clone(), cx);
window.dispatch_action(zed_actions::OpenKeymapFile.boxed_clone(), cx);
}),
),
)
+2 -2
View File
@@ -9,7 +9,7 @@ use workspace::{
item::{Item, ItemEvent},
with_active_or_new_workspace,
};
use zed_actions::{Extensions, OpenSettingsEditor, agent, command_palette};
use zed_actions::{Extensions, OpenSettings, agent, command_palette};
use crate::{Onboarding, OpenOnboarding};
@@ -53,7 +53,7 @@ const CONTENT: (Section<4>, Section<3>) = (
SectionEntry {
icon: IconName::Settings,
title: "Open Settings",
action: &OpenSettingsEditor,
action: &OpenSettings,
},
SectionEntry {
icon: IconName::ZedAssistant,
+2 -2
View File
@@ -38,7 +38,7 @@ use ui::{
use ui_input::{NumberField, NumberFieldType};
use util::{ResultExt as _, paths::PathStyle, rel_path::RelPath};
use workspace::{OpenOptions, OpenVisible, Workspace, client_side_decorations};
use zed_actions::OpenSettingsEditor;
use zed_actions::OpenSettings;
use crate::components::SettingsEditor;
@@ -286,7 +286,7 @@ pub fn init(cx: &mut App) {
init_renderers(cx);
cx.observe_new(|workspace: &mut workspace::Workspace, _, _| {
workspace.register_action(|workspace, _: &OpenSettingsEditor, window, cx| {
workspace.register_action(|workspace, _: &OpenSettings, window, cx| {
let window_handle = window
.window_handle()
.downcast::<Workspace>()
+94 -104
View File
@@ -664,49 +664,55 @@ impl TitleBar {
pub fn render_app_menu_button(&mut self, cx: &mut Context<Self>) -> impl Element {
let user_store = self.user_store.read(cx);
if let Some(user) = user_store.current_user() {
let has_subscription_period = user_store.subscription_period().is_some();
let plan = user_store.plan().filter(|_| {
// Since the user might be on the legacy free plan we filter based on whether we have a subscription period.
has_subscription_period
});
let user = user_store.current_user();
let user_avatar = user.avatar_uri.clone();
let free_chip_bg = cx
.theme()
.colors()
.editor_background
.opacity(0.5)
.blend(cx.theme().colors().text_accent.opacity(0.05));
let user_avatar = user.as_ref().map(|u| u.avatar_uri.clone());
let user_login = user.as_ref().map(|u| u.github_login.clone());
let pro_chip_bg = cx
.theme()
.colors()
.editor_background
.opacity(0.5)
.blend(cx.theme().colors().text_accent.opacity(0.2));
let is_signed_in = user.is_some();
PopoverMenu::new("user-menu")
.anchor(Corner::TopRight)
.menu(move |window, cx| {
ContextMenu::build(window, cx, |menu, _, _cx| {
let user_login = user.github_login.clone();
let has_subscription_period = user_store.subscription_period().is_some();
let plan = user_store.plan().filter(|_| {
// Since the user might be on the legacy free plan we filter based on whether we have a subscription period.
has_subscription_period
});
let (plan_name, label_color, bg_color) = match plan {
None | Some(Plan::V1(PlanV1::ZedFree) | Plan::V2(PlanV2::ZedFree)) => {
("Free", Color::Default, free_chip_bg)
}
Some(Plan::V1(PlanV1::ZedProTrial) | Plan::V2(PlanV2::ZedProTrial)) => {
("Pro Trial", Color::Accent, pro_chip_bg)
}
Some(Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro)) => {
("Pro", Color::Accent, pro_chip_bg)
}
};
let free_chip_bg = cx
.theme()
.colors()
.editor_background
.opacity(0.5)
.blend(cx.theme().colors().text_accent.opacity(0.05));
menu.custom_entry(
let pro_chip_bg = cx
.theme()
.colors()
.editor_background
.opacity(0.5)
.blend(cx.theme().colors().text_accent.opacity(0.2));
PopoverMenu::new("user-menu")
.anchor(Corner::TopRight)
.menu(move |window, cx| {
ContextMenu::build(window, cx, |menu, _, _cx| {
let user_login = user_login.clone();
let (plan_name, label_color, bg_color) = match plan {
None | Some(Plan::V1(PlanV1::ZedFree) | Plan::V2(PlanV2::ZedFree)) => {
("Free", Color::Default, free_chip_bg)
}
Some(Plan::V1(PlanV1::ZedProTrial) | Plan::V2(PlanV2::ZedProTrial)) => {
("Pro Trial", Color::Accent, pro_chip_bg)
}
Some(Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro)) => {
("Pro", Color::Accent, pro_chip_bg)
}
};
menu.when(is_signed_in, |this| {
this.custom_entry(
move |_window, _cx| {
let user_login = user_login.clone();
let user_login = user_login.clone().unwrap_or_default();
h_flex()
.w_full()
@@ -724,75 +730,59 @@ impl TitleBar {
},
)
.separator()
.action("Settings", zed_actions::OpenSettingsEditor.boxed_clone())
.action("Keymap Editor", Box::new(zed_actions::OpenKeymapEditor))
.action(
"Themes…",
zed_actions::theme_selector::Toggle::default().boxed_clone(),
)
.action(
"Icon Themes…",
zed_actions::icon_theme_selector::Toggle::default().boxed_clone(),
)
.action(
"Extensions",
zed_actions::Extensions::default().boxed_clone(),
)
.separator()
.action("Sign Out", client::SignOut.boxed_clone())
})
.into()
})
.trigger_with_tooltip(
ButtonLike::new("user-menu")
.child(
h_flex()
.gap_0p5()
.children(
TitleBarSettings::get_global(cx)
.show_user_picture
.then(|| Avatar::new(user_avatar)),
)
.child(
Icon::new(IconName::ChevronDown)
.size(IconSize::Small)
.color(Color::Muted),
),
)
.style(ButtonStyle::Subtle),
Tooltip::text("Toggle User Menu"),
)
.anchor(gpui::Corner::TopRight)
} else {
PopoverMenu::new("user-menu")
.anchor(Corner::TopRight)
.menu(|window, cx| {
ContextMenu::build(window, cx, |menu, _, _| {
menu.action("Settings", zed_actions::OpenSettings.boxed_clone())
.action(
"Settings Profiles",
zed_actions::settings_profile_selector::Toggle.boxed_clone(),
)
.action("Key Bindings", Box::new(zed_actions::OpenKeymapEditor))
.action(
"Themes…",
zed_actions::theme_selector::Toggle::default().boxed_clone(),
)
.action(
"Icon Themes…",
zed_actions::icon_theme_selector::Toggle::default().boxed_clone(),
)
.action(
"Extensions",
zed_actions::Extensions::default().boxed_clone(),
)
.action("Settings", zed_actions::OpenSettings.boxed_clone())
.action("Keymap", Box::new(zed_actions::OpenKeymap))
.action(
"Themes…",
zed_actions::theme_selector::Toggle::default().boxed_clone(),
)
.action(
"Icon Themes…",
zed_actions::icon_theme_selector::Toggle::default().boxed_clone(),
)
.action(
"Extensions",
zed_actions::Extensions::default().boxed_clone(),
)
.when(is_signed_in, |this| {
this.separator()
.action("Sign Out", client::SignOut.boxed_clone())
})
.into()
})
.trigger_with_tooltip(
IconButton::new("user-menu", IconName::ChevronDown).icon_size(IconSize::Small),
Tooltip::text("Toggle User Menu"),
)
}
.into()
})
.map(|this| {
if is_signed_in {
this.trigger_with_tooltip(
ButtonLike::new("user-menu")
.child(
h_flex()
.gap_0p5()
.children(
TitleBarSettings::get_global(cx)
.show_user_picture
.then(|| user_avatar.clone())
.flatten()
.map(|avatar| Avatar::new(avatar)),
)
.child(
Icon::new(IconName::ChevronDown)
.size(IconSize::Small)
.color(Color::Muted),
),
)
.style(ButtonStyle::Subtle),
Tooltip::text("Toggle User Menu"),
)
} else {
this.trigger_with_tooltip(
IconButton::new("user-menu", IconName::ChevronDown)
.icon_size(IconSize::Small),
Tooltip::text("Toggle User Menu"),
)
}
})
.anchor(gpui::Corner::TopRight)
}
}
+58 -53
View File
@@ -93,7 +93,8 @@ use workspace::{
};
use workspace::{Pane, notifications::DetachAndPromptErr};
use zed_actions::{
OpenAccountSettings, OpenBrowser, OpenDocs, OpenServerSettings, OpenSettings, OpenZedUrl, Quit,
OpenAccountSettings, OpenBrowser, OpenDocs, OpenServerSettings, OpenSettingsFile, OpenZedUrl,
Quit,
};
actions!(
@@ -196,7 +197,7 @@ pub fn init(cx: &mut App) {
open_telemetry_log_file(workspace, window, cx);
});
});
cx.on_action(|&zed_actions::OpenKeymap, cx| {
cx.on_action(|&zed_actions::OpenKeymapFile, cx| {
with_active_or_new_workspace(cx, |_, window, cx| {
open_settings_file(
paths::keymap_file(),
@@ -206,7 +207,7 @@ pub fn init(cx: &mut App) {
);
});
});
cx.on_action(|_: &OpenSettings, cx| {
cx.on_action(|_: &OpenSettingsFile, cx| {
with_active_or_new_workspace(cx, |_, window, cx| {
open_settings_file(
paths::settings_file(),
@@ -1270,58 +1271,61 @@ pub fn handle_settings_file_changes(
MigrationNotification::set_global(cx.new(|_| MigrationNotification), cx);
// Helper function to process settings content
let process_settings =
move |content: String, is_user: bool, store: &mut SettingsStore, cx: &mut App| -> bool {
let id = NotificationId::Named("failed-to-migrate-settings".into());
// Apply migrations to both user and global settings
let (processed_content, content_migrated) = match migrate_settings(&content) {
Ok(result) => {
dismiss_app_notification(&id, cx);
if let Some(migrated_content) = result {
(migrated_content, true)
} else {
(content, false)
}
}
Err(err) => {
show_app_notification(id, cx, move |cx| {
cx.new(|cx| {
MessageNotification::new(
format!(
"Failed to migrate settings\n\
{err}"
),
cx,
)
.primary_message("Open Settings File")
.primary_icon(IconName::Settings)
.primary_on_click(|window, cx| {
window.dispatch_action(zed_actions::OpenSettings.boxed_clone(), cx);
cx.emit(DismissEvent);
})
})
});
// notify user here
let process_settings = move |content: String,
is_user: bool,
store: &mut SettingsStore,
cx: &mut App|
-> bool {
let id = NotificationId::Named("failed-to-migrate-settings".into());
// Apply migrations to both user and global settings
let (processed_content, content_migrated) = match migrate_settings(&content) {
Ok(result) => {
dismiss_app_notification(&id, cx);
if let Some(migrated_content) = result {
(migrated_content, true)
} else {
(content, false)
}
};
let result = if is_user {
store.set_user_settings(&processed_content, cx)
} else {
store.set_global_settings(&processed_content, cx)
};
if let Err(err) = &result {
let settings_type = if is_user { "user" } else { "global" };
log::error!("Failed to load {} settings: {err}", settings_type);
}
settings_changed(result.err(), cx);
content_migrated
Err(err) => {
show_app_notification(id, cx, move |cx| {
cx.new(|cx| {
MessageNotification::new(
format!(
"Failed to migrate settings\n\
{err}"
),
cx,
)
.primary_message("Open Settings File")
.primary_icon(IconName::Settings)
.primary_on_click(|window, cx| {
window.dispatch_action(zed_actions::OpenSettingsFile.boxed_clone(), cx);
cx.emit(DismissEvent);
})
})
});
// notify user here
(content, false)
}
};
let result = if is_user {
store.set_user_settings(&processed_content, cx)
} else {
store.set_global_settings(&processed_content, cx)
};
if let Err(err) = &result {
let settings_type = if is_user { "user" } else { "global" };
log::error!("Failed to load {} settings: {err}", settings_type);
}
settings_changed(result.err(), cx);
content_migrated
};
// Initial load of both settings files
let global_content = cx
.background_executor()
@@ -1499,7 +1503,7 @@ fn show_keymap_file_json_error(
MessageNotification::new(message.clone(), cx)
.primary_message("Open Keymap File")
.primary_on_click(|window, cx| {
window.dispatch_action(zed_actions::OpenKeymap.boxed_clone(), cx);
window.dispatch_action(zed_actions::OpenKeymapFile.boxed_clone(), cx);
cx.emit(DismissEvent);
})
})
@@ -1516,7 +1520,7 @@ fn show_keymap_file_load_error(
error_message,
"Open Keymap File".into(),
|window, cx| {
window.dispatch_action(zed_actions::OpenKeymap.boxed_clone(), cx);
window.dispatch_action(zed_actions::OpenKeymapFile.boxed_clone(), cx);
cx.emit(DismissEvent);
},
cx,
@@ -1635,7 +1639,7 @@ pub fn handle_settings_changed(error: Option<anyhow::Error>, cx: &mut App) {
.primary_message("Open Settings File")
.primary_icon(IconName::Settings)
.primary_on_click(|window, cx| {
window.dispatch_action(zed_actions::OpenSettings.boxed_clone(), cx);
window.dispatch_action(zed_actions::OpenSettingsFile.boxed_clone(), cx);
cx.emit(DismissEvent);
})
})
@@ -4653,6 +4657,7 @@ mod tests {
"window",
"workspace",
"zed",
"zed_actions",
"zed_predict_onboarding",
"zeta",
];
+4 -4
View File
@@ -63,13 +63,13 @@ pub fn app_menus(cx: &mut App) -> Vec<Menu> {
MenuItem::submenu(Menu {
name: "Settings".into(),
items: vec![
MenuItem::action("Open Settings", zed_actions::OpenSettingsEditor),
MenuItem::action("Open Settings JSON", super::OpenSettings),
MenuItem::action("Open Settings", zed_actions::OpenSettings),
MenuItem::action("Open Settings File", super::OpenSettingsFile),
MenuItem::action("Open Project Settings", super::OpenProjectSettings),
MenuItem::action("Open Default Settings", super::OpenDefaultSettings),
MenuItem::separator(),
MenuItem::action("Open Keymap Editor", zed_actions::OpenKeymapEditor),
MenuItem::action("Open Keymap JSON", zed_actions::OpenKeymap),
MenuItem::action("Open Keymap", zed_actions::OpenKeymap),
MenuItem::action("Open Keymap File", zed_actions::OpenKeymapFile),
MenuItem::action(
"Open Default Key Bindings",
zed_actions::OpenDefaultKeymap,
+10 -6
View File
@@ -30,22 +30,26 @@ pub struct OpenZedUrl {
actions!(
zed,
[
/// Opens the settings JSON file.
#[action(deprecated_aliases = ["zed_actions::OpenSettingsEditor"])]
OpenSettings,
/// Opens the settings JSON file.
#[action(deprecated_aliases = ["zed_actions::OpenSettings"])]
OpenSettingsFile,
/// Opens the settings editor.
OpenSettingsEditor,
/// Opens the default keymap file.
OpenDefaultKeymap,
/// Opens the user keymap file.
#[action(deprecated_aliases = ["zed_actions::OpenKeymap"])]
OpenKeymapFile,
/// Opens the keymap editor.
#[action(deprecated_aliases = ["zed_actions::OpenKeymapEditor"])]
OpenKeymap,
/// Opens account settings.
OpenAccountSettings,
/// Opens the keymap editor.
OpenKeymapEditor,
/// Opens server settings.
OpenServerSettings,
/// Quits the application.
Quit,
/// Opens the user keymap file.
OpenKeymap,
/// Shows information about Zed.
About,
/// Opens the documentation website.
+1 -1
View File
@@ -83,6 +83,6 @@ Visit [the AI overview page](./ai/overview.md) to learn how to quickly get start
## Set up your key bindings
To edit your custom keymap and add or remap bindings, you can either use {#kb zed::OpenKeymapEditor} to spawn the Zed Keymap Editor ({#action zed::OpenKeymapEditor}) or you can directly open your Zed Keymap json (`~/.config/zed/keymap.json`) with {#action zed::OpenKeymap}.
To edit your custom keymap and add or remap bindings, you can either use {#kb zed::OpenKeymap} to spawn the Zed Keymap Editor ({#action zed::OpenKeymap}) or you can directly open your Zed Keymap json (`~/.config/zed/keymap.json`) with {#action zed::OpenKeymap}.
To access the default key binding set, open the Command Palette with {#kb command_palette::Toggle} and search for "zed: open default keymap". See [Key Bindings](./key-bindings.md) for more info.
+1 -1
View File
@@ -24,7 +24,7 @@ For more information, see the documentation for [Vim mode](./vim.md) and [Helix
## User keymaps
Zed reads your keymap from `~/.config/zed/keymap.json`, which you can open with the {#action zed::OpenKeymap} action from the command palette.
You can also edit your keymap through the Zed Keymap Editor, accessible via the {#action zed::OpenKeymapEditor} action or the {#kb zed::OpenKeymapEditor} keybinding.
You can also edit your keymap through the Zed Keymap Editor, accessible via the {#action zed::OpenKeymap} action or the {#kb zed::OpenKeymap} keybinding.
The `keymap.json` file contains a JSON array of objects with `"bindings"`. If no `"context"` is set, the bindings are always active. If it is set, the binding is only active when the [context matches](#contexts).