Kakoune hook negative selector


is it possible to add negative selector to hook? In mi case I added expanding/unexpanding tabs to spaces to hooks BufOpenFile, BufWritePre and BufWritePost, but I would like these hooks to be disabled when I’m working with Makefile. I tried to came up with regex using negative lookahead but it seems to always match .*(?!Makefile$). Can you help me please?

Thank you

If you cannot find a regex that would do the job, one way out would be to call the shell within your hooks. This is the approach I follow with my hook on WinCreate .*; the hook is called with a regex that matches anything (.*), but I use the shell’s case construct on $kak_opt_filetype within the hook to decide what to do depending on the file just opened.

In your use case, you might use a case construct on $kak_bufname and include an empty branch when the case pattern equals Makefile:

evaluate-commands %sh{
    case "$kak_bufname" in
       Makefile) ;;
       *) printf %s\\n 'set-option buffer indentwidth 4' ;;

for example. Hope you get the idea.


Thank you for your response, after reading it, I tried again and finally solved it, regex is


I was making mistake by buting .* before lookahead.

Thank you again

I was to eager, seems that kakoune can’t handle selector like that

regex parse error: Quantifiers cannot be used in lookarounds at '^(?!.*Makefile)<<<HERE>>>.*$'

Hi ottertino, I tried to get this working myself but failed! Alternatively, as there is a small range of filetypes you could try a per basis hook for your filetypes. From your post I worked this one out, I just keep them in one file and its then just a repeating copy and paste job for new filetypes you encounter.

# hanging whitespace removal hook
hook global BufWritePre '.*.java' %{
  try %{ execute-keys -draft '%s\h+$<ret>d' }

hook global BufWritePre '.*.kt' %{
  try %{ execute-keys -draft '%s\h+$<ret>d' }

Not much help to you, but thanks for your post as it got me sorted so I thought I would share. Let us know if you work it out as my problem is negation of *.md as whitespace matters.

probably your best bet, good of luck with it, bye.

If you’re gonna do it this way, you can use a single hook by using a regex alternation:

hook global BufWritePre '.*\.(java|kt)' %{
  try %{ execute-keys -draft '%s\h+$<ret>d' }

I think the problem is that .* will greedily consume the entire input and the empty string at the end satisfies the negative lookahead. A negative look behind, e.g. .*$(?<!Makefile), does work but has an issue I’m not sure how to solve in that you can’t specify the character before Makefile has to be ^|/ since Kakoune only allows literals in lookbehind|aheads.

You could try switching to hook global BufSetOption filetype=(?!makefile) but keep in mind this will trigger later on in the “pipeline” of hooks.

Thanks SeerLite, I’ll give it a run. Works a treat thanks buddy went with '.*\.(java|kt|kts)$'

Is this possible: naming your hooks with -group and using remove-hooks <scope> <group> in addition to prion’s suggestion.

hook global BufCreate .*(/?[mM]akefile|\.mk|\.make) %{

    remove-hooks <scope> <group>

and you can always copy out the rc/filetype/makefile.kak and break it till you make it.

It’s a 1am idea, so untried and untested.

What thas it mean that later on in the pipeline?

Thank you, but this will be useless since I work with quite range of programming languages (I like to explore source code of tools I’m using) and most of them I open once in a while so I need good default behaviour, I can’t spend time on configuring kakoune for every new file type I open

Just that the filetype option is typically set in a BufCreate or BufOpenFile hook so a BufSetOption hook should trigger later than the current one. Probably not relevant but thought I should mention it.

Oh, ok, thank you

Intersting, I will test it tommorow