Bug: Codex TUI overrides terminal cursor style in Neovim :terminal

Open 💬 3 comments Opened May 8, 2026 by xzbdmw

What version of Codex CLI is running?

0.129.0

What subscription do you have?

pro

Which model were you using?

_No response_

What platform is your computer?

_No response_

What terminal emulator and version are you using (if applicable)?

ghostty+neovim 0.12

What issue are you seeing?

Codex emits ESC [ 0 q (DECSCUSR reset to default cursor shape) on every frame when not in Vim insert mode. In embedded terminal emulators like Neovim's built-in
:terminal, this actively overrides the host's configured cursor style (e.g. guicursor), forcing a blinking block cursor instead of the user's configured bar
cursor.

Environment

  • Codex CLI: v0.129.0
  • Neovim: 0.11+ (built-in terminal with "actual cursor" support)
  • OS: macOS (Apple Silicon)
  • Terminal: Neovim :terminal buffer

What steps can reproduce the bug?

Steps to Reproduce

  1. Configure Neovim with a bar cursor for terminal mode:

-- ~/.config/nvim/lua/init.lua
vim.o.guicursor = "n-sm-ve:block-Cursor,t-i-c-ci:ver16-Cursor,r-cr-v-o:hor7-Cursor"

  1. Open Neovim and enter a :terminal buffer.
  2. Confirm the cursor is a vertical bar (as configured by t:ver16-Cursor).
  3. Run codex inside the terminal buffer.
  4. Observe the cursor changes to a blinking block, ignoring the Neovim guicursor setting.

Minimal Reproduction (without Codex)

Inside a Neovim :terminal buffer, run:
printf '\033[0 q'
This sends the same escape sequence Codex emits, and the cursor changes from bar to blinking block — confirming the issue is the ESC [ 0 q escape.

Expected Behavior
When Codex has not intentionally changed the cursor style (i.e., not in Vim insert mode), it should not emit any cursor-shape escape sequence. The host
terminal's cursor configuration should be respected.

Actual Behavior

Codex emits SetCursorStyle::DefaultUserShape (ESC [ 0 q) on every render frame as the default cursor style. In embedded terminals, this is an active reset that
overrides the parent's cursor configuration, not a no-op.

Root Cause

The cursor_style() method in chat_composer.rs (line 4219) returns SetCursorStyle::DefaultUserShape for all non-Vim-insert states:

fn cursor_style(&self, _area: Rect) -> crossterm::cursor::SetCursorStyle {
if self.textarea.uses_vim_insert_cursor() {
crossterm::cursor::SetCursorStyle::SteadyBar
} else {
crossterm::cursor::SetCursorStyle::DefaultUserShape // ← the problem
}
}

This is also the default in renderable.rs (line 20-21) and used in custom_terminal.rs for initialization and reset.

DefaultUserShape is not "do nothing" — it actively sends ESC [ 0 q to the terminal. In standalone terminals this resolves to the user's configured default, but
in embedded terminals (Neovim, tmux with cursor passthrough disabled, etc.) it resolves to "blinking block" which may not match the host's configuration.

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

3 Comments

tummetott · 3 months ago

As far as I understand, this was introduced in 0.129.0 and is not Neovim specific. Codex suddenly started overriding the cursor style instead of respecting the cursor shape configured by the shell/terminal. For example, even when my cursor is configured as a bar, opening Codex standalone shows a block cursor. This behavior did not exist before.

abbbi · 3 months ago
As far as I understand, this was introduced in 0.129.0 and is not Neovim specific. Codex suddenly started overriding the cursor style instead of respecting the cursor shape configured by the shell/terminal. For example, even when my cursor is configured as a bar, opening Codex standalone shows a block cursor. This behavior did not exist before.

yes, starting codex in a regular xterm session will change the cursor type to a blinking block. Quitting codex leaves the cursor at this state w/o resetting original behavior.

cycne · 2 months ago

I can confirm this issue also affects old Konsole versions.

In my case, Codex emits DECSCUSR cursor-style sequences like ESC [ 5 SPACE q. xterm handles them correctly, but Konsole 2.14.2 does not support them and renders the final "q" literally on screen.

Changing TERM or terminfo did not help, because the sequence appears to be emitted directly by Codex.

As a temporary workaround, I patched the musl binary by replacing DECSCUSR sequences with NUL bytes while preserving binary size/offsets:

https://gist.github.com/cycne/ce8754d8adf25494431239bf9e53385b

A proper fix would probably be a config option to disable cursor-style escape emission, or avoiding DECSCUSR unless the terminal is known to support it.