MoonshotAI / MoonshotAI/kimi-cli
[Feature Request] Opt-out of alt-screen/high-frequency redraws for Neovim :terminal use
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 11.4k
- Forks
- 1.3k
- Avg merge
- 9h 47m
- Merged PRs (30d)
- 2
Description
[Feature Request] Opt-out of alt-screen/high-frequency redraws for use inside host terminal buffers (Neovim :terminal)
What version of Kimi Code CLI is running?
1.37.0
Which open platform/subscription were you using?
Moderato Plan
Which model were you using?
kimi-for-coding
What platform is your computer?
Nobara Linux 43 (Fedora 43 base), KDE Plasma, Wayland
What issue are you seeing?
When kimi runs inside a Neovim terminal buffer (:terminal-backed by toggleterm, as part of a Neovim "agent cockpit" layout), the current Kimi TUI is effectively unusable for reading back long replies because its continuous cursor-position writes keep pulling the visible viewport back to the bottom of the buffer.
Concrete symptom: after pressing <Esc> to enter Neovim's terminal-normal mode (the mode that lets me use regular motions like gg, k, <C-u> to scroll through earlier output), the viewport snaps back to the bottom of the buffer the moment the next frame from Kimi arrives. The result looks like flicker: my cursor is briefly where I moved it to, then yanked back. I can never hold a position to read earlier content.
This does not happen with other agent CLIs under the exact same Neovim + tmux + Ghostty stack:
- Claude Code ships
NO_FLICKER=1. SettingNO_FLICKER=1makes Claude Code stop aggressively repainting its UI, so<Esc>+ scrollback inside Neovim's terminal works perfectly. - Codex and Gemini CLI default to more conservative repaints and also behave correctly inside Neovim's terminal.
- Kimi (via plain
kimi) is the outlier — the scroll-snap-to-bottom happens even with or without the thinking spinner, so the cause isn't just the animation.
I searched the documentation and open issues/PRs, and checked how other coding agents handle this, to find a configuration that can make Kimi behave as a well-embedded panel inside a host terminal buffer — couldn't find one. Related prior art: #1212 (fish-style Ctrl-L pushing content into scrollback) and #1326 (terminal resize fixes) suggest the TUI renderer is aware of scrollback concerns but doesn't offer an opt-out.
What steps can reproduce the bug?
-
Install Neovim 0.12+ (tested on 0.12.1), Ghostty (tested on 1.3.1), tmux 3.5a.
-
Start tmux inside Ghostty.
-
Launch Neovim. Use any terminal plugin (I'm on
akinsho/toggleterm.nvim) to open a vertical split runningkimi:local Terminal = require("toggleterm.terminal").Terminal local kimi = Terminal:new({ cmd = "kimi", hidden = true, direction = "vertical", count = 16 }) vim.keymap.set("n", "<leader>tk", function() kimi:toggle() end) -
Send
kimia prompt long enough to produce a reply that fills several screens (e.g. "give me a 100-line overview of X"). Wait for it to finish streaming. -
Press
<Esc>inside the Kimi window to enter Neovim's terminal-normal mode. -
Try to scroll up with
gg,<C-b>, ork.
Expected: the viewport stays where I moved it; I can read the earlier part of the reply at my own pace.
Actual: the viewport is jerked back to the bottom of the buffer repeatedly. Kimi is emitting cursor-positioning escape sequences (likely as part of its input buffer / status line repaint) that Neovim's terminal buffer faithfully applies, overriding my own cursor position and forcing the window to follow the new bottom-anchored cursor.
What is the expected behavior?
I can see two reasonable fixes:
-
Add an env var (preferred, matches Claude Code precedent):
KIMI_CLI_NO_ALT_SCREEN=1 # or KIMI_CLI_NO_FLICKER=1When set, Kimi should avoid alt-screen mode and/or coalesce cursor repositioning to only happen when the frame actually needs to change. This is exactly the shape of Claude Code's
NO_FLICKER=1, which makes Claude Code well-behaved as an in-Neovim panel. -
Or a CLI flag:
kimi --static-tui,kimi --no-altscreen, etc. Env var is nicer because Neovim config can set it once and apply to every spawn ofkimi, but either is an improvement.
Beyond the redraw gating, adding documentation somewhere like usage/interaction.md that says "Kimi works best in a standalone terminal; if running inside a host terminal buffer set $KIMI_CLI_NO_ALT_SCREEN=1" would help people who want to use Kimi from Neovim / Zed / Emacs / tmux popups.
Additional information
Environment (captured inside the affected Neovim terminal):
TERM=xterm-256colorTERM_PROGRAM=tmux(outer terminal is Ghostty 1.3.1; we overrideTERM_PROGRAM=ghosttyinside tmux for yazi but that doesn't affect Kimi's behavior)COLORTERM=truecolorTMUXis setallow-passthrough onis enabled in.tmux.conf(needed for kitty graphics protocol foryazi; shouldn't be interfering)- Neovim terminal is managed by
toggleterm.nvimv. latest,cmd = "kimi",direction = "vertical"
For reference, Claude Code's equivalent launch line in the same setup works fine:
Terminal:new({ cmd = "NO_FLICKER=1 claude --effort max --dangerously-skip-permissions", ... })
I'd be happy to test a PR / nightly build that adds the env-var switch.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the behavior by running kimi in a Neovim :terminal buffer and entering terminal-normal mode while a long reply streams. Inspect the CLI TUI renderer's redraw and cursor-positioning behavior, then add and document the agreed opt-out if the implementation supports it. Update usage/interaction.md if that documentation location is selected, and verify that scrolling remains stable in the stated setup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux, neovim, python
- Domain
- cli, developer-experience
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100