1

Emacs keeps on asking me

Buffer text.txt does not end in newline.  And one? (y or n)

I am confused about why I cannot stop Emacs from making this inquiry. I've set both

require-final-newline
mode-require-final-newline

to nil in a hook to tex-mode.

I've verified that it's value is indeed nil when I'm working in my file. But nevertheless, Emacs continues to make the inquiry.

I've looked at the code for basic-save-buffer. The relevant part of the code is:

       (or (eq require-final-newline t)
           (eq require-final-newline 'visit-save)
           (and require-final-newline
            (y-or-n-p
             (format "Buffer %s does not end in newline.  Add one? "
                 (buffer-name)))))

It seems that Emacs should never get to the y-or-n-p since it appears as the second part of an and test where the first part evaluates to nil.

What's going on here?

My Emacs is GNU 27.2.

I've played a bit rewriting this code. As an example,

       (or (eq require-final-newline t)
           (eq require-final-newline 'visit-save)
           (and nil
            (y-or-n-p
             (format "Buffer %s does not end in newline.  Add one? "
                 (buffer-name)))))

Behaves as I would expect.

I've also tried something like:

       (or (eq require-final-newline t)
           (eq require-final-newline 'visit-save)
           (and require-final-newline
                        (progn
                          (message (concat "[2] require-final-newline: " (format "%S" require-final-newline)))
                          (sit-for 1)
                          t)
            (y-or-n-p
             (format "Buffer %s does not end in newline.  Add one? "
                 (buffer-name)))))

And the message reports that require-final-newline is nil but the only way to get to the message is for it to be t.

What's going on?

UPDATE

I am able to go in and customize the variable. And when I do that and set it to Don't add newlines, the annoying question goes away. But, I'm not happy with this. That seems to set this value globally regardless of the mode I'm in. That's not what I want. It's just for specific files and when in tex-mode that I want this to apply.

Further update:

@phils 's questions have been very useful, actually, for me to begin to debug what's going on here.

I think I've located the problem. I'm still interested how to solve it.

I'm using a .dir-locals.el to set a number of parameters for the local files I'm working on. If I remove the .dir-locals.el file and set things via hooks (as I formerly believed I was doing), everything behaves properly.

However, if I use the .dir-locals.el file set parameters, then things stop working properly. In the .dir-locals.el file I have the following line:

(nil . ((require-final-newline nil)))

This seems to be the problem. What's happening is that instead of require-final-newline getting set to nil it is getting set to (nil).

I can stick with the use of a hook to accomplish what I want. But, now I'm curious. Am I getting the syntax for .dir-locals.el wrong. Here's my full .dir-locals.el file

(
 (nil . ((fill-column . 70)))
 (nil . ((mode .tex)))
 (nil . ((require-final-newline nil)))
)
A.Ellett
  • 331
  • 2
  • 10
  • Why `tex-mode` ?? – phils Feb 15 '22 at 04:47
  • @phils I don't understand the question. It's the mode I use to write to many of my files. – A.Ellett Feb 15 '22 at 05:40
  • You've associated `.txt` filenames like "text.txt" with `tex-mode` rather than the normal `text-mode`?? `tex-mode` is for TeX and LaTeX. – phils Feb 15 '22 at 06:23
  • @phils I'm aware of that. There are feature of `tex-mode` I find useful which don't exist in `text-mode`. What does that have to do with my question? – A.Ellett Feb 15 '22 at 13:49
  • 1
    I asked because you'd added a hook to `tex-mode` and were confused that it wasn't working for a `text.txt` file, and by default that would be expected. It looked like *that* might have been your problem. – phils Feb 15 '22 at 19:59
  • @phils Thank you for explaining your point. I understand now. Without going into the nuts-and-bolts of why I occasionally use `tex-mode` for `txt` files, I've set up a `.dir-locals.el` file to invoke `tex-mode` for this particular `.txt` file (and others that share this directory). – A.Ellett Feb 15 '22 at 20:04
  • @phils I am truly grateful to you for you questions. I didn't understand what you were after, but you did get me looking closer at things I had not considered being the culprit. I've now figured out the error. Everything works as it should now. – A.Ellett Feb 15 '22 at 20:28

1 Answers1

2

The problem I encountered is due to a syntax error in my .dir-locals.el file.

I have a line in that file which reads

(nil . ((require-final-newline nil)))

that is wrong. It sets require-final-newline to (nil), not nil.

If I correct the syntax to

(nil . ((require-final-newline . nil)))

everything works as desired and as expected.

A.Ellett
  • 331
  • 2
  • 10
  • You probably know, but see `C-h i g (elisp)Dotted Pair Notation` if you're not sure why that value ended up as `(nil)` before. – phils Feb 15 '22 at 20:59
  • And these days (since Emacs 27.1) `M-x add-dir-local-variable` generates dotted notation for the (var . value) pairs, so you can use that to update the file without it ending up hard to read. It'll get confused by your file having multiple `nil` keys, though, so make sure you fix that. – phils Feb 15 '22 at 21:06
  • @phils Thank you for the heads up and the references. I hadn't known (obviously) about the error of using multiple `nil`. I don't remember when I started using `.dir-locals.el`. But it was a very long time ago when I knew only a small fraction of what I do now. I'll have to research `.dir-locals.el` syntax some more. I'm sure I've got other quacky things going on. – A.Ellett Feb 15 '22 at 21:13
  • Note that the correct structure is `((nil . ((fill-column . 70) (mode . tex) (require-final-newline . nil))))`. As well as the multiple `nil` keys you had another typo in `(mode .tex)` instead of `(mode . tex)` -- the former considers the dot to be part of the mode symbol, rather than as a dotted pair separator, so that value was the list `(\.tex)` – phils Feb 15 '22 at 21:14