# keymap_editor: Fix default binding deletion and override \(\#50699\) · gitcafe/zed

[View on GitCafe](https://git.cafe/gitcafe/zed/commit/94400d856e0e0ad263a457c2c412897fe883f3d7)

Repository: [gitcafe/zed](https://git.cafe/gitcafe/zed)

Visibility: public

Requested revision: 94400d856e0e0ad263a457c2c412897fe883f3d7

Requested commit: 94400d856e0e0ad263a457c2c412897fe883f3d7

Commit: 94400d856e0e0ad263a457c2c412897fe883f3d7

Tree: 1c5adb03d0f92c477e03678c3c2aed8cde960970

Author: iam-liam

Committer: GitHub

## Message

```
keymap_editor: Fix default binding deletion and override (#50699)

## Summary

Fixes #48725

When using the keymap editor to delete or re-bind default keybindings,
two issues caused stale entries to persist:

- **Deleting a default binding** created a `NoAction` suppression entry
in `keymap.json` (correct for GPUI-level suppression), but the keymap
editor displayed it as a phantom `<null>` row alongside the greyed-out
default. Searching by keystroke showed both entries, and clash detection
counted the phantom as a real binding.

- **Changing a default binding's keystroke** (e.g. `⌥⌘T` → `⇧⌃⌘T`) added
the new binding but never suppressed the original default under the old
keystroke. The old default continued appearing in keystroke searches and
clash warnings.

## Fix

1. **Filter `NoAction` suppression bindings from the keymap editor
display.** These remain in the internal binding list for conflict
detection (so overridden defaults are still correctly greyed out), but
are excluded from the visible match results.

2. **Append a `null` suppression for the old keystroke when replacing a
non-user binding with a different keystroke.** When `update_keybinding`
converts a `Replace` to `Add` for a non-user binding and the keystroke
changes, it now also writes `{"old-keystroke": null}` (with the original
context) to suppress the stale default.

## Reproduction steps (verified fixed)

1. Open the keymap editor
2. Click Search by Keystroke and press `⌥⌘T`
3. You should see "agent: new thread" and "pane: close other items"
(both Default)
4. Right-click "agent: new thread" and choose Delete
5. Double-click "pane: close other items", change keystroke to `⇧⌃⌘T`,
click Save
6. Verify no `<null>` phantom row appears, and no stale defaults remain
under `⌥⌘T`
7. Close and reopen the keymap editor, search `⌥⌘T` — no results
8. Search for "editor: wrap selections in tag" and assign `⌥⌘T` — no
clash warnings

## Test plan

- [x] Existing `keymap_update` and `test_keymap_remove` tests pass
- [x] Added test: replacing a non-user binding **without** changing the
keystroke produces no suppression
- [x] Added test: replacing a non-user binding **with** context and
keystroke change produces a suppression that preserves the context
- [x] Manual verification of all reproduction steps above

Release Notes:

- Fixed an issue with the keymap editor where where the defaults would not be completely removed when deleting or overriding default keybindings

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
```

## Parents

- [f3fb4e04aa85dbbde6e83d28f231fc452cd8863f](https://git.cafe/gitcafe/zed/commit/f3fb4e04aa85dbbde6e83d28f231fc452cd8863f?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zed/tree/94400d856e0e0ad263a457c2c412897fe883f3d7?format=markdown)
