Why dose Kakoune try to trim whitespace for empty line?

This feature has been bothering me for a while, whenever I start a new line, type a few indent spaces, then go into normal mode, at this time Kakoune deletes all the whitespace, then I paste something, I need to re-indent every time, I checked the source code, found that most languages have this default behavior, I want to ask what is the intention of this design? To me it’s counter-intuitive. I know I can avoid this by type \i, but this also disable other hooks that I wanted, like <tab> hooks.

I also searched another related question about this:

you can disable specific hooks, e.g.

rmhooks window java-trim-indent

Although I’d instead recommend preventing the behavior from happening at undesirable times by using < and > to indent from normal mode or <c-r>" to paste from insert mode.

@prion Thanks, but I still want to know the purpose of this hook. is it inherited from vim?

and it seems there is no -group xxx for this hook, can I really remove it by rmhooks window java-trim-indent?

When tracking changes to source-code, it’s common to have issues with trailing whitespace characters on a line. Because they’re (usually) invisible, they can be added and removed quite by accident and without affecting how the software works, but source-control tools like Git and Subversion will dutifully record and highlight each change, adding noise and distraction any time somebody’s trying to find out when and why a particular change was made.

As a result, software developers tend to be pretty aggressive about removing trailing whitespace. It would be easy enough to automatically strip trailing whitespace from every line in the buffer when it’s written to disk, but if trailing whitespace does creep in somehow, automatically removing it causes exactly the kind of diff noise we’re trying to avoid.

As a result, most editors will automatically strip trailing whitespace from lines the user changes, and leave the rest of the file alone. In Kakoune, this happens to be implemented as a hook that triggers when leaving insert mode.

Actually, there is, it’s just constructed in a weird way:

hook window ModeChange pop:insert:.* -group "%val{hook_param_capture_1}-trim-indent" javascript-trim-indent

The group-name for this hook is %val{hook_param_capture_1}-trim-indent, but because it’s in double-quotes, the %val{} expansion will be replaced. hook_param_capture_1 is not listed in :doc expansions, but hook_param is the string that the hook’s regex argument matched, and regexes have “capture groups” that are traditionally numbered. This hook’s regex argument is filetype=(javascript|typescript) so I expect that %val{hook_param_capture_1} expands to either javascript or typescript depending on what kind of file this is.

Although you can de-fang a hook with rmhooks, it’s more effective to set the disabled_hooks option to a regex that matches the names of the hooks you want to disable. That way, you don’t have to worry that your rmhooks was run before the hooks were installed, just set the option in your kakrc and those hooks are always disabled.


Thanks for the detailed explanations!

I think I need to remove these hooks cause it’s common for me to paste something after I insert some indent. And I think it’s better if there is a warning like empty line with spaces is better than deleting these spaces.

Thanks for the explanation for -group!