Kakoune comes with a spell-checking script (spell.kak
) but as is convention, it just defines a few commands and leaves the user to figure out how to incorporate them. It occurs to me that what I really want is:
- declare a custom spell-checking mode
- add spell-checking-related mappings in that mode
- execute
:spell<ret>
on entering that mode - execute
:spell-clear<ret>
on exiting that mode
The first two items in the list are easy enough:
declare-user-mode spell
map global spell n ': spell-next' -docstring "next misspelling"
For the last two items, though, Iâm a bit stuck. I clearly canât use the InsertBegin
/InsertEnd
/NormalBegin
/NormalEnd
hooks, because they know nothing about my custom mode. The ModeChange
hook is much more general, though, so I added:
hook global ModeChange .*:spell %{ spell }
hook global ModeChange spell:.* %{ spell-clear }
⌠and nothing happened. I got curious, so I added a new hook:
hook global ModeChange .* %{ echo -debug ModeChange %val{hook_param} }
⌠and started playing around. When I hit , to display the list of user modes, my debug log says:
ModeChange normal:next-key
⌠and when I type a mapping to enter a user-mode, it says:
ModeChange next-key:normal
ModeChange normal:prompt
ModeChange prompt:normal
ModeChange normal:next-key
In a way, that makes sense: the mapping is a normal-mode command, so Kakoune leaves the ânext-keyâ mode and goes back to normal mode. The normal-mode command is : to open the prompt, it types an enter-user-mode
command, and then weâre back in next-key
mode again. But clearly trying to hook our user-mode by name is not going to work if Kakoune is only ever in next-key
mode.
I guess strictly speaking we donât need a special hook to run commands when entering a mode:
define-command enter-spell-mode %{
spell
enter-user-mode -lock spell
}
map global user s ': enter-spell-mode<ret>' -docstring spellcheck
⌠but the user can leave spell mode at any time with Esc, which I canât write a mapping for (a good thing).
Alternatively, when entering the mode I could write a one-shot hook for ModeChange next-key:normal
, except that Kakoune naturally fires that hook while executing commands within the mode, not just when exiting it.
But of course, thatâs what the proposed ModePush and ModePop hooks are for, right? Surely that will let me distinguish âtemporarily entering normal mode to run a commandâ from âpermanently returning to normal modeâ. As it turns out, no:
ModePush normal:next-key:2 # I hit , to enter the user-mode list
ModePop next-key:normal:2 # I hit s to trigger the "enter spell mode" mapping
ModePush normal:prompt:2 # the mapping runs in normal mode
ModePop prompt:normal:2
ModePush normal:next-key:2 # Kakoune actually enters spell mode
ModePop next-key:normal:2
It seems that âenteringâ a custom mode is not like entering normal mode from insert mode, it doesnât add new stack modes, it just shuffles modes around at the same depth.
Is there some clever way I can get the ârun commands on entering and exiting a user-modeâ that I want, or should I start filing issues?