On Mon, Jun 16, 2025 at 10:09 AM Eli Zaretskii <eliz@gnu.org> wrote:
> From: Jimmy Yuen Ho Wong <wyuenho@gmail.com>
> Date: Sun, 15 Jun 2025 17:30:47 +0100
> Cc: 78777@debbugs.gnu.org
>
>  I understand what you are saying, but not why you think it's a bug.
>  Once again, the call to after-change-functions in this scenario is
>  done not from insert-file-contents, but from the function that decodes
>  the text read from the file.  That function runs in a temporary
>  buffer, which has no associated file name.
>
> Because the docstring of after-change-functions says the hooks are called with the current buffer, and the
> current buffer at the time insert-file-contents is called, is the file buffer, not the code conversion buffer. The
> message printed out also indicated that the current buffer at the time the after-change-functions lambda is
> called is indeed the file buffer, not the code conversion buffer. The file buffer's buffer-file-name should not
> be set to nil by insert-file-contents or any function it calls. As far as I know, only `insert-file-contents` exhibits
> this undocumented behavior for any functions that change buffer contents.

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. 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?

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.
 

> The guarantee of after-change-functions being called with the current buffer isn't very useful if crucial
> variables of the current buffer such as the buffer file name cannot also be guaranteed to remain the same.
> This use case is illustrated by the tickets I linked to in my original report. There exist many file formatter
> packages that replace the content of the current buffer with a temporary file with the formatted file content
> inside a before-save-hook due to slowness of replace-buffer-content. When these packages are used in
> combination with lsp-mode, which has a function added to after-change-functions that needs access to the
> current buffer's file name in order to synchronize the document between the editor and the language server.

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.

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.