fix: #5239 let Ctrl+Backspace delete a word at the end of a line by johannesroth-coreproduction · Pull Request #5657 · marktext/marktext · GitHub
Skip to content

fix: #5239 let Ctrl+Backspace delete a word at the end of a line - #5657

Merged
Jocs merged 1 commit into
marktext:developfrom
johannesroth-coreproduction:fix/5239-ctrl-backspace
Oct 8, 2026
Merged

Jocs merged 1 commit into
marktext:developfrom
johannesroth-coreproduction:fix/5239-ctrl-backspace

Conversation

@johannesroth-coreproduction

Copy link
Copy Markdown
Contributor

Closes #5239

Summary

In the WYSIWYG editor, Ctrl+Backspace at the end of a line only deletes one
character instead of the previous word. In the middle of a line it works.

Cause: Format.backspaceHandler contains a Firefox workaround for
marktext/muya#113. Whenever the caret is exactly at the end of a token, it
removes the last character itself and calls preventDefault(). At the end of
a line the caret is always at the end of the last (plain text) token, so the
browser's native word deletion is suppressed. Modifier keys are never checked.
The legacy muyajs editor only handled inline_math and <ruby> here, so 0.17
was not affected.

Fix: when Ctrl, Alt or Cmd is held, return early and let the browser perform
its native word/line deletion, as it already does in the middle of a line.
Plain Backspace keeps the existing behaviour. Backspace at offset 0 (block
merge) is handled before this code and is unaffected.

Type of change

  • Bug fix (non-breaking, fixes an issue)
  • New feature (non-breaking, adds functionality)
  • Breaking change (causes existing functionality to change)
  • Documentation update

Test plan

  • New tests added (formatBackspace.spec.ts, fail without the fix)
  • Manually tested on: Linux (Kubuntu)

Notes for reviewers

Ctrl+Backspace directly after inline markup (e.g. **strong**|) is now also
handled natively, the same way it already is in the middle of a line.

Format.backspaceHandler removes the last character itself whenever the
caret sits at the end of a token (Firefox workaround for muya#113). At
the end of a line that is always true for the last text token, so the
native Ctrl/Alt/Cmd+Backspace word deletion was suppressed. Leave
modified Backspace to the browser, as already happens mid-line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Jocs
Jocs merged commit 38a7563 into marktext:develop Oct 8, 2026
6 checks passed
Jocs added a commit that referenced this pull request Oct 8, 2026
…in code blocks (#5239)

#5657 let Ctrl/Alt/Cmd+Backspace reach the browser so it can delete a whole
word or line. Two gaps remained.

`resolveEndpoint` read the DOM offset of an element-anchored selection as a
character offset. A native "delete to line start" clears the last line, leaves
a trailing `<br>`, and parks the caret on the content element itself — so the
surviving text `foo\n` resolved to offset 1 and the caret jumped into `foo`.
Translate the child index into a text offset for that anchor. Endpoints inside
a child node keep the legacy mapping, which the inline-image paths compensate
for.

`CodeBlockContent.backspaceHandler` owns its own token-boundary fix-up and
never called `super`, so at a Prism token boundary it still intercepted the
chord and trimmed one character (`const|` -> `cons x = 1` instead of ` x = 1`).
Defer to the browser there too, after the offset-0 branch that converts the
block to a paragraph.
Jocs added a commit that referenced this pull request Oct 8, 2026
…in code blocks (#5239) (#5658)

#5657 let Ctrl/Alt/Cmd+Backspace reach the browser so it can delete a whole
word or line. Two gaps remained.

`resolveEndpoint` read the DOM offset of an element-anchored selection as a
character offset. A native "delete to line start" clears the last line, leaves
a trailing `<br>`, and parks the caret on the content element itself — so the
surviving text `foo\n` resolved to offset 1 and the caret jumped into `foo`.
Translate the child index into a text offset for that anchor. Endpoints inside
a child node keep the legacy mapping, which the inline-image paths compensate
for.

`CodeBlockContent.backspaceHandler` owns its own token-boundary fix-up and
never called `super`, so at a Prism token boundary it still intercepted the
chord and trimmed one character (`const|` -> `cons x = 1` instead of ` x = 1`).
Defer to the browser there too, after the offset-0 branch that converts the
block to a paragraph.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Ctrl+Backspace deletes only one character at the end of a line in WYSIWYG

2 participants