4.9 KiB
title | date |
---|---|
Writing Emails In Kakoune | 2025-06-01 |
This post will guide you through my setup for using Kakoune as an email
composer inside aerc
. I'll also explain how to configure Kakoune to act
as the pager for reading text/plain
emails. If you only care about the
final config, feel free to skip to it here.
[TOC]
Naive Approach
Since aerc
uses your $EDITOR
for composition, you don't technically
have to do anything. I prefer setting it explicitly in aerc.conf
, for
good measure:
[compose]
editor=kak
The rest of the magic happens in your kakrc
.
Composer Setup
Essentially, we want to hook filetype=mail
and set our buffer
configuration there. I'll share a recommended configuration with some
explanation.
hook global WinSetOption filetype=mail %~
set-option window formatcmd '/home/fic/dev/utils/mail-utils/format.py'
set-option window comment_line '>'
try autospell-enable
hook -group mail-auto-format window BufWritePre .* format
hook -once -always window WinSetOption filetype=.* %{
unset-option window formatcmd
remove-hooks window mail-auto-format
}
~
I use a custom formatter to format emails. It automatically hard-wraps lines while preserving certain markup elements, code blocks, sign-offs, and signature blocks. For more details, check the formatting section of my post on Helix.
I find that setting >
as the comment_line
token is convenient for
working with quotes in replies.
The try autospell-enable
enables my
kak-autospell plugin for the
buffer. Essentially, it provides spellchecking that's continuously
refreshed and hidden in insert mode.
The remaining commands configure auto-formatting on save. I always prefer having this on so I never forget to format my message before sending it.
Reader Setup
I find that using Kakoune to read emails is helpful because of how
easy it is to copy quotes, open links, etc. Configuring this is a tad
hackier, however. The basic idea is to set Kakoune as the viewer pager
in aerc.conf
.
However, all this does is pipe the email to kak
through standard input,
so we need to tell the editor to treat it like an email:
[viewer]
pager=kak -e 'set buffer filetype mail'
When you're using Kakoune as a pager, you'll probably want to configure
some things differently. In my case, I like to set the buffer as
readonly
, remove the number-lines
and show-whitespaces
highlighters,
disable soft-wrap & my scrolloff settings, and not set any formatters.
The pager
command above sets the filetype, but we need to distinguish
between composing and reading in our Kakoune hook. When Kakoune is
opened with input through standard input, it loads a buffer that's
conveniently named *stdin*
. Thus, we can check the buffer name before
continuing.
If we're in "reading mode", we define a hidden command called
ismailreader
which doesn't do anything. Why? If the command is defined,
and we try to invoke it... well, nothing happens! But if it's not
defined, we get an error instead. We can combine this with the try
command to for some simple boolean logic.
evaluate-commands %sh{
# stdin, we assume it's a pager
if [ "$kak_bufname" = "*stdin*" ]; then
echo 'define-command -hidden ismailreader nop'
fi
}
try %{
ismailreader
# do reader config here
} catch %{
# do composer config here
}
I set the following configuration for "reader mode":
set buffer readonly true
try %{
remove-highlighter window/number-lines
remove-highlighter window/show-whitespaces
# custom commands defined elsewhere in my kakrc
ui-wrap-disable
ui-scrolloff-disable
}
Final Configuration
To recap, you'll want to set this in aerc.conf
:
[viewer]
pager=kak -e 'set buffer filetype mail'
# ...
[compose]
editor=kak
And the following in your kakrc
:
hook global WinSetOption filetype=mail %~
evaluate-commands %sh{
# stdin, we assume it's a pager
if [ "$kak_bufname" = "*stdin*" ]; then
echo 'define-command -hidden ismailreader nop'
fi
}
try %{
# READER MODE setup
ismailreader
set buffer readonly true
try %{
# remove these highlighters so everything displays properly
remove-highlighter window/number-lines
remove-highlighter window/show-whitespaces
ui-wrap-disable
ui-scrolloff-disable
}
} catch %{
# WRITER MODE setup
set-option window formatcmd '/home/fic/dev/utils/mail-utils/format.py'
set-option window comment_line '>'
try autospell-enable
hook -group mail-auto-format window BufWritePre .* format
hook -once -always window WinSetOption filetype=.* %{
unset-option window formatcmd
remove-hooks window mail-auto-format
}
}
~