shift+enter keybinding not working · Issue #1505 · anomalyco/opencode · GitHub
Skip to content

shift+enter keybinding not working #1505

Closed

Description

@bluenex

I noticed that the shift+enter keybinding, which is supposed to insert a newline in the input field, doesn’t seem to work. However, the alternative keybinding ctrl+j works fine for the same action.

Expected Behavior

When I press shift+enter, it should insert a newline in the input field.

Observed Behavior

  • Pressing shift+enter
    • Does nothing when the input is blank
    • Send the message when the input is not blank
  • On the other hand, ctrl+j works as expected and inserts a newline.

Steps to Reproduce

  1. Open OpenCode.
  2. Focus on an input field.
  3. Press shift+enter to try inserting a newline.
  4. Notice that nothing happens.

Environment

  • Platform: macOS M2 (version 14.6.1)
  • Terminal: tested on Terminal and Warp
  • Version: tested on dev branch

Analysis by Qwen3 Coder

That's the key! Looking at the editor code, I can see what's happening:

  1. When a key event occurs, the editor first checks if msg.Text != "" (line 126)
  2. If there's text in the message, it directly passes the message to the textarea's Update method (line 128)
  3. ctrl+j is interpreted by the terminal as a newline character (\n), so msg.Text contains "\n"
  4. This gets passed directly to the textarea, which inserts it as a newline

However, shift+enter is not interpreted as text by the terminal - it's sent as a special key event. Since there's no msg.Text for shift+enter, the code doesn't take the early return path, and instead continues to process the key event through the rest of the switch statement.

The issue is that shift+enter is not being handled specifically in the editor's key processing logic. Let me look at where commands are actually executed:
qwen/qwen3-coder:free (09:00 PM)

Now I understand the issue! Looking at the code flow:

  1. In the TUI's Update method, key events are first checked against commands using a.app.Commands.Matches(msg, a.app.IsLeaderSequence) (line 304 in tui.go)
  2. If a command matches, it gets executed via commands.ExecuteCommandsMsg(matches) (line 310)
  3. The InputNewlineCommand is configured with keybindings for "shift+enter" and "ctrl+j" (line 299 in command.go)

The problem is that when shift+enter is pressed:

  1. It matches the InputNewlineCommand
  2. The command gets executed
  3. But there's likely no handler for InputNewlineCommand that actually calls the editor's Newline() method

Let me check where commands are actually executed:
qwen/qwen3-coder:free (09:00 PM)

