Emacs keybindings frustratingly inconsistent
Description
So a fairly hardcoded sequence of keys in my brain for emacs is "Ctrl-A Ctrl-K", to go to the beginning of the line and delete it.
Unfortunately, currently in opencode:
- Ctrl-A takes you to the beginning of the entire text window, not the beginning of that line
- Ctrl-K then deletes the first paragraph, which is often something I spent over a minute writing
- There doesn't seem to be an "Undo" function to get this text back (e.g., Ctrl-_ or Cmd-Z)
This has happened to me three times today, and I don't remember it happening before; has something changed?
I could deal with the Ctrl-A behavior if there was some way to undo the Ctrl-K; but to have your work just go up in smoke is really frustrating.
OpenCode version
1.0.119
Steps to reproduce
- Type a paragraph
- Type a second paragraph
- Press "Ctrl-A" then "Ctrl-K" in quick succession
First paragraph is deleted instead of the second paragraph
Screenshot and/or share link
No response
Operating System
macOS
Terminal
Ghostty
This issue might be a duplicate of existing issues. Please check:
- #2649: Standard keyboard cursor navigation (Home/End key, ctrl+left/right key) - covers Ctrl+A behavior for line navigation
- #3978: Cannot Navigate the TextArea using Ctrl and Alt - covers similar keybinding navigation issues
- #3640: Surprising unexpected ctrl+p/ctrl+n behaviour - related to emacs keybindings not working as expected
- #1268: Basic undo feature - addresses the missing undo functionality that would prevent data loss
Feel free to ignore if none of these address your specific case.
C-k deleting instead of yanking is a readline-ism, lots of apps are like that (for example, most shells like bash/fish/etc and most other agent CLIs)... I do agree that I'd prefer yanking, but I've kind of gotten used to it, and I'm sure many other folks have the opposite preference and prefer it just how it is. shrug What can ya do?
undo/redo is ctrl+- (minus/dash) and ctrl+. (dot)
There are conflicting expectations all around on what the default bindings should be I am afraid. Just recently this one went into opentui https://github.com/sst/opentui/pull/344. I am currently not sure how to handle these conflicting expectations best.
Personally, I've long since grown accustomed to maintaining a 300+ line .el file of custom keybindings in my emacs config: so, I don't really care what the default keybindings are - so long as they can be rebound, I'm happy to do a little work and rebind keys myself.
Maybe we could have a second command that yanks the remainder of the line, not bound to any key by default but allowing those of us who'd prefer this behaviour to configure a keybinding for it ourselves? That way, we wouldn't change the default behaviour and surprise users who have come to expect it and those with different preferences would have a way to get what we want, keeping everybody happy.
@kommander It looks like opentui#344 is the main fix I want. Thanks for the undo -- I'll give that a try! Is that documented anywhere?
@ariane-emory I've gotten used to C-k is delete in bash as well; generally I really did mean to delete it and accept the consequences if I don't. But when you're expecting to delete the paragraph you're on and instead you end up delete a completely different paragraph, that's an issue.
I don't think new default keybindings are documented properly yet.
As for start/end of line the question is: logical or visual line?
When just typing along it will Auto wrap the text visually, but it is still just one logical line. So does it jump to the start of where it wrapped visually or to the beginning of the logical line, which could be considered a "paragraph"? I think there is a lot of confusion coming from that.
So does it jump to the start of where it wrapped visually or to the beginning of the logical line, which could be considered a "paragraph"?
It looks like macOS goes to the beginning of the logical line, and emacs in wordwrap mode goes to the beginning of the visually wrapped line; so either one seems like a reasonable choice. I'd say go with what you think is best, and feel free to chose based on what's easiest to implement.
There are conflicting expectations all around on what the default bindings should be I am afraid. Just recently this one went into opentui https://github.com/sst/opentui/pull/344. I am currently not sure how to handle these conflicting expectations best.
For cli apps, isn't readline by far the most commonly used thing, and thus the closest we have to a de-facto standard?
- https://man7.org/linux/man-pages/man3/readline.3.html
That's not to say that every app needs to mimic readline 100%, but just that a least-surprising design choice is to default to readline behaviors as much as is reasonable for a given app, since readline's behaviors are the behaviors that most cli users will expect.
A f**ing frustrating one for me is Alt-D which my neurons trigger to delete a word forward actually clears the entire prompt!
What OS and terminal emulator do you expect alt+d to be word forward deletion for? In the textarea it is currently mapped to delete-line which was the expectation from other users.
I'd like that in iTerm2 on MacOS. Since I live in emacs, I'm soooo accustomed to M-d aka alt+d meaning kill-word (delete the word ahead of point and put it in the clilpboard) that not having the same behaviour in opencode is something I frequently trip over.
Same here. I always expect Alt+D to delete the next word in CLIs, shells, repls. I even have my browser configured like that. I've never heard of Alt+D doing delete-line. I have lost multiple prompts in opencode due to this behavior, it's been very annoying. Alt+D doing kill-word has been the default behavior in any shell I can remember using - sh, bash, zsh, nushell. Same for REPLs like node, python, R, lua. It also works the way I expect in Claude Code.
+1 alt+d (M-D) does kill-word in readline, which is always what I consider to be the closest thing to an authority on cli line editing norms:
- https://man7.org/linux/man-pages/man3/readline.3.html#DEFAULT_KEY_BINDINGS
alt+d by default will be delete-word-forward. Additionally, all textarea input actions will be customizable, so any default that does not live up to personal standards can be remapped.
That will be a great frustration reducer! Please also link to documentation that lists all the default keybinds. (The keybind section of the opencode docs seems to only have a few examples)
(Edit: just saw your message on another issue about the newly extended documentation - thanks!)
For completeness https://opencode.ai/docs/keybinds/ - should list all the additional input_* binding possibilitie.