It's been a while…

I haven't published a public note in July. Not that I haven't written anything, far from that. Just didn't publish.

Okay, some updates:

Add buffer name autocomplete to cape

I use cape.el to manage specific completion-at-point functions. The most used ones for me are {C-c t f} - complete file name and {C-c t s} - complete Elisp symbol.

After starting using ghostel with Claude Code being able to complete the buffer name became more desirable than ever, so I can quickly drop into notes things like this:

  • (vux-ghostel-buffer "cape-buffer")

Asked Claude, it wrote "cape-buffer-name" function, bound to {C-c t b}. Works!

(defun cape-buffer-name ()
  "Completion-at-point function for open buffer names."
  (let ((bounds (or (bounds-of-thing-at-point 'symbol)
                    (cons (point) (point)))))
    (list (car bounds) (cdr bounds)
          (completion-table-dynamic
           (lambda (_) (mapcar #'buffer-name (buffer-list))))
          :exclusive 'no
          :annotation-function (lambda (_) " Buffer"))))

(use-package cape
  :after (tempo)
  :config
  (setq cape-elisp-symbol-wrapper '())
  (setq cape-keymap (make-sparse-keymap))
  (let ((map cape-keymap))
    (keymap-set map "<tab>" #'completion-at-point)
    (keymap-set map "b" (lambda () (interactive)
                          (cape-interactive #'cape-buffer-name)))
    ;; (keymap-set map "t" #'complete-tag)
    (keymap-set map "t" #'tempo-complete-tag)
    (keymap-set map "d" #'cape-dabbrev)
    (keymap-set map "f" #'cape-file) ;; using often
    (keymap-set map "k" #'cape-keyword)
    (keymap-set map "s" #'cape-elisp-symbol) ;; using often
    (keymap-set map "a" #'cape-abbrev)
    (keymap-set map "l" #'cape-line)
    (keymap-set map "w" #'cape-dict)
    (keymap-set map "_" #'cape-tex)
    ;; (keymap-set map "&" #'cape-sgml)
    ;; (keymap-set map "r" #'cape-rfc1345)
    t)
  (keymap-global-set "C-c t" cape-keymap))

Screenshot:

260630--cape-complete-buffer__emacs_screenshot.png

Create Graphviz graph out of a picture

I was cleaning my screenshots directory and spotted one from the "Wisey" service that teaches you mindfullness and habits. I didn't go to subscribe to the service but I did save the screenshot.

I asked Claude Code: I want Graphviz graph that looks as close as possible to this file:

260629--morning-routine-wisey__screenshot.png

And here's the result I got in a minute:

(vux-ghostel-buffer "graphviz-morning-routine")
260629--morning-routine__graphviz.png

Not bad, huh?

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)))
  1. Define function easy-kill-on-buffer-name.
  2. Add binding to 'easy-kill-alist.

Integrating format-all with terraform-ts-mode

· :Emacs:

In order for format-all picks up terraform-fmt formatter of Terraform files, when using Tree Sitter with terraform-ts-mode, the mode should be registered in language-id package like this:

(when-let ((terraform-def (assoc "Terraform" language-id--definitions)))
   (setcdr terraform-def '(terraform-mode terraform-ts-mode)))

Added to Pavel's Emacs Configuration v3 to (use-package format-all) block.

kids-unicode-mode

Emacs supports Unicode:

(insert-char (char-from-name "T-REX")) ;; 🦖

To have fun with kids, I wrapped kids-unicode minor mode that brings keymap redefining every key to insert emoji. Enable with {M-x kids-unicode-mode} and have fun typing, encoding names with emojis and train memory.

(use-package kids-unicode-mode :ensure nil)

Source: kids-unicode-mode.el

Showcase: 260516--kids-unicode-mode__screenshot.png

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)

New agent skill – youtube-monitor

Below is the content of ~/.claude/skills/youtube-monitor/SKILL.md that I fully wrote myself. You can see results by searching for YouTube tag. I added a Claude Routine to run this skill daily. Let's see how it would work.

---
name: youtube-monitor
description: Monitor and summarize new YouTube videos from channels I follow.
compatibility: Requires curl and network access.
allowed-tools: Bash WebSearch
---

## Instructions

### Step 1: Identify channells that I follow

Check `elfeed-feeds` variable in Emacs (via `emacsclient`), filter YouTube
channels.

### Step 2: Find latest videos using /youtube-finder skill

Exclude shorts.

### Step 3: Find new videos that were not yet summarized

Run this shell command, providing correct user handle of the channel:

```sh
cat ~/Notes/youtube_summaries.org | grep -E '(<handle>)' -A5 | head -n 10
```

In results will be the last summarized video, all videos after that are new.

### Step 4: Summarize each new video

Summarize each new video using /youtube-summarizer skill, write new
summary to ~/Notes/youtube_summaries.org file as the first heading,
using this template:

```org-mode
* <title of the video> – <name> (<handle>)   YouTube
:PROPERTIES:
URL <url of the video>
DURATION <MM:SS>
PUBLISHED <YYYY-MM-DD DOW>
END
- <url of the video>

<abstract>

/summary generated by my "YouTube summarizer" AI skill./

<full summary, if using subheadings, only H2 are allowed>
```