Automatically delete the trailing whitespace on save in emacs while excluding the trailing newlines

I use emacs as my editor and have it configured to delete all trailing whitespace in a file, including any trailing newlines at the end, before saving it. The configuration snippet that I have in my emacs configuration file to do this is

(add-hook 'before-save-hook 'delete-trailing-whitespace)

While this is very convenient and works as expected, it becomes a hindrance in specific cases – the Jinja2 templating language deletes a single trailing newline, thereby leaving the rendered templates without a newline at the end.

One way to work around this behaviour is to add 2 trailing newlines in the jinja2 template files. But unfortunately, due to my emacs configuration that deletes all trailing whitespace, this doesn’t work. So I started reading the documentation for the delete-trailing-whitespace function and found out about the delete-trailing-newlines variable (default: t). This variable controls whether the trailing newline characters at the end of a file are deleted or not. So I wanted to try overriding the delete-trailing-newlines variable to be false in jinja2-mode, that I use for editing Jinja2 templates.

With some help from the excellent folks in the #emacs IRC channel on Libera Chat, I was able to come up with the following configuration, that works as expected.

(use-package jinja2-mode                                                                     
  :pin nongnu                                                                                
  (jinja2-mode . (lambda ()                                                                  
                   (setq-local delete-trailing-lines nil)))                                  
  :mode "\\.j2\\'")

Note that I use the excellent use-package macro to install the jinja2-mode and configure it appropriately. If you don’t use use-package, this can be done using the add-hook function.

Leave a Reply

Your email address will not be published. Required fields are marked *