[Solved] Proper removal of highlighter when changing filetype


Ok so imagine I have a highlighter set like so:

# C/Cpp/Rust syntax fixes
hook global WinSetOption filetype=(c|cpp|rust|java) %{
    add-highlighter window/functions regex \w+(\h+)?(?=\() 0:function

If I change current window filetype from c to cpp, i’ll get error of duplicate highlighters.

I’ve tried to clean it up by adding a hook (with echoing to debug to see the sequence of commands):

hook global WinSetOption filetype=(c|cpp|rust|java) %{
    echo -debug "setting highlihgters"
    add-highlighter window/functions regex \w+(\h+)?(?=\() 0:function
    echo -debug "defining hook to clean up"
    hook -always -once window WinSetOption filetype=.* %{
        echo -debug "cleaning up"
        remove-highlighter window/functions

If I set the filetype of a window from none to c I’ll see these messages:

setting highlihgters
defining hook to clean up

If after that I’ll set the filetype to cpp, I’ll see this:

setting highlihgters
error running hook WinSetOption(filetype=cpp)/: 5:320: 'add-highlighter' duplicate id: 'functions'
cleaning up

I’ve thought that hook that removes highlighters will be called before it’s parent, but that’s not happening. How should I clear such highlighters on filetype change?


Hehe I’ve got the perfect solution to this. The problem is that the highlighters have the same name regardless of the filetype so it’s highly dependent on hook execution order. The solution is to give them separate names, you can do it by using the value hook_param_capture_n, kinda like that:

hook global WinSetOption filetype=(c|cpp|rust|java) %{
    # in the cpp case, the highlighter name is window/functions_cpp 
    add-highlighter "window/functions_%val{hook_param_capture_1}" regex \w+(\h+)?(?=\() 0:function
    # bake the highlighter name in the cleanup hook
    hook -always -once window WinSetOption filetype=.* "remove-highlighter window/functions_%val{hook_param_capture_1}"

This is also what c-family.kak does to handle changes between C, CPP and ObjC.


Kakoune truly is amazing