Skip to content

editor: Fix DeleteToPreviousSubwordStart and DeleteToNextSubwordEnd interaction with newlines #46235

Merged
SomeoneToIgnore merged 4 commits intozed-industries:mainfrom
RubenFricke:fix/40110-subword-delete-newlines
Jan 11, 2026
Merged

editor: Fix DeleteToPreviousSubwordStart and DeleteToNextSubwordEnd interaction with newlines #46235
SomeoneToIgnore merged 4 commits intozed-industries:mainfrom
RubenFricke:fix/40110-subword-delete-newlines

Conversation

@RubenFricke
Copy link
Contributor

@RubenFricke RubenFricke commented Jan 7, 2026

Closes #40110

Changes:

  • DeleteToPreviousSubwordStart now deletes \n separately from preceding subwords and whitespace.
  • DeleteToNextSubwordEnd now deletes \n and any following whitespace separately from subsequent subwords.
  • Added an ignore_newlines flag to both actions to optionally retain the old behavior.

These modifications align the subword commands with their word counterparts and with other popular editors like VSCode and Sublime.

Related to: #16848

Release Notes:

  • Improved DeleteToPreviousSubwordStart and DeleteToNextSubwordEnd interactions around newlines. You can opt-in into the previous behavior by adding {"ignore_newlines": true} to either action's binds in your keymap.

This is my first contribution to Zed! If anything should be done differently, please let me know. Happy to learn :)

@cla-bot
Copy link

cla-bot bot commented Jan 7, 2026

We require contributors to sign our Contributor License Agreement, and we don't have @RubenFricke on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@RubenFricke
Copy link
Contributor Author

@cla-bot check

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Jan 7, 2026
@cla-bot
Copy link

cla-bot bot commented Jan 7, 2026

The cla-bot has been summoned, and re-checked this pull request!

@RubenFricke RubenFricke changed the title editor: Add ignore_newlines parameter to subword deletion actions editor: Fix DeleteToPreviousSubwordStart and DeleteToNextSubwordEnd interaction with newlines Jan 7, 2026
@SomeoneToIgnore SomeoneToIgnore self-assigned this Jan 11, 2026
Copy link
Contributor

@SomeoneToIgnore SomeoneToIgnore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a great first contributions, thank you for fixing this.

@SomeoneToIgnore SomeoneToIgnore enabled auto-merge (squash) January 11, 2026 08:36
@SomeoneToIgnore SomeoneToIgnore merged commit e0b8969 into zed-industries:main Jan 11, 2026
24 of 25 checks passed
Leoyzen pushed a commit to Leoyzen/zed that referenced this pull request Jan 11, 2026
…nteraction with newlines (zed-industries#46235)

Closes zed-industries#40110

  Changes:
- `DeleteToPreviousSubwordStart` now deletes `\n` separately from
preceding subwords and whitespace.
- `DeleteToNextSubwordEnd` now deletes `\n` and any following whitespace
separately from subsequent subwords.
- Added an `ignore_newlines` flag to both actions to optionally retain
the old behavior.

These modifications align the subword commands with their word
counterparts and with other popular editors like VSCode and Sublime.

Related to: zed-industries#16848

  Release Notes:

- Improved `DeleteToPreviousSubwordStart` and `DeleteToNextSubwordEnd`
interactions around newlines. You can opt-in into the previous behavior
by adding `{"ignore_newlines": true}` to either action's binds in your
keymap.

  ---

This is my first contribution to Zed! If anything should be done
differently, please let me know. Happy to learn :)
@Andrei-Pozolotin
Copy link

@RubenFricke :

while this issue is till "warm" in your mind:

In python, "word separators" for symbols are "underscores";

How hard would it be to extend your PR for
DeleteToPreviousSubwordStart, DeleteToNextSubwordEnd, etc,
to support proper handing of long_symbol_names_like_this ?

By exposing action params, like
"word_boundary_regex": "[a-zA-Z0-9]+|_"
?

Or by handling this issue on per-language basis via settings.json?

@RubenFricke
Copy link
Contributor Author

Thanks for the question @Andrei-Pozolotin! I believe the current implementation should already handle long_symbol_names_like_this correctly. Underscores are treated as subword separators in the boundary logic:

  // is_subword_start: underscore→letter transitions
  left == '_' && right != '_'

  // is_subword_boundary_end: letter→underscore transitions
  left != '_' && right == '_'

So DeleteToPreviousSubwordStart on long_symbol_names_like_this should stop at: this → like → names → symbol → long.
Could you test and let me know if you're seeing different behavior?

Regarding configurable regex or per-language settings: as far as I see, this would introduce complexity and would likely need some additional direction. Happy to discuss if there's a specific use case the current behavior doesn't cover.

@Andrei-Pozolotin
Copy link

Thank you so much getting back.

Well, the reason "I am here" because "that does not work for me." :-)

What I observe in python code editor with zed:

Zed 0.221.5 
03bfbf242c57f7fdb45708d63d74182898edf2c5

Using vscode/linux profile:
https://github.com/zed-industries/zed/blob/main/assets/keymaps/default-linux.json

    "context": "Editor",
    "bindings": {
      "ctrl-backspace": ["editor::DeleteToPreviousWordStart", { "ignore_newlines": false, "ignore_brackets": false }],

To reproduce:

  • position cursor in the middle of symbol long_symbol_names_like_this
  • press 'F2' (start symbol edit), whole symbol becomes selected
  • press 'End' (to force un-select), cursor moves at the end of _this
  • press 'ctrl-backspace' (trying to delete only _this)
  • result: whole symbol is deleted

May be there is a difference: "main edit mode" vs "symbol edit mode"?

Since I see no unit tests for this in the code,
(I mean, tests for patterns like: 'long_symbol_names_like_this'),
then I guess there is no way prove that either way.

Perhaps just have to chalk this up this issue to "me, being a zed newbie".

Thanks again.

@RubenFricke
Copy link
Contributor Author

RubenFricke commented Feb 4, 2026

Sorry for the late reaction @Andrei-Pozolotin , but I think I’ve spotted the issue! In your keymap, you are using editor::DeleteToPreviousWordStart.

In Zed, Word actions treat the entire symbol (including underscores) as a single unit. To get the behavior you're looking for where it stops at underscores, you need to use the Subword variant that I've changed in this PR:

"ctrl-backspace": ["editor::DeleteToPreviousSubwordStart", { "ignore_newlines": false }]

The "Subword" actions are specifically designed to respect snake_case and camelCase boundaries.

Regarding the unit tests: you should be able to find the logic and test cases for these boundaries in crates/editor/src/movement.rs. Let me know if this works! :)

@Andrei-Pozolotin
Copy link

@RubenFricke :

Thank you,
you are right about 'Subword' vs 'Word',
and you solved my problem!

Final curiosity: short of using:

What is an easy/simple way to trace from action
(like editor::DeleteToPreviousSubwordStart)
to the zed implementation snippet?
(like the code in your PR)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mismatched behavior for delete word and subword commands

3 participants