Skip to content

Support running kakoune without a controlling /dev/tty terminal - #5528

Open
exlee wants to merge 1 commit into
mawww:masterfrom
exlee:fix-kakoune-without-terminal
Open

exlee wants to merge 1 commit into
mawww:masterfrom
exlee:fix-kakoune-without-terminal

Conversation

@exlee

@exlee exlee commented Jul 29, 2026

Copy link
Copy Markdown

This fixes issue when trying to run kakoune without controlling terminal (e.g. trying to run from within Claude Code in full-terminal mode).

Without the fix following crash happens:

Received SIGSEGV, exiting.
Callstack:
0   kak  Kakoune::Backtrace::Backtrace()
1   kak  Kakoune::(anonymous namespace)::signal_handler(int)
2   libsystem_platform.dylib  _sigtramp
3   kak  void Kakoune::select_coord<(Kakoune::SelectMode)1>(Kakoune::Context&, Kakoune::BufferCoord) + 76
4   kak  Kakoune::goto_commands<(Kakoune::SelectMode)1>(...)::'lambda'(Key, Context&)::operator()
5   kak  Kakoune::InputModes::NextKey::on_key(Kakoune::Key)
6   kak  Kakoune::InputHandler::handle_key(Kakoune::Key, bool)
7…  kak  execute-keys → context_wrap → CommandManager::execute → evaluate-commands

Fix resolves the issue, all tests are green.

Reproduction

Run Claude Code, run any prompt, press Left Arrow (that backgrounds the process and shows the list or thread), select the thread and press Ctrl-g (open Editor).

When kak is started from a background process, open("/dev/tty") fails.
TerminalUI::check_resize then bailed out early, leaving the terminal
dimensions at {0,0}: the whole screen stayed blank and window-relative
goto commands (gb) computed a negative buffer line, which Buffer::clamp
happily used to index m_lines out of bounds (SIGSEGV, the release build
compiles the guarding kak_assert away).

- check_resize now falls back to querying stdout, which we already
  require to be a terminal.
- Buffer::clamp clamps negative coordinates instead of relying on
  callers, and the gb computation no longer goes below the first line.
- Opening /dev/tty to restore stdin is now checked: on failure use
  /dev/null rather than leaving fd 0 pointing at the piped input that is
  already being consumed as the *stdin* fifo.
@Screwtapello

Copy link
Copy Markdown
Contributor

Why would you want to use Kakoune without a controlling terminal?

If you want to execute Kakoune's command language, you can use kak -f.

I guess Kakoune probably shouldn't crash, just exit with a non-zero exit code.

@exlee

exlee commented Jul 30, 2026

Copy link
Copy Markdown
Author

Why would you want to use Kakoune without a controlling terminal?

The case here is using Kakoune as $EDITOR within applications that are running in alternate-screen terminal. I checked bunch of other TUI/CLI editor (nano, neovim, vim, helix) and only Kakoune failed to launch in this environment.

Discovered by accident when I was trying to start Kakoune from within Claude Code running in full TUI mode.

Comment thread src/main.cc
{
int tty = open("/dev/tty", O_RDONLY);
if (tty < 0)
tty = open("/dev/null", O_RDONLY);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

So we cannot get any keyboard input in that case ? From what I understand we would just end-up with Kakoune showing up but no ability to directly interact with it except through kak -p. Am I missing something ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Correct, no keys in that case, but this branch only runs when stdin is piped (not a tty), so there was never a key source without /dev/tty. The old code left fd 0 racing against the *stdin* fifo reader on the same pipe. /dev/null turns that into a clean EOF/hangup instead.

@mawww mawww Aug 3, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Then we should probably error out in this case, which I would expect to happen due to the tty check in TerminalUI constructor (terminal_ui.cc:457). How come this does not fire ? Are we in a situation where stdout is a tty but /dev/tty does not exist ?

Do you have a use case for the half-failing behaviour being proposed ? (where Kakoune quits gracefully but does not provide any interactivity)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I don't have a use case, just a thought that it might be better than erroring out. Should I change that?

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants