You need to either set the default value of the variable, if you want it for every file:
(setq-default require-final-newline t)
;; or ...
(customize-set-variable 'require-final-newline t)
or to set it in the mode hook, if you only want it for files of that mode:
(add-hook 'some-mode-hook (lambda () (setq-local require-final-newline t)))
The reason that a bare (setq require-final-newline t)
does not work is that require-final-newline
is buffer-local in certain cases. A number of modes (most prominently prog-mode
and text-mode
) do this:
(setq-local require-final-newline mode-require-final-newline)
That also affects their derived modes (e.g. emacs-lisp-mode
in the first case and org-mode
in the second). So in those modes, require-final-newline
is indeed buffer-local.
I don't know exactly how the loading and evaluation of the init file happens, but if it happens in such a buffer (e.g. in an emacs-lisp-mode
buffer), require-final-newline
is indeed a buffer-local, so the setq
does not change the global default and your (future) buffer does not see the changed value. I suspect (but I don't know for sure) that this is the underlying cause of the failure of the bare setq
in your init file and why you need setq-default
.
EDIT: In answer to your question in the comment, I don't think there is a way to ask whether the variable is buffer-local in any buffer that exists in the current session, except by checking every buffer.
The problem is that any variable can be made buffer-local in a particular buffer, and nobody would know about that except that particular buffer: if you try tosetq
from that buffer, you would only change the local value. So if you ask about the variable anywhere except in that buffer, it would say "not local". There are two functions local-variable-p
and local-variable-is-set-p
that do this kind of asking and they both say nil
for a buffer in e.g. fundamental-mode
for the variable require-final-newline
. You can check for local-ness in other buffers so you could write something like this to check every buffer:
(defun is-local (sym)
(catch 'found
(dolist (buf (buffer-list))
(when (local-variable-p sym buf)
(throw 'found t)))
nil))
If you evaluate (is-local 'require-final-newline)
in any buffer, it says t
, because it is local in the *scratch*
buffer e.g.
But even this is not completely reliable: if during initialization a buffer is created and makes require-final-newline
buffer-local but then gets deleted, the loop above will not find it afterwards. If there is no other buffer with a buffer-local require-final-newline
, the function says nil
. You can check that by setting initial-major-mode
to fundamental
, in a small init file that also contains the function above and the setq
of require-final-newline
, and invoking emacs with emacs -Q -l /path/to/minimal.init.el
. The *scratch* buffer is now in fundamental mode and no other existing buffer (minibuffer, the
Messages buffer etc) makes the variable buffer-local, so the function happily says nil
- but the setq
still does not work. To me, that indicates that the scenario I've been describing here is correct (but I can easily imagine being Horatio to someone's Hamlet :-) ).
require-final-newline
that hints variable is buffer local @jue : replace q.uestions in NickD's link