Subject: Re: bug#78777: 30.1; insert-file-contents should not set buffer-file-name to nil

From: Eli Zaretskii <[email-masked]>
Date: Mon, 16 Jun 2025 16:58:43 +0300

> From: Jimmy Yuen Ho Wong <[email-masked]>
> Date: Mon, 16 Jun 2025 13:19:08 +0100
> Cc: [email-masked]
> 
>  OK, I see what happens.  insert-file-contents intentionally binds
>  buffer-file-name temporarily to nil when it is called with REPLACE
>  non-nil, during the deletion or insertion from the code-conversion
>  buffer.  It does that to avoid prompting the user via
>  ask-user-about-supersession-threat, which in this case will confuse.
> 
>  So this is a feature, an intentional behavior.
> 
> This is one silly hack.

Thank you for your kind words.  Any hope of convincing you to use
kinder language?

> If the intention is to suppress some file lock interactive functions, isn't the Emacs
> convention to use some kind of inhibit-* variable? In my case, I don't even use file locks, I've set
> create-lockfiles permanantly to nil, there's no reason that any file lock related functions should be run at all.
> 
> Can userlock--ask-user-about-supersession-threat be modified to check for create-lockfiles and a newly
> introduced inhibit-file-lock internal variable before running userlock--check-content-unchanged? 

ask-user-about-supersession-threat is not about file locks, it's about
discovering that the file was modified outside of this Emacs session
(perhaps by another Emacs session or some other system command).

> This change also seems to have been introduced to before-change-functions are called at the right time,
> perhaps we should ask Stefan what the best thing to do here is.

Perhaps.

>  I suggest that buffer-modification hooks use buffer-file-truename
>  instead, it will provide the correct file name in this (and other)
>  cases.
> 
> This is not ideal. The Language Server Protocol does not specify how to handle symlinks, there is no
> guarantee that file content changes to the source of a symlink will also change the target, which as far as the
> language server is concerned, can very well be just 2 regular files.

An alternative is to go back to using replace-buffer-content.  If its
default operation is (or could be) too slow, you should be able to
avoid that by passing zero for the MAX-SECS argument.

> In addition, the expectation is that unless the user has explicitly changed the buffer-file-name by renaming
> the buffer and/or file, buffer-file-name should remain unmodified at all times from the user's perspective.
> Examining buffer-file-truename should only be used as a crutch to look up the target of a file symlink quickly
> without hitting the disk. Both of the above scenarios are not what's happening here. insert-file-content is
> simply writing to a buffer and after-change-functions are simply reacting to changes in the buffer, not the file
> on disk.

Can you explain what exactly is the problem with buffer-file-name
being nil in the cases where you found that?  If the problem is that a
function placed on the after-change-functions hook doesn't expect
that, it should be easy to amend the function to deal with the
problem, no?  IOW, would it solve the problem if the after-change hook
simply did nothing when buffer-file-name is not a valid file name?  If
not, why not?