Activity

  1. the-vampiire commented on Aug 15, 2025

    @the-vampiire

    I’m going to close #1941 but do want to note that this only happens in vscode for me. i dont have this issue when running in iterm or ghostty

  2. fmatsos commented on Aug 15, 2025

    @fmatsos

    I’m going to close #1941 but do want to note that this only happens in vscode for me. i dont have this issue when running in iterm or ghostty

    I have the issue on Fedora with ddterm. I know some teammates have the issue too, but idk which terminal (on linux distro too).

  3. wanjuntham commented on Aug 16, 2025

    @wanjuntham

    I face the same issue on mac built-in terminal and vscode.

  4. rekram1-node commented on Aug 16, 2025

    @rekram1-node
    Collaborator

    @wanjuntham some terminals/multiplexers don't pass this through right, you can use ctrl+j in those cases, or you can remap the keybind

  5. wanjuntham commented on Aug 16, 2025

    @wanjuntham

    @wanjuntham some terminals/multiplexers don't pass this through right, you can use ctrl+j in those cases, or you can remap the keybind

    yes ctrl + j works, but I am already so used to shift + enter keybind for inserting a new line.

  6. rekram1-node commented on Aug 16, 2025

    @rekram1-node
    Collaborator

    yes definitely annoying, kinda depends on your emulator tho, in ghostty and zed shift+enter works fine (many others too)

  7. SMFloris commented on Aug 16, 2025

    @SMFloris

    In alacritty, you just need to add the following to map shift+enter to \n.

    [keyboard]
    bindings = [ { key = "Return", mods = "Shift", chars = "\n" } ]
    
  8. hamza-m-masood commented on Aug 19, 2025

    @hamza-m-masood

    I have noticed that when I am using tmux in ghostty terminal on my mac, the shift enter does not work in opencode.

  9. hd-o commented on Aug 29, 2025

    @hd-o

    Same here in vscode. Solved by remapping submit, then enter inputs a new line

    {
      "keybinds": {
        "input_submit": "alt+enter",
      },
    }
  10. CSRessel commented on Sep 8, 2025

    @CSRessel

    I actually have this issue in ghostty on Linux, but not when running another other TUI application I have built within ghostty

  11. ahosker commented on Sep 11, 2025

    @ahosker
    Contributor

    Very new to this tried Shift + Ender on termius and it acted as a submit.

  12. mrgoonie commented on Sep 14, 2025

    @mrgoonie

    I still cannot get shift+enter works in Warp terminal (ctrl+j works), quite frustrating 😂
    Ps. shift+enter works on iTerm2

  13. joseph-hlucny commented on Sep 20, 2025

    @joseph-hlucny

    Consider implementing a default configuration that works with vscode.
    ctrl + j is a default keybinding in vscode to toggle panel (e.g., terminal) visibility
    shift + enter doesn't work

  14. esafak commented on Sep 23, 2025

    @esafak
    Contributor

    shift+enter used to work in ghostty with macos, and it no longer does. I use nushell, if that helps.

  15. 111 remaining items

  16. anentropic commented on Mar 11, 2026

    @anentropic

    Why are the default keybindings so bad?

  17. codingthat commented on Mar 25, 2026

    @codingthat

    @hamza-m-masood @hasanfaesal Thanks for sharing! I'm curious if there were some other steps left out or something... how did either of you get this working as-is?

    {
      keybinds: {
        input_submit: return,
        input_newline: shift+return
      }
    }
    

    Aside from the missing quote marks, in ~/.config/opencode/opencode.json it's against the schema and I get an error Property keybinds is not allowed.

    According to https://opencode.ai/docs/keybinds/ it belongs in tui.json, but even when I put this:

    {
        "$schema": "https://opencode.ai/tui.json",
        "keybinds": {
            "input_newline": "shift+return",
            "input_submit": "return"
        }
    }

    ...in ~/.config/opencode/tui.json (which didn't exist beforehand), and add the other two lines to tmux.conf (which came with one other line already, set -ga terminal-overrides ',xterm*:smcup@:rmcup@') and source the update as stated, it unfortunately doesn't work when I reattach, even if I create a new tmux window and open a fresh opencode.

  18. jcubic commented on Mar 25, 2026

    @jcubic

    I come to the conclusion that this is just a limitation of the terminal emulator if you don't have a way to remap the keys. OpenCode can't do anything if Terminal Emulator doesn't have such a feature.

  19. hamza-m-masood commented on Mar 25, 2026

    @hamza-m-masood

    @codingthat I ended up moving away from tmux and installed cmux terminal instead. Try it out! I think you will most probably like it and get used to it if you are proficient in tmux.

  20. codingthat commented on Mar 26, 2026

    @codingthat

    Many thanks @hamza-m-masood — I'm on Linux Mint but I appreciate the recommendation nonetheless =)

  21. Grey2k commented on Apr 2, 2026

    @Grey2k

    hi, any ideas about MacOS with JetBrains IDE Terminal -

    shift+enter works well in iTerm2 , but not in IDE

  22. anggaaryas commented on May 17, 2026

    @anggaaryas

    Both shift + return and opt + return doesnt work in mac default terminal.

  23. zjtalia commented on May 27, 2026

    @zjtalia

    for tmux users, the workaround detailed in this claude code issue worked for me!

    Also, the Proposed Fix from the linked issue would be a simple way for OpenCode to resolve this issue as well.

  24. oribarilan commented on May 27, 2026

    @oribarilan
    Contributor

    btw, if you are familiar with vim-motions, another option is to use plain old return, in insert mode, with this plugin i created:
    github.com/oribarilan/vimcode

  25. Nowaker commented on Jun 3, 2026

    @Nowaker

    I come to the conclusion that this is just a limitation of the terminal emulator if you don't have a way to remap the keys. OpenCode can't do anything if Terminal Emulator doesn't have such a feature.

    Somehow other tools can do Shift+Enter just fine - only OpenCode is affected. This is just a limitation of OpenCode that needs fixing.

  26. kikoreis commented on Jun 4, 2026

    @kikoreis

    Looked into this a bit today and here is a summary for whoever shows up here to complain.

    The reason why this is inconsistent is because it depends on how the terminal you are using encodes the keystroke when sending it to the pty, which is where opencode reads it from. There are three cases:

    • ghostty, Wezterm, Warp, alacritty and other newer terminals support the kitty protocol for keystroke encoding, and if opencode is doing the right thing, they should work. Some of these need kitty to be explicitly enabled; I know ghostty enables it by default.
    • Some terminals allow defining custom encodings for keystrokes; Windows Terminal I believe is an example
    • Now for the sad part. gnome-terminal (and the newer ptyxis) which gnome-based distros default to, and which both use the GNOME VTE library, do not yet support kitty nor allow configuring a custom encoding.

    In the legacy (non-kitty) protocol, neither Ctrl- nor Shift-enter generate an encoding distinct from Enter. But Alt-Enter does, and it does work in gnome-terminal and ptyxis — but not in textareas like this one. Annoyingly, Ctrl-Enter submits so you can't learn to use that either!

    If you want to know more than you need to about this issue, the kitty protocol link I provided above has the nitty gritty. There has been work done to implement kitty support in VTE but it's yet merged and may be stalled and looking for help.

  27. AlwaysYng commented on Aug 31, 2026

    @AlwaysYng

    OpenCode TUI: Use linefeed Instead of ctrl+j for input_submit

    In my tests with Windows Terminal and XShell 8 using showkey -a:

    Key Raw input OpenTUI event
    Enter \r (0x0d) return
    Shift+Enter \r (0x0d) return
    Ctrl+M \r (0x0d) return
    Ctrl+Enter \n (0x0a) linefeed
    Ctrl+J \n (0x0a) linefeed

    OpenTUI parses raw \n as linefeed, which Textarea maps to a newline.

    To make Enter insert a newline and Ctrl+Enter submit, use:

    {
      "$schema": "https://opencode.ai/tui.json",
      "keybinds": {
        "input_newline": "return",
        "input_submit": "linefeed"
      }
    }

    Result:

    • Enter, Shift+Enter, and Ctrl+M insert a newline.
    • Ctrl+Enter and Ctrl+J submit the prompt.

    No terminal remapping is needed for this raw CR/LF setup. Distinguishing Ctrl+Enter from Ctrl+J requires the terminal to send a distinct sequence, such as CSI-u.

    Version note: this was tested with OpenCode v1.18.25, which uses OpenTUI v0.4.5. The same behavior remains in OpenTUI v0.5.9.

    Relevant OpenTUI v0.5.9 source:

  28. rahul-behera commented on Oct 21, 2026

    @rahul-behera

    OpenCode TUI: Use linefeed Instead of ctrl+j for input_submit

    In my tests with Windows Terminal and XShell 8 using showkey -a:

    Key Raw input OpenTUI event
    Enter \r (0x0d) return
    Shift+Enter \r (0x0d) return
    Ctrl+M \r (0x0d) return
    Ctrl+Enter \n (0x0a) linefeed
    Ctrl+J \n (0x0a) linefeed
    OpenTUI parses raw \n as linefeed, which Textarea maps to a newline.

    To make Enter insert a newline and Ctrl+Enter submit, use:

    {
    "$schema": "https://opencode.ai/tui.json",
    "keybinds": {
    "input_newline": "return",
    "input_submit": "linefeed"
    }
    }
    Result:

    • Enter, Shift+Enter, and Ctrl+M insert a newline.
    • Ctrl+Enter and Ctrl+J submit the prompt.

    No terminal remapping is needed for this raw CR/LF setup. Distinguishing Ctrl+Enter from Ctrl+J requires the terminal to send a distinct sequence, such as CSI-u.

    Version note: this was tested with OpenCode v1.18.25, which uses OpenTUI v0.4.5. The same behavior remains in OpenTUI v0.5.9.

    Relevant OpenTUI v0.5.9 source:

    Thanks this worked for. Other suggestions didn't.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingopentuiThis relates to changes in v1.0, now that opencode uses opentui

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions