An Emacs mode for a shitty coding agent
December 30, 2025 | View Comments
Claude Code is certainly an amazing piece of software. It's been at the forefront of agentic coding or agentic anything for a while now. Andrej Karpathy was inspired to have it hack his home automation system, after seeing someone control their oven with it, evidently taking --dangerously-skip-permissions to a whole new level.
But Claude Code is also arguably shitty, and I mean the terminal-based user interface (TUI), not the code that it outputs, which tends to be amazingly good these days.
That's why I ended up building pi-coding-agent, an Emacs mode for Mario Zechner's excellent pi. The Emacs mode gives you a nice, consistent, and guaranteed flicker-free user interface on top of pi, with separate windows for chat history and prompt composition, proper key bindings, while supporting all of pi's features. Here's a quick demo:
But let me explain what led me here!
What's wrong with Claude Code
It turns out that Claude Code's TUI is a React app that's rendered through a library called Ink. React in the terminal wasn't on my bingo card before I found out about it, but to the Node community it must seem natural? But so, Ink often isn't up to the task of rendering large streaming output. It frequently clears and redraws the whole screen, leading to crazy strobing while the terminal is busy scrolling and re-rendering, normally worth a seizure trigger warning. Apparently Gemini CLI shares these problems. But I hear they're working on it!
Another arguably shitty part of Claude Code is the Esc key, which has multiple uses: It's used to interrupt whatever Claude is doing. But when you're in a menu, it's also used to close that. Then, if you want to go back in your conversation history, you hit Esc twice. Paired with the fact that your terminal may become less responsive during re-rendering, so your Esc presses don't register in quick enough succession, there's a good chance you'll end up hitting Esc like a madman, and eventually burn down your session like an undersea telegraph cable.
Enter pi
But excuse me, enough shitting on other people's software. Enter: The Shitty Coding Agent, aka Mario Zechner's opinionated pi coding agent. pi is not just a coding agent, it's a whole toolkit. It's a reaction to some of the wrongs in Claude Code, namely its increasing feature bloat and magick, and the flickering. You should totally give it a try, because it comes with:
- complete transparency and control over the context
- a well-defined session format, and a built-in way to export to HTML
- cost and token tracking across providers
- a minimal toolset: no MCP, no plan mode, but easy to extend with your own tools
- headless operation through the RPC mode
- an author who keeps rejecting my pull requests
And finally, pi coding agent comes with its own TUI framework called pi-tui, which is pi's reaction to Claude's flickering issues. Thanks to it, there's no or almost no flicker by some accounts. My own experience is that I still see flickering occasionally, especially when there's large code blocks or so in the output, but then I'm also running pi in Eat mode, which might perform a little worse than terminals like Alacritty.
Okay, I have to admit: I lied when I said I would stop shitting on other people's software. There's one thing about the shitty coding agent that still annoys the hell out of me. And that's the inconsistent keyboard bindings.
While pi-tui implements some of the common readline-style shortcuts, others don't work, or don't work as expected. Take Ctrl+K, which deletes to end-of-line, but lacks a kill ring, and thus a way of pasting back what you cut via Ctrl+Y. You wrote an elaborate prompt but now you have to move it to the side and use it later? Your best bet is to either mark the text with the mouse and copy or you submit your prompt then abort immediately, to find it in the history later.
Also there's no undo of commands via Ctrl+_ or similar. No Ctrl+space to start a region and Ctrl+w to cut it, all of which a lot of people heavily rely on when editing text.
The Node ecosystem doesn't really have a proper readline library, which seems to be why pi-tui and Claude Code each implement their own little non-standards.
pi-coding-agent
Back to some of the awesome features of pi: pi comes with an option to run it in headless mode --mode rpc, which means you can drive it from any frontend, like Clawdis does, a personal AI assistant built on top of pi, which you can talk to from WhatsApp, Telegram, or Discord.
What's more, it allowed me to build an Emacs mode for pi! One that solves issues around terminal, shortcuts, and text handling, but also comes with fundamental improvements to user experience.
The Emacs mode implements most features of the pi coding agent, including markdown rendering and syntax highlighting in the chat window, switching models, session restore, an activity spinner, and stats showing your context window usage. There's some convenience like completions of sessions or branches, and easy switching between thinking modes and models through a mouse click.
Tool output is collapsible with a preview, and you can fold entire conversation turns with TAB (or cycle all with S-TAB) to keep long sessions manageable.
It also separates the prompt editor from the chat window, which for me is a big improvement: Imagine having one window for the chat history and one where you compose your prompts: both with their own cursor and scroll positions. This allows you to scroll through the chat window, copy text, and paste it into your prompt—without losing your place in either window.
It also auto-scrolls as new content streams in, but preserves your scroll position if you've scrolled up to read earlier content.
Finally, since your chat window is a fully-fledge Emacs buffer using markdown-mode, you can simply save the contents of the chat window, or copy parts of it into your blog, in addition to pi's built-in HTML export.
And of course there's more benefits from running this in Emacs: No flickering, no jumping, unlimited scrollback, proper key bindings (also Vim-style), and the ability to search, copy, and paste in the chat window just like in any other Emacs buffer.
While slash commands are still supported in the prompt editor for custom commands, for everything else there's a nice Magit-style keyboard menu that makes pi's shortcuts and settings easy to discover and use.
You can find pi-coding-agent on GitHub. To install, clone and add to your load path:
git clone https://github.com/dnouri/pi-coding-agent ~/.emacs.d/site-lisp/pi-coding-agent
(add-to-list 'load-path "~/.emacs.d/site-lisp/pi-coding-agent") (require 'pi-coding-agent)
You'll also need pi coding agent installed. Then run M-x pi-coding-agent to start a session.
Fun facts
I coded pi-coding-agent in a matter of days on-and-off. I never understood how to write elisp before, always struggled even with configuring Emacs. Now, with the help of AI-assisted programming, I was able to create a new mode that integrates neatly with the rest of the Emacs ecosystem, using common patterns and libraries like or and transient.
In addition to unit tests, I've also added GUI tests that start up an actual Emacs GUI to test some of the trickier aspects like auto-scroll. These first start up Emacs, then communicate via TCP/IP to run tests and observe outputs. It's a ton of fun going from an idea like this to an implementation in such a short amount of time. Driving Emacs to test my own package wasn't on my bingo card either for 2025.