Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/en/guides/interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ By default, up to 4 background tasks can run simultaneously. This can be adjuste

## Multi-line input

Sometimes you need to enter multiple lines, such as pasting a code snippet or error log. Press `Ctrl-J` or `Alt-Enter` to insert a newline instead of sending the message immediately.
Sometimes you need to enter multiple lines, such as pasting a code snippet or error log. Press `Shift-Enter`, `Ctrl-J`, or `Alt-Enter` to insert a newline instead of sending the message immediately.

After finishing your input, press `Enter` to send the complete message.

Expand Down
8 changes: 5 additions & 3 deletions docs/en/reference/keyboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ Kimi Code CLI shell mode supports the following keyboard shortcuts.
| `Ctrl-X` | Toggle agent/shell mode |
| `Shift-Tab` | Toggle plan mode (read-only research and planning) |
| `Ctrl-O` | Edit in external editor (`$VISUAL`/`$EDITOR`) |
| `Ctrl-J` | Insert newline |
| `Alt-Enter` | Insert newline (same as `Ctrl-J`) |
| `Shift-Enter` | Insert newline |
| `Ctrl-J` | Insert newline (same as `Shift-Enter`) |
| `Alt-Enter` | Insert newline (same as `Shift-Enter`) |
| `Ctrl-S` | Steer: inject input immediately into the running turn (during streaming) |
| `Ctrl-V` | Paste (supports images and video files) |
| `Ctrl-E` | Expand full approval request content |
Expand Down Expand Up @@ -60,10 +61,11 @@ Useful for writing multi-line prompts, complex code snippets, etc.

## Multi-line input

### `Ctrl-J` / `Alt-Enter`: Insert newline
### `Shift-Enter` / `Ctrl-J` / `Alt-Enter`: Insert newline

By default, pressing `Enter` submits the input. To enter multi-line content, use:

- `Shift-Enter`: Insert newline at any position
- `Ctrl-J`: Insert newline at any position
- `Alt-Enter`: Insert newline at any position

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/guides/interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Thinking 模式需要当前模型支持。部分模型(如 `kimi-k2-thinking-t

## 多行输入

有时你需要输入多行内容,比如贴入一段代码或错误日志。按 `Ctrl-J` 或 `Alt-Enter` 可以插入换行,而不是直接发送消息。
有时你需要输入多行内容,比如贴入一段代码或错误日志。按 `Shift-Enter`、`Ctrl-J` 或 `Alt-Enter` 可以插入换行,而不是直接发送消息。

输入完成后,按 `Enter` 发送整条消息。

Expand Down
8 changes: 5 additions & 3 deletions docs/zh/reference/keyboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ Kimi Code CLI Shell 模式支持以下键盘快捷键。
| `Ctrl-X` | 切换 Agent/Shell 模式 |
| `Shift-Tab` | 切换 Plan 模式(只读研究与规划) |
| `Ctrl-O` | 在外部编辑器中编辑(`$VISUAL`/`$EDITOR`) |
| `Ctrl-J` | 插入换行 |
| `Alt-Enter` | 插入换行(同 `Ctrl-J`) |
| `Shift-Enter` | 插入换行 |
| `Ctrl-J` | 插入换行(同 `Shift-Enter`) |
| `Alt-Enter` | 插入换行(同 `Shift-Enter`) |
| `Ctrl-S` | Steer:在 streaming 期间将输入立即注入到正在运行的轮次 |
| `Ctrl-V` | 粘贴(支持图片和视频文件) |
| `Ctrl-E` | 展开审批请求完整内容 |
Expand Down Expand Up @@ -60,10 +61,11 @@ Kimi Code CLI Shell 模式支持以下键盘快捷键。

## 多行输入

### `Ctrl-J` / `Alt-Enter`:插入换行
### `Shift-Enter` / `Ctrl-J` / `Alt-Enter`:插入换行

默认情况下,按 `Enter` 会提交输入。如需输入多行内容,可使用:

- `Shift-Enter`:在任意位置插入换行
- `Ctrl-J`:在任意位置插入换行
- `Alt-Enter`:在任意位置插入换行

Expand Down
5 changes: 3 additions & 2 deletions src/kimi_cli/ui/shell/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ def _build_toolbar_tips(clipboard_available: bool) -> list[str]:
"ctrl-x: toggle mode",
"shift-tab: plan mode",
"ctrl-o: editor",
"ctrl-j: newline",
"shift-enter / ctrl-j: newline",
"/feedback: send feedback",
"/theme: switch dark/light",
]
Expand Down Expand Up @@ -1321,8 +1321,9 @@ async def _toggle() -> None:

@_kb.add("escape", "enter", eager=True)
@_kb.add("c-j", eager=True)
@_kb.add("s-enter", eager=True)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 s-enter is not a valid prompt_toolkit key name, crashing CustomPromptSession.__init__

_kb.add("s-enter", eager=True) raises ValueError: Invalid key: s-enter at call time because s-enter does not exist in prompt_toolkit's ALL_KEYS (verified on both 3.0.28 and the pinned 3.0.52). Because Python evaluates stacked decorators bottom-up, this error fires before the c-j and escape+enter decorators above it are applied, so all three newline bindings fail to register and the CustomPromptSession.__init__ crashes entirely. This means the interactive shell UI cannot start at all.

Reproduction confirming the issue on prompt_toolkit 3.0.52
from prompt_toolkit.key_binding import KeyBindings
kb = KeyBindings()

try:
    @kb.add('escape', 'enter', eager=True)
    @kb.add('c-j', eager=True)
    @kb.add('s-enter', eager=True)
    def handler(event):
        pass
except Exception as e:
    print(f'Error: {e}')  # ValueError: Invalid key: s-enter

print(len(kb.bindings))  # 0 — none of the three bindings were registered

Shift+Enter is indistinguishable from Enter in most terminals because they both send \r. Modern terminals supporting the Kitty keyboard protocol can distinguish them, but prompt_toolkit does not expose a s-enter key. A different approach is needed (e.g., handling via a VT100 escape sequence or the Kitty protocol directly).

Prompt for agents
The key name `s-enter` is not recognized by prompt_toolkit (tested on 3.0.52, the pinned version). The `_kb.add("s-enter", eager=True)` call at `src/kimi_cli/ui/shell/prompt.py:1324` raises ValueError immediately, which also prevents the Ctrl-J and Alt-Enter bindings from being registered (since decorators are evaluated bottom-up), and crashes the entire CustomPromptSession.__init__.

Shift+Enter is fundamentally indistinguishable from Enter in classic terminal protocols (both send CR). Only terminals implementing the Kitty keyboard protocol can differentiate them, and prompt_toolkit has no built-in support for this.

Possible approaches:
1. Remove the `s-enter` binding entirely and keep only `c-j` and `escape+enter` (Alt-Enter) as before, updating docs accordingly.
2. If Kitty protocol support is desired, handle the raw escape sequence `\x1b[13;2u` (Shift+Enter in Kitty protocol) by adding it to prompt_toolkit's VT100 input parser, or use a custom key binding approach that works with terminals that report this sequence.
3. At minimum, the `@_kb.add("s-enter", eager=True)` line must be separated from the other two decorators (or wrapped in a try/except) so that its failure does not break Ctrl-J and Alt-Enter.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P0 Badge Replace unsupported Shift-Enter key spec

Using @_kb.add("s-enter", eager=True) introduces a startup-breaking binding because prompt-toolkit==3.0.52 does not define s-enter as a valid special key (it only supports s-tab and a limited set of other s-* keys), and KeyBindings.add() validates keys eagerly via _parse_key, which raises ValueError("Invalid key: s-enter") for multi-character unknown keys. As a result, constructing CustomPromptSession fails before the shell prompt can run.

Useful? React with 👍 / 👎.

def _(event: KeyPressEvent) -> None:
"""Insert a newline when Alt-Enter or Ctrl-J is pressed."""
"""Insert a newline when Alt-Enter, Ctrl-J, or Shift-Enter is pressed."""
from kimi_cli.telemetry import track

track("shortcut_newline")
Expand Down
Loading