claude-pager
On <2026-06-03 Wed> I somehow bumped into idea to use emacsclient as EDITOR in Claude Code.
Turns out CC respects EDITOR env variable, either from environment or configured in ~/.claude/settings.json:
{"env": {"EDITOR": "emacsclient", "VISUAL": "emacsclient"}}
Even if [Feature Request] Allow configuring external editor for Ctrl-G prompt editing · Issue #18990 · anthropics/claude-code is still in open.
In that issue I spotted this project: gradigit/claude-pager. Fast C transcript pager for Claude Code: no blank Ctrl-G screen, clickable links/files, queued prompt composer. And its sister editor: gradigit/turbodraft.
Tried both. Turbodraft - I don't need another text editor rather than Emacs, so skipping it. But claude-pager looks useful, so I forked it.
First, I wired Emacs into claude-pager; so that it renders transcripts in both CC screen when it waits for the prompt + adds it to Emacs temporary buffer.
This mostly solves clunkiness of copying from claude terminal into Emacs and back - now I press {C-g} in claude and continue editing in Emacs.
Related to Agent SDK billing and parting ways with agent-shell.
This is how my env block looks like in ~/.claude/settings.json.
{
"env": {
"EDITOR": "/Users/pavel/.velppa/claude-pager/bin/claude-pager-open",
"CLAUDE_PAGER_EDITOR": "/Users/pavel/.velppa/claude-pager/emacs/claude-emacs-prompt",
"CLAUDE_PAGER_EDITOR_TYPE": "gui"
}
}
{C-g} in claude opens claude-pager-open that generates transcript and pastes it into both terminal and to the temp file to edit in Emacs, then runs claude-emacs-prompt shell file that calls elisp file which loads into the buffer, assigns keybindings etc.
Setup involves adding hooks:
SessionStart hook:
26: "command": "/Users/pavel/.velppa/claude-pager/shim/save-session-transcript.sh"
Then I rewrote the binary from C to Zig. Rewrite used Superpowers to develop a spec first, then launch a series of agents. It took 4+ hours for CC to finish rewrite, it was ready in the morning. It used all extra usage (42 EUR) in fast mode in first 20 minutes.
7000 loc in C => ??? in Zig.
Now I understand the C well.
Another interesting project from the same author:
- gradigit/confetti - Lightweight confetti animation for macOS — fire colorful confetti from your screen corners
Copy buffer-name with easy-kill
easy-kill Emacs package allows killing multiple things, switching between them on the fly. I use it to quickly grab the buffer-file-name (full path or file name only), using {M-w b}.
- github
- leoliu/easy-kill
Keybindings:
- {M-w} without active region
- copy current line, same as {x y} in meow-normal-mode
- {M-w C-w} without active region
- kill current line, same as {x s} in meow-normal-mode
- {M-w b}
- copy current full path to buffer-file-name
- {M-w b 0}
- copy current buffer-file-name
- {M-w b -}
- copy current directory
On <2026-06-04 Thu> I added {M-w B} to copy current buffer-name, useful to paste into Claude Code (running under ghostel for me).
Here's the configuration block:
(use-package easy-kill
:config
(keymap-global-set "<remap> <kill-ring-save>" #'easy-kill)
(defun easy-kill-on-buffer-name (_n)
"Get current `buffer-name'."
(if (easy-kill-get mark)
(easy-kill-echo "Not supported in `easy-mark'")
(easy-kill-adjust-candidate 'buffer-name (buffer-name))))
(add-to-list 'easy-kill-alist '(?B buffer-name)))
- Define function
easy-kill-on-buffer-name. - Add binding to 'easy-kill-alist.
Agent Skills collections
Okay, there are many of Agent Skills collections.
Storing those that I encountered here:
- obra/superpowers (from Jesse Vincent of Keyboard.io)
- forrestchang/andrej-karpathy-skills
- affaan-m/everything-claude-code (SLOP!)
- anthropics/financial-services
- mattpocock/skills
- JuliusBrussee/caveman (I'm using only it)
- exploreomni/omni-claude-skills
Superpowers
An agentic skills framework & software development methodology that works.
- github
- obra/superpowers
CAVEMAN vs Superpowers
Stacking: orthogonal. Run both → superpowers process + caveman terse output.
caveman
- Purpose
- output compression, cuts tokens ~75%
- Affects
- how Claude speaks — style only
- Skills
caveman,caveman-commit,caveman-review,caveman-compress,caveman-stats,caveman-help- Agents
cavecrew-investigator,cavecrew-builder,cavecrew-reviewer(compressed output)- When active
- persistent mode (every response)
- Token cost
- saves tokens
superpowers
- Purpose
- workflow scaffolding, methodology + process skills
- Affects
- what Claude does — multi-step procedures
- Skills
brainstorming,writing-plans,executing-plans,test-driven-development,systematic-debugging,subagent-driven-development,dispatching-parallel-agents,using-git-worktrees,requesting-code-review,receiving-code-review,verification-before-completion,finishing-a-development-branch,writing-skills,using-superpowers- Agents
- none direct
- When active
- invoked per-task (Skill tool)
- Token cost
- spends tokens (more thorough flows)
caveman
- github
- JuliusBrussee/caveman
- HN
- Caveman: Why use many token when few token do trick | Hacker News
- YouTube
- No way this actually works - YouTube - ThePrimeTime
Why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman.
I tried it on <2026-04-11 Sat> on Mac Mini 2024 and on Mac Book Pro M1.
claude plugin marketplace add JuliusBrussee/caveman && claude plugin install caveman@caveman claude plugin uninstall caveman@caveman && claude plugin marketplace remove caveman
Uninstalled after reading HN comments. Installed again recently.
Caveman in gptel
Add caveman as a gptel directive:
(setq gptel-directives
(cons '(caveman . "CAVEMAN MODE: Drop articles/filler/pleasantries/hedging. Fragments OK. Short synonyms. Pattern: [thing] [action] [reason]. [next step]. Keep full technical accuracy. Code unchanged.")
gptel-directives))
Select with C-c C-d in gptel buffer.
HN comments summary
A developer created "Caveman," a Claude Code skill that forces the AI to respond in simplified, caveman-like language to reduce token usage by approximately 75%. The author clarifies this is mostly a joke and targets visible output (removing preambles and filler text), not the hidden "thinking" tokens that improve performance. They acknowledge the ~75% claim needs proper benchmarking and note that the skill doesn't affect code quality itself.
The Hacker News community is highly skeptical, with many arguing that tokens are "units of thinking" for LLMs—reducing them could make the model dumber by limiting its reasoning capacity. Critics point out that chain-of-thought reasoning requires verbose output, and forcing concise responses may degrade performance. However, some find the concept useful for cutting through verbose AI responses, comparing it to telegram-style communication or noting that similar concise prompting can work without harming quality for simple tasks. The debate centers on whether this actually saves meaningful costs versus potentially sacrificing accuracy.
SafariTabs.app v0.2.0
On <2026-05-07 Thu> I do several improvements to SafariTabs.app.
- Dragging swimlanes, so I can rearrange them to follow Spaces 3, 4, 5.
- Rename windows, mine are "Personal", "Work – Tech", "Work – Communications"
- Auto-sized swimlanes: each column takes 1/3 of the app window, capped at 1/6 of the current display — so a half-screen window always fits 3 columns and a maximised one fits 6, on any resolution.
terraform-ts-mode
At work I work with Terraform, so need to edit quite a lot of tf files in GNU Emacs. There's no built-in terraform-ts-mode Emacs package and I don't want to install regexp-based terraform-mode package
Existing terraform-ts-mode is this: kgrotel/terraform-ts-mode, which claims being experimental. So it's a good opportunity to learn how to create major modes using Tree Sitter and on <2026-05-05 Tue> I built my own with Claude Code.
Installation: put terraform-ts-mode.el to load-path.
Usage:
(use-package terraform-ts-mode :ensure nil
:init
(add-to-list 'major-mode-remap-alist '(terraform-mode . terraform-ts-mode)))
With this knowledge, the next step is [TK: try mickeynp/combobulate package].
SafariTabs.app
We need RSS for sharing abundant vibe-coded apps post by Matt Webb mentions Tabulator app, part of Wall of Apps by Matt Sephton. All the apps there share the same minimalist design, native Swift UI, tiny and, supposedly, fast. The downside is that they are paid.
I wanted to try Tabulator, as I use seal_safari_tabs.lua with Hammerspoon. So I built SafariTabs.app (using Claude Code, a project), source code is here – velppa/SafariTabs. Version v0.1.0.
Features:
- Fuzzy-searching for tabs
- Keyboard navigation
- Switching to the selected tab
- Close tab
- Headless mode, "safaritabs:" URL scheme
Let's see if I'm going to use it, if yes – will think about publishing a release. If you want to build it – clone the repo and ask Claude Code to build it.
Trying org-tufte for public notes
On <2026-04-28 Tue> I tried to add footnotes to notes in Textpod. It works, {C-c C-x f} adds a footnote link. Then publishing works normally, just make sure footnotes heading is level down of the published note (usually h2).
But, footnotes looks ugly, and rendered at the bottom. I want sidenotes, as in Tufte CSS. I remember org-tufte exporter, so decided to try. Apparently, there's newer version exists - Zilong-Li/org-tufte. Let's try it.
(use-package org-tufte :ensure nil)
Export to plain HTML looks fine, side-notes as footnotes work fine this is side note, but in Org file it's actually a footnote! . But when exporting into Textpod – body only, + custom HTML and JS injected – it breaks.
Okay, time to some vibe-coding. New package textpod-org-tufte.el.
HTML export to Textpod
On <2026-04-27 Mon> I'm once again fascinated how bad Markdown is and how broken the export is. So for Textpod I decided to skip Markdown, and export notes directly from Org to HTML.
Problem
Markdown can't handle lists properly.
This Org Mode block:
- github :: [[https://github.com/inanimate-tech/mist][inanimate-tech/mist]]
- posts ::
- [[https://interconnected.org/home/2026/02/12/mist][mist: Share and edit Markdown together, quickly (Interconnected)]]
- [[https://interconnected.org/home/2026/04/10/open-mist][mist is now open source and looking for interop (Interconnected)]]
: curl https://mist.inanimate.tech/new -T file.md
is exported as this Markdown block:
- **github:** [inanimate-tech/mist](https://github.com/inanimate-tech/mist)
- **posts:** - [mist: Share and edit Markdown together, quickly (Interconnected)](https://interconnected.org/home/2026/02/12/mist)
- [mist is now open source and looking for interop (Interconnected)](https://interconnected.org/home/2026/04/10/open-mist)
curl https://mist.inanimate.tech/new -T file.md
which is then converted to this HTML block:
- github: inanimate-tech/mist
posts: - mist: Share and edit Markdown together, quickly (Interconnected)
curl https://mist.inanimate.tech/new -T file.md
The list was rendered completely wrong.
When exporting from Org directly to HTML, it's correct - dl/dt/dd tags are used, comment rendered as verbatim text:
- github
- inanimate-tech/mist
- posts
curl https://mist.inanimate.tech/new -T file.md
Solution
Luckily, the change in texptpod.el is this:
- (org-export-string-as org-text 'md t)
+ (org-export-string-as org-text 'html t)
I also changed backend to preprocess internal links, they look like this:
../markdown.md // for Markdown export
../markdown.html#5B98C220-A8F4-4202-9708-82B0D000A4E9 // for HTML export
Preprocessing changes both to ?q=markdown., so search starts to /markdown.
which matches both md and html extensions.