unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
@ 2020-01-19 11:14 Felician Nemeth
  2020-01-20 22:56 ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Felician Nemeth @ 2020-01-19 11:14 UTC (permalink / raw)
  To: 39190

If I read correctly, diff-syntax-fontify-props sets buffer-file-name of
a temporary buffer to an existing one.  This is not necessarily a bug,
but it definitely looks strange that we have two buffers with different
contents and the same buffer-file-name.

Eglot (in ELPA) runs into problems because of this
(https://github.com/joaotavora/eglot/pull/233).

Is there a recommended way to check in an after-change-major-mode-hook
whether the current buffer is or isn't a temporary diff buffer?  For
example, to check if first character of buffer-name is space.

Thank you.

In GNU Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.5, cairo version 1.16.0)
 of 2020-01-19 built on betli
Repository revision: 35a1a007bb7506c72ee6d9757a79014c679e7bae
Repository branch: emacs-27
Windowing system distributor 'The X.Org Foundation', version 11.0.12004000
System Description: Debian GNU/Linux 10 (buster)






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-19 11:14 bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props) Felician Nemeth
@ 2020-01-20 22:56 ` Juri Linkov
  2020-01-20 23:34   ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-01-20 22:56 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 39190, stefan monnier

X-Debbugs-CC: Stefan Monnier <monnier@iro.umontreal.ca>

Stefan, do you think diff-syntax-fontify-props should let-bind
after-change-major-mode-hook to nil to not allow running this hook
on an internal buffer.  Or it's the responsibility of the eglot package
to check for the leading space in the buffer name when its
after-change-major-mode-hook is called?

> If I read correctly, diff-syntax-fontify-props sets buffer-file-name of
> a temporary buffer to an existing one.  This is not necessarily a bug,
> but it definitely looks strange that we have two buffers with different
> contents and the same buffer-file-name.
>
> Eglot (in ELPA) runs into problems because of this
> (https://github.com/joaotavora/eglot/pull/233).
>
> Is there a recommended way to check in an after-change-major-mode-hook
> whether the current buffer is or isn't a temporary diff buffer?  For
> example, to check if first character of buffer-name is space.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-20 22:56 ` Juri Linkov
@ 2020-01-20 23:34   ` Stefan Monnier
  2020-01-24  0:13     ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-01-20 23:34 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> Stefan, do you think diff-syntax-fontify-props should let-bind
> after-change-major-mode-hook to nil to not allow running this hook
> on an internal buffer.

No, that's definitely not the right fix.  It's at best a weak
workaround, but it won't handle the case where the code that depends on
`buffer-file-name` is placed on `foo-mode-hook` rather than on
`after-change-major-mode-hook`.

>> If I read correctly, diff-syntax-fontify-props sets buffer-file-name of
>> a temporary buffer to an existing one.  This is not necessarily a bug,
>> but it definitely looks strange that we have two buffers with different
>> contents and the same buffer-file-name.

Yes, it's definitely borderline.  I remember feeling a bit uneasy about
it at the time.  Maybe a better fix would be to be able to pass the
file-name to `set-auto-mode` (or some new function created for that
purpose) as an argument (instead of passing it via dynamic scoping in
`buffer-file-name`).

BTW, I see somewhat similar code in `xref--collect-matches`, so maybe
there's a need for a more general solution (haven't looked any further,
but I'd be surprised if there aren't other cases).

> Or it's the responsibility of the eglot package to check for the
> leading space in the buffer name when its after-change-major-mode-hook
> is called?

The eglot package could protect itself from such things by making its
`after-change-major-mode-hook` just add the buffer to a global var, and
then process this global var in `post-command-hook` or in a timer.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-20 23:34   ` Stefan Monnier
@ 2020-01-24  0:13     ` Juri Linkov
  2020-01-24 14:18       ` Stefan Monnier
  2020-01-26 19:34       ` Felician Nemeth
  0 siblings, 2 replies; 52+ messages in thread
From: Juri Linkov @ 2020-01-24  0:13 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

Now I tried to repeat this problem with eglot and got such backtrace:

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  substring(nil 0 1)
  file-truename(nil)
  eglot--path-to-uri(nil)
  eglot--TextDocumentIdentifier()
  eglot--signal-textDocument/didClose()
  kill-buffer(#<buffer  *temp*-492063>)
  (and (buffer-name temp-buffer) (kill-buffer temp-buffer))
  (unwind-protect (progn (insert text) (diff-syntax-fontify-props ...
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (insert text) (diff-syntax-fontify-props ...
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (insert text) ...
  (cond ((and file diff-default-directory ...) ...) ...)
  (let ((file (car (diff-hunk-file-names old)))) ...)
  (or (if (and diff-vc-backend (not (eq diff-font-lock-syntax 'hunk-only))) ...) ...)
  (let* ((hunk (buffer-substring-no-properties beg end)) ...) ...
  diff-syntax-fontify-hunk(10530 14909 t)
  diff-syntax-fontify(10530 14909)
  #f(compiled-function (beg end) #<bytecode 0x1cb64d70b7d4e0e5>)(10530 14909)
  diff--iterate-hunks(12505 #f(compiled-function (beg end) #<bytecode 0x1cb64d70b7d4e0e5>))
  diff--font-lock-syntax(12505)
  font-lock-fontify-keywords-region(11965 12505 nil)
  font-lock-default-fontify-region(11980 12480 nil)
  font-lock-fontify-region(11980 12480)
  #f(compiled-function (fun) #<bytecode 0x303b13b2afd8864>)(font-lock-fontify-region)
  run-hook-wrapped(#f(compiled-function (fun) #<bytecode 0x303b13b2afd8864>) font-lock-fontify-region)
  jit-lock--run-functions(11980 12480)
  jit-lock-fontify-now(11980 12480)
  jit-lock-function(11980)
  redisplay_internal\ \(C\ function\)()

>> Stefan, do you think diff-syntax-fontify-props should let-bind
>> after-change-major-mode-hook to nil to not allow running this hook
>> on an internal buffer.
>
> No, that's definitely not the right fix.  It's at best a weak
> workaround, but it won't handle the case where the code that depends on
> `buffer-file-name` is placed on `foo-mode-hook` rather than on
> `after-change-major-mode-hook`.

In fact, eglot recommends adding such hooks:

  (add-hook 'foo-mode-hook 'eglot-ensure)

where eglot-ensure relies on buffer-file-name, so such fix is not possible indeed.

>>> If I read correctly, diff-syntax-fontify-props sets buffer-file-name of
>>> a temporary buffer to an existing one.  This is not necessarily a bug,
>>> but it definitely looks strange that we have two buffers with different
>>> contents and the same buffer-file-name.
>
> Yes, it's definitely borderline.  I remember feeling a bit uneasy about
> it at the time.  Maybe a better fix would be to be able to pass the
> file-name to `set-auto-mode` (or some new function created for that
> purpose) as an argument (instead of passing it via dynamic scoping in
> `buffer-file-name`).

The problem is that the right value of buffer-file-name is required
also by other more deep functions that set local variables like
dir-locals-collect-variables.

> BTW, I see somewhat similar code in `xref--collect-matches`, so maybe
> there's a need for a more general solution (haven't looked any further,
> but I'd be surprised if there aren't other cases).

Another example is mm-display-inline-fontify in gnus/mm-view.el,
so the problem is more widespread, and perhaps not much could be done
more than already using temporary buffers as an indication
for external packages that these buffers are for internal use only.

>> Or it's the responsibility of the eglot package to check for the
>> leading space in the buffer name when its after-change-major-mode-hook
>> is called?
>
> The eglot package could protect itself from such things by making its
> `after-change-major-mode-hook` just add the buffer to a global var, and
> then process this global var in `post-command-hook` or in a timer.

Felician, do you think that the eglot package should take more care
to protect itself, so this report could be closed?





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-24  0:13     ` Juri Linkov
@ 2020-01-24 14:18       ` Stefan Monnier
  2020-01-28  0:01         ` Juri Linkov
  2020-01-26 19:34       ` Felician Nemeth
  1 sibling, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-01-24 14:18 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

>> Yes, it's definitely borderline.  I remember feeling a bit uneasy about
>> it at the time.  Maybe a better fix would be to be able to pass the
>> file-name to `set-auto-mode` (or some new function created for that
>> purpose) as an argument (instead of passing it via dynamic scoping in
>> `buffer-file-name`).
>
> The problem is that the right value of buffer-file-name is required
> also by other more deep functions that set local variables like
> dir-locals-collect-variables.

Passing it down as an arg is indeed problematic.
Maybe we should just add yet-another buffer-<foo>-filename and change
the corresponding places to so that instead of consulting

    buffer-file-name

they consult

    (or buffer-file-name buffer-<foo>-filename)

Maybe this could also be used for things like `vc-revision-other-window`.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-24  0:13     ` Juri Linkov
  2020-01-24 14:18       ` Stefan Monnier
@ 2020-01-26 19:34       ` Felician Nemeth
  2020-01-28  0:05         ` Juri Linkov
  1 sibling, 1 reply; 52+ messages in thread
From: Felician Nemeth @ 2020-01-26 19:34 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Stefan Monnier

> Now I tried to repeat this problem with eglot and got such backtrace:
[...]

Did you use the ELPA version or the git master?

> Felician, do you think that the eglot package should take more care
> to protect itself, so this report could be closed?

Having read your discussion I have a feeling that this issue affects
more than just Eglot.  Nevertheless we plan a feature that postpones the
activation of Eglot and this feature is somewhat similar to Stefan's
first suggestion.  So if the only concern is Eglot, then this issue can
be closed.

I haven't completely understood Stefan's second suggestion of
buffer-<foo>-filename, but if this means temporary diff buffers can be
detected similarly how save-some-buffers detects indirect buffers with
buffer-base-buffer, then I support the idea.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-24 14:18       ` Stefan Monnier
@ 2020-01-28  0:01         ` Juri Linkov
  2020-01-28  1:30           ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-01-28  0:01 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

[-- Attachment #1: Type: text/plain, Size: 441 bytes --]

> Passing it down as an arg is indeed problematic.
> Maybe we should just add yet-another buffer-<foo>-filename and change
> the corresponding places to so that instead of consulting
>
>     buffer-file-name
>
> they consult
>
>     (or buffer-file-name buffer-<foo>-filename)
>
> Maybe this could also be used for things like `vc-revision-other-window`.

This requires more testing, but at least such patch
basically would look like this:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: buffer-file-name-for-mode.patch --]
[-- Type: text/x-diff, Size: 3838 bytes --]

diff --git a/lisp/files.el b/lisp/files.el
index 683f4a8ce7..e2721f43fc 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3080,6 +3080,8 @@ magic-mode-regexp-match-limit
   "Upper limit on `magic-mode-alist' regexp matches.
 Also applies to `magic-fallback-mode-alist'.")
 
+(defvar-local buffer-file-name-for-mode nil)
+
 (defun set-auto-mode (&optional keep-mode-if-same)
   "Select major mode appropriate for current buffer.
 
@@ -3197,11 +3199,10 @@ set-auto-mode
 	  (set-auto-mode-0 done keep-mode-if-same)))
     ;; Next compare the filename against the entries in auto-mode-alist.
     (unless done
-      (if buffer-file-name
-	  (let ((name buffer-file-name)
-		(remote-id (file-remote-p buffer-file-name))
-		(case-insensitive-p (file-name-case-insensitive-p
-				     buffer-file-name)))
+      (if (or buffer-file-name buffer-file-name-for-mode)
+	  (let* ((name (or buffer-file-name buffer-file-name-for-mode))
+		 (remote-id (file-remote-p name))
+		 (case-insensitive-p (file-name-case-insensitive-p name)))
 	    ;; Remove backup-suffixes from file name.
 	    (setq name (file-name-sans-versions name))
 	    ;; Remove remote file name identification.
@@ -3459,6 +3460,8 @@ hack-local-variables-confirm
     (let ((name (cond (dir-name)
 		      (buffer-file-name
 		       (file-name-nondirectory buffer-file-name))
+		      (buffer-file-name-for-mode
+		       (file-name-nondirectory buffer-file-name-for-mode))
 		      ((concat "buffer " (buffer-name)))))
 	  (offer-save (and (eq enable-local-variables t)
 			   unsafe-vars))
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el
index a6be04e313..0c2b985956 100644
--- a/lisp/gnus/mm-view.el
+++ b/lisp/gnus/mm-view.el
@@ -482,7 +482,7 @@ mm-display-inline-fontify
         ;; aren't a problem any more.  So we could probably get rid of this
         ;; setting now, but it seems harmless and potentially still useful.
 	(set (make-local-variable 'font-lock-mode-hook) nil)
-        (setq buffer-file-name (mm-handle-filename handle))
+        (setq buffer-file-name-for-mode (mm-handle-filename handle))
 	(with-demoted-errors
 	    (if mode
                 (save-window-excursion
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 1a34456340..4290eeb66a 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1391,7 +1391,7 @@ xref--collect-matches
           (insert-file-contents file nil 0 200)
           ;; Can't (setq-local delay-mode-hooks t) because of
           ;; bug#23272, but the performance penalty seems minimal.
-          (let ((buffer-file-name file)
+          (let ((buffer-file-name-for-mode file)
                 (inhibit-message t)
                 message-log-max)
             (ignore-errors
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 2dbab80208..cff0a5a103 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2718,7 +2718,7 @@ diff-syntax-fontify-props
     ;; temp buffer.
     (cl-assert (null buffer-file-name))
     (let ((enable-local-variables :safe) ;; to find `mode:'
-          (buffer-file-name file))
+          (buffer-file-name-for-mode file))
       (set-auto-mode)
       ;; FIXME: Is this really worth the trouble?
       (when (and (fboundp 'generic-mode-find-file-hook)
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index f64b6c0631..79f49ab68b 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -2097,7 +2099,7 @@ vc-find-revision-no-save
                 (if buffer
                     ;; For non-interactive, skip any questions
                     (let ((enable-local-variables :safe) ;; to find `mode:'
-                          (buffer-file-name file))
+                          (buffer-file-name-for-mode file))
                       (ignore-errors (set-auto-mode)))
                   (normal-mode))
 	        (set-buffer-modified-p nil)

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-26 19:34       ` Felician Nemeth
@ 2020-01-28  0:05         ` Juri Linkov
  2020-01-28 17:18           ` Felician Nemeth
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-01-28  0:05 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 39190, Stefan Monnier

>> Now I tried to repeat this problem with eglot and got such backtrace:
> [...]
>
> Did you use the ELPA version or the git master?

The backtrace was from the ELPA version, but trying it
in the git master signals a different error:

Error in post-command-hook:
(error "[eglot] Can't guess mode to manage for ` *diff-syntax:...

> Having read your discussion I have a feeling that this issue affects
> more than just Eglot.  Nevertheless we plan a feature that postpones the
> activation of Eglot and this feature is somewhat similar to Stefan's
> first suggestion.  So if the only concern is Eglot, then this issue can
> be closed.

Since it will take much time when the fix in Emacs will appear in a released
version, a workaround needs to be added to Eglot immediately.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28  0:01         ` Juri Linkov
@ 2020-01-28  1:30           ` Stefan Monnier
  2020-01-28  3:32             ` Eli Zaretskii
  2020-01-30 22:50             ` Juri Linkov
  0 siblings, 2 replies; 52+ messages in thread
From: Stefan Monnier @ 2020-01-28  1:30 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> This requires more testing, but at least such patch
> basically would look like this:

This looks pretty good to me.  I wonder what Eli thinks about it.

> +(defvar-local buffer-file-name-for-mode nil)

Clearly we'd need a docstring here.

> +      (if (or buffer-file-name buffer-file-name-for-mode)

And now that I think about it, maybe

    (or buffer-file-name-for-mode buffer-file-name)

would be preferable (in case we want to set the major mode of a file
buffer based o a different file name).


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28  1:30           ` Stefan Monnier
@ 2020-01-28  3:32             ` Eli Zaretskii
  2020-01-28 13:58               ` Stefan Monnier
  2020-01-30 22:50             ` Juri Linkov
  1 sibling, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2020-01-28  3:32 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, felician.nemeth, juri

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Mon, 27 Jan 2020 20:30:31 -0500
> Cc: 39190@debbugs.gnu.org, Felician Nemeth <felician.nemeth@gmail.com>
> 
> > This requires more testing, but at least such patch
> > basically would look like this:
> 
> This looks pretty good to me.  I wonder what Eli thinks about it.

I wasn't following this thread closely, so I don't have a clear idea
what problems does this change try to solve.  Could you humor me with
a summary, please?  Why isn't buffer-file-name enough?





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28  3:32             ` Eli Zaretskii
@ 2020-01-28 13:58               ` Stefan Monnier
  2020-01-28 14:54                 ` Dmitry Gutov
  2020-01-28 17:54                 ` Eli Zaretskii
  0 siblings, 2 replies; 52+ messages in thread
From: Stefan Monnier @ 2020-01-28 13:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 39190, felician.nemeth, juri

> I wasn't following this thread closely, so I don't have a clear idea
> what problems does this change try to solve.  Could you humor me with
> a summary, please?  Why isn't buffer-file-name enough?

Some packages set `buffer-file-name` in temp-buffers in order to
activate the major mode of the corresponding file.  As you can see in
the patch it's used in various circumstances.

Most of the time this is harmless because it's transient, but it is
fundamentally a lie (it more or less claims that this temp buffer holds
the content of that file, even though it's not the case (not only
because the content doesn't match, but the buffer is usually not fully
set up as a proper file buffer, it can lead to get-file-buffer returning
the wrong buffer, ...) and even though it's transient it can cause
problems because hooks are run during this time (e.g. major mode hooks)
which may take action under the mistaken assumption that this buffer
really correspond to the file.

In the original bug report the problem was that the major mode activated
`eglot-mode` in this temp buffer.  There are many ways for this to
create problems.  The immediate error can be avoided in eglot of course,
but I think the problem goes deeper and we should fix it by making it
possible to set the major mode without having to lie about
`buffer-file-name`.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 13:58               ` Stefan Monnier
@ 2020-01-28 14:54                 ` Dmitry Gutov
  2020-01-28 22:53                   ` Juri Linkov
  2020-01-28 17:54                 ` Eli Zaretskii
  1 sibling, 1 reply; 52+ messages in thread
From: Dmitry Gutov @ 2020-01-28 14:54 UTC (permalink / raw)
  To: Stefan Monnier, Eli Zaretskii; +Cc: 39190, felician.nemeth, juri

On 28.01.2020 16:58, Stefan Monnier wrote:
> it can cause
> problems because hooks are run during this time (e.g. major mode hooks)
> which may take action under the mistaken assumption that this buffer
> really correspond to the file

I think diff-mode could also use delay-mode-hooks and then run them (or 
not) outside of that let binding.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28  0:05         ` Juri Linkov
@ 2020-01-28 17:18           ` Felician Nemeth
  2020-01-29 23:07             ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Felician Nemeth @ 2020-01-28 17:18 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Stefan Monnier

>>> Now I tried to repeat this problem with eglot and got such backtrace:
>> [...]
>>
>> Did you use the ELPA version or the git master?
>
> The backtrace was from the ELPA version, but trying it
> in the git master signals a different error:
>
> Error in post-command-hook:
> (error "[eglot] Can't guess mode to manage for ` *diff-syntax:...

That's strange.  I was able to reproduce the original bug report
following this recipe:
https://github.com/joaotavora/eglot/pull/233#issuecomment-466691992
I wonder if your setup is different is some way.

>> Having read your discussion I have a feeling that this issue affects
>> more than just Eglot.  Nevertheless we plan a feature that postpones the
>> activation of Eglot and this feature is somewhat similar to Stefan's
>> first suggestion.  So if the only concern is Eglot, then this issue can
>> be closed.
>
> Since it will take much time when the fix in Emacs will appear in a released
> version, a workaround needs to be added to Eglot immediately.

OK, but this feature ("Better syntax highlighting of Diff hunks") will
first appear in Emacs 27.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 13:58               ` Stefan Monnier
  2020-01-28 14:54                 ` Dmitry Gutov
@ 2020-01-28 17:54                 ` Eli Zaretskii
  2020-01-28 20:12                   ` Stefan Monnier
  1 sibling, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2020-01-28 17:54 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, felician.nemeth, juri

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: juri@linkov.net,  39190@debbugs.gnu.org,  felician.nemeth@gmail.com
> Date: Tue, 28 Jan 2020 08:58:32 -0500
> 
> Some packages set `buffer-file-name` in temp-buffers in order to
> activate the major mode of the corresponding file.  As you can see in
> the patch it's used in various circumstances.
> 
> Most of the time this is harmless because it's transient, but it is
> fundamentally a lie (it more or less claims that this temp buffer holds
> the content of that file, even though it's not the case (not only
> because the content doesn't match, but the buffer is usually not fully
> set up as a proper file buffer, it can lead to get-file-buffer returning
> the wrong buffer, ...) and even though it's transient it can cause
> problems because hooks are run during this time (e.g. major mode hooks)
> which may take action under the mistaken assumption that this buffer
> really correspond to the file.
> 
> In the original bug report the problem was that the major mode activated
> `eglot-mode` in this temp buffer.  There are many ways for this to
> create problems.  The immediate error can be avoided in eglot of course,
> but I think the problem goes deeper and we should fix it by making it
> possible to set the major mode without having to lie about
> `buffer-file-name`.

Thanks.

So this is because those modes set buffer-file-name instead of
activating the major mode directly?  And by setting buffer-file-name
they by side effect tell unrelated features that this buffer is
associated with a file?

If so, then I'm not sure I understand the solution.  The offending
modes will have to be modified to use this new variable instead of
buffer-file-name, no?  And if we have to modify them, then why not do
TRT while at that, i.e. call the major mode directly instead of
setting some variable?  Or what am I missing?





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 17:54                 ` Eli Zaretskii
@ 2020-01-28 20:12                   ` Stefan Monnier
  2020-01-28 20:23                     ` Eli Zaretskii
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-01-28 20:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 39190, felician.nemeth, juri

> So this is because those modes

They're not "modes", really, they're features that create a temp buffer
related to file FOO and need to set this buffer to the same mode as file FOO
(e.g. this happens in vc-revision-other-window, or also in diff-mode
where we grab a hunk's text and want to put it in its corresponding
major mode to give it mode-specific highlighting).

> set buffer-file-name instead of activating the major mode directly?

Right: they don't know which major mode should be used, so they set
buffer-file-name and then call set-auto-mode (which looks up
auto-mode-alist and directory local vars appropriately).

> And by setting buffer-file-name they by side effect tell unrelated
> features that this buffer is associated with a file?

Indeed.

> If so, then I'm not sure I understand the solution.  The offending
> modes will have to be modified to use this new variable instead of
> buffer-file-name, no?

That's what the patch does, yes (modulo the fact that they're not
really "modes").

> And if we have to modify them, then why not do TRT while at that,
> i.e. call the major mode directly instead of setting some variable?

We set the variable in order to find out what mode to use.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 20:12                   ` Stefan Monnier
@ 2020-01-28 20:23                     ` Eli Zaretskii
  2020-01-28 23:17                       ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2020-01-28 20:23 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, felician.nemeth, juri

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: juri@linkov.net,  39190@debbugs.gnu.org,  felician.nemeth@gmail.com
> Date: Tue, 28 Jan 2020 15:12:03 -0500
> 
> > And if we have to modify them, then why not do TRT while at that,
> > i.e. call the major mode directly instead of setting some variable?
> 
> We set the variable in order to find out what mode to use.

Sorry, I don't understand.  I meant to ask why the code which sets
this new variable cannot call the major mode function instead?





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 14:54                 ` Dmitry Gutov
@ 2020-01-28 22:53                   ` Juri Linkov
  0 siblings, 0 replies; 52+ messages in thread
From: Juri Linkov @ 2020-01-28 22:53 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 39190, felician.nemeth, Stefan Monnier

>> it can cause
>> problems because hooks are run during this time (e.g. major mode hooks)
>> which may take action under the mistaken assumption that this buffer
>> really correspond to the file
>
> I think diff-mode could also use delay-mode-hooks and then run them (or
> not) outside of that let binding.

Interesting idea, I see no problem with this:

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 2dbab80208..9035f7643a 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2719,7 +2719,7 @@ diff-syntax-fontify-props
     (cl-assert (null buffer-file-name))
     (let ((enable-local-variables :safe) ;; to find `mode:'
           (buffer-file-name file))
-      (set-auto-mode)
+      (delay-mode-hooks (set-auto-mode))
       ;; FIXME: Is this really worth the trouble?
       (when (and (fboundp 'generic-mode-find-file-hook)
                  (memq #'generic-mode-find-file-hook





^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 20:23                     ` Eli Zaretskii
@ 2020-01-28 23:17                       ` Stefan Monnier
  2020-01-29 17:13                         ` Eli Zaretskii
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-01-28 23:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 39190, felician.nemeth, juri

> Sorry, I don't understand.  I meant to ask why the code which sets
> this new variable cannot call the major mode function instead?

The code does basically:

    (let ((buffer-file-name FOO))
      (set-auto-mode))

How could it "call the major mode function instead"?


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 23:17                       ` Stefan Monnier
@ 2020-01-29 17:13                         ` Eli Zaretskii
  2020-01-29 21:33                           ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2020-01-29 17:13 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, felician.nemeth, juri

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: juri@linkov.net,  39190@debbugs.gnu.org,  felician.nemeth@gmail.com
> Date: Tue, 28 Jan 2020 18:17:23 -0500
> 
> > Sorry, I don't understand.  I meant to ask why the code which sets
> > this new variable cannot call the major mode function instead?
> 
> The code does basically:
> 
>     (let ((buffer-file-name FOO))
>       (set-auto-mode))

Ah, okay.

But then did you consider alternatives to yet another magic
buffer-local variable?  Two possibilities come to mind:

 . change set-auto-mode to accept another optional argument, the file
   name to use to look up the mode

 . perform look up of auto-mode-alist, then invoke the mode directly

Also, setting the pseudo-filename is not guaranteed to turn on the
mode according to that file name.  Not sure if this matters in these
cases.

And finally, I cannot say that I like this part of the patch:

  @@ -3459,6 +3460,8 @@ hack-local-variables-confirm
       (let ((name (cond (dir-name)
			(buffer-file-name
			 (file-name-nondirectory buffer-file-name))
  +		      (buffer-file-name-for-mode
  +		       (file-name-nondirectory buffer-file-name-for-mode))
			((concat "buffer " (buffer-name)))))
	    (offer-save (and (eq enable-local-variables t)
			     unsafe-vars))

If buffer-file-name-for-mode is not really a file name, we shouldn't
call file-name-nondirectory on it.  If nothing else, it will signal an
error if buffer-file-name-for-mode is nil.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-29 17:13                         ` Eli Zaretskii
@ 2020-01-29 21:33                           ` Stefan Monnier
  2020-01-30 14:17                             ` Eli Zaretskii
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-01-29 21:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 39190, felician.nemeth, juri

> But then did you consider alternatives to yet another magic
> buffer-local variable?  Two possibilities come to mind:
>
>  . change set-auto-mode to accept another optional argument, the file
>    name to use to look up the mode
>
>  . perform look up of auto-mode-alist, then invoke the mode directly

The issue is that we also want to obey dir-locals and both above options
seem to become more invasive once we try and handle those (the first
above option is the first one I proposed, since I prefer
lexically-scoped args over dynamically-scoped vars ;-)

> Also, setting the pseudo-filename is not guaranteed to turn on the
> mode according to that file name.  Not sure if this matters in these
> cases.

Not sure what you mean here.

> And finally, I cannot say that I like this part of the patch:
>
>   @@ -3459,6 +3460,8 @@ hack-local-variables-confirm
>        (let ((name (cond (dir-name)
> 			(buffer-file-name
> 			 (file-name-nondirectory buffer-file-name))
>   +		      (buffer-file-name-for-mode
>   +		       (file-name-nondirectory buffer-file-name-for-mode))
> 			((concat "buffer " (buffer-name)))))
> 	    (offer-save (and (eq enable-local-variables t)
> 			     unsafe-vars))
>
> If buffer-file-name-for-mode is not really a file name, we shouldn't
> call file-name-nondirectory on it.

It is supposed to be a file name.  It's only that the buffer is not
supposed to be the buffer corresponding to that file.

> If nothing else, it will signal an
> error if buffer-file-name-for-mode is nil.

That code is predicated on `buffer-file-name-for-mode` being
non-nil, AFAICT, so I think we're OK in this regard.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28 17:18           ` Felician Nemeth
@ 2020-01-29 23:07             ` Juri Linkov
  2020-01-30 19:48               ` Felician Nemeth
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-01-29 23:07 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 39190, Stefan Monnier

>> Since it will take much time when the fix in Emacs will appear in a released
>> version, a workaround needs to be added to Eglot immediately.
>
> OK, but this feature ("Better syntax highlighting of Diff hunks") will
> first appear in Emacs 27.

Right, so it needs to be fixed in Emacs 27.

Could you please try to reproduce the issue using Eglot with the
following minimal patch.  If it really fixes the bug then it
should be committed to Emacs 27 immediately, and more changes
could be added later.

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 2dbab80208..9035f7643a 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2719,7 +2719,7 @@ diff-syntax-fontify-props
     (cl-assert (null buffer-file-name))
     (let ((enable-local-variables :safe) ;; to find `mode:'
           (buffer-file-name file))
-      (set-auto-mode)
+      (delay-mode-hooks (set-auto-mode))
       ;; FIXME: Is this really worth the trouble?
       (when (and (fboundp 'generic-mode-find-file-hook)
                  (memq #'generic-mode-find-file-hook







^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-29 21:33                           ` Stefan Monnier
@ 2020-01-30 14:17                             ` Eli Zaretskii
  2020-01-30 14:34                               ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Eli Zaretskii @ 2020-01-30 14:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, felician.nemeth, juri

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: juri@linkov.net,  39190@debbugs.gnu.org,  felician.nemeth@gmail.com
> Date: Wed, 29 Jan 2020 16:33:31 -0500
> 
> > But then did you consider alternatives to yet another magic
> > buffer-local variable?  Two possibilities come to mind:
> >
> >  . change set-auto-mode to accept another optional argument, the file
> >    name to use to look up the mode
> >
> >  . perform look up of auto-mode-alist, then invoke the mode directly
> 
> The issue is that we also want to obey dir-locals and both above options
> seem to become more invasive once we try and handle those (the first
> above option is the first one I proposed, since I prefer
> lexically-scoped args over dynamically-scoped vars ;-)

What is the problem of the first alternative wrt dir-locals?  I don't
think I understand that.

> > Also, setting the pseudo-filename is not guaranteed to turn on the
> > mode according to that file name.  Not sure if this matters in these
> > cases.
> 
> Not sure what you mean here.

set-auto-mode looks on other mode-determining stuff, before looking at
the file name.

> > And finally, I cannot say that I like this part of the patch:
> >
> >   @@ -3459,6 +3460,8 @@ hack-local-variables-confirm
> >        (let ((name (cond (dir-name)
> > 			(buffer-file-name
> > 			 (file-name-nondirectory buffer-file-name))
> >   +		      (buffer-file-name-for-mode
> >   +		       (file-name-nondirectory buffer-file-name-for-mode))
> > 			((concat "buffer " (buffer-name)))))
> > 	    (offer-save (and (eq enable-local-variables t)
> > 			     unsafe-vars))
> >
> > If buffer-file-name-for-mode is not really a file name, we shouldn't
> > call file-name-nondirectory on it.
> 
> It is supposed to be a file name.  It's only that the buffer is not
> supposed to be the buffer corresponding to that file.

Yes, but having leading directories in it feels... unclean, even more
than just having this variable.

> > If nothing else, it will signal an
> > error if buffer-file-name-for-mode is nil.
> 
> That code is predicated on `buffer-file-name-for-mode` being
> non-nil, AFAICT, so I think we're OK in this regard.

Non-nil doesn't mean it's a string.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-30 14:17                             ` Eli Zaretskii
@ 2020-01-30 14:34                               ` Stefan Monnier
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Monnier @ 2020-01-30 14:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 39190, felician.nemeth, juri

>> >  . change set-auto-mode to accept another optional argument, the file
>> >    name to use to look up the mode
>> >
>> >  . perform look up of auto-mode-alist, then invoke the mode directly
>> 
>> The issue is that we also want to obey dir-locals and both above options
>> seem to become more invasive once we try and handle those (the first
>> above option is the first one I proposed, since I prefer
>> lexically-scoped args over dynamically-scoped vars ;-)
>
> What is the problem of the first alternative wrt dir-locals?  I don't
> think I understand that.

As I wrote: it's more invasive because you have to pass that extra arg
through various functions.

>> > Also, setting the pseudo-filename is not guaranteed to turn on the
>> > mode according to that file name.  Not sure if this matters in these
>> > cases.
>> Not sure what you mean here.
> set-auto-mode looks on other mode-determining stuff, before looking at
> the file name.

Ah, right.  This is a side-issue, yes: in cases like
`vc-revision-other-window` it does exactly what we want (i.e. it takes
advantage of the buffer's content (file-local vars, magic strings, ...)
to guess the mode), but in cases like diff-mode it can be detrimental
(since we don't have the full file content in that case, but only
a chunk of it, which means that things like file-local vars not only
will usually not be found but can even be incorrectly found).

I don't think it makes much difference to the current discussion, tho
(it's largely orthogonal).

>> > And finally, I cannot say that I like this part of the patch:
>> >
>> >   @@ -3459,6 +3460,8 @@ hack-local-variables-confirm
>> >        (let ((name (cond (dir-name)
>> > 			(buffer-file-name
>> > 			 (file-name-nondirectory buffer-file-name))
>> >   +		      (buffer-file-name-for-mode
>> >   +		       (file-name-nondirectory buffer-file-name-for-mode))
>> > 			((concat "buffer " (buffer-name)))))
>> > 	    (offer-save (and (eq enable-local-variables t)
>> > 			     unsafe-vars))
>> >
>> > If buffer-file-name-for-mode is not really a file name, we shouldn't
>> > call file-name-nondirectory on it.
>> 
>> It is supposed to be a file name.  It's only that the buffer is not
>> supposed to be the buffer corresponding to that file.
>
> Yes, but having leading directories in it feels... unclean,

Why so?  The leading directories are crucial for dir-locals support, and
they can also be important for auto-mode-alist.

>> That code is predicated on `buffer-file-name-for-mode` being
>> non-nil, AFAICT, so I think we're OK in this regard.
> Non-nil doesn't mean it's a string.

If someone sets it to non-nil and not a string, they'll get what
they deserve.  Same holds already for `buffer-file-name`, so it's not
a new problem introduced with this change.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-29 23:07             ` Juri Linkov
@ 2020-01-30 19:48               ` Felician Nemeth
  2020-01-30 22:45                 ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Felician Nemeth @ 2020-01-30 19:48 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Stefan Monnier

> Could you please try to reproduce the issue using Eglot with the
> following minimal patch.  If it really fixes the bug then it
> should be committed to Emacs 27 immediately, and more changes
> could be added later.

Unfortunately the minimal patch doesn't fix the issue.

Case 1. When Eglot is started manually, then the recipe fails in an
after-change-major-mode-hook where the buffer-file-name is non-nil for
the temporary diff buffer.

Case 2. With (add-to-list 'python-mode-hook 'eglot-ensure) the recipe
fails in a post-command-hook, because eglot-ensure has this:

      (when buffer-file-name
        (add-hook 'post-command-hook #'maybe-connect 'append nil)))))

And buffer-file-name is non-nil for the diff buffer during the execution
of python-mode-hook.  But during the execution of maybe-connect in the
post-command-hook, the buffer-file-name is nil and that leads to an
error.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-30 19:48               ` Felician Nemeth
@ 2020-01-30 22:45                 ` Juri Linkov
  2020-02-02  9:42                   ` Felician Nemeth
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-01-30 22:45 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 39190, Stefan Monnier

>> Could you please try to reproduce the issue using Eglot with the
>> following minimal patch.  If it really fixes the bug then it
>> should be committed to Emacs 27 immediately, and more changes
>> could be added later.
>
> Unfortunately the minimal patch doesn't fix the issue.
>
> Case 1. When Eglot is started manually, then the recipe fails in an
> after-change-major-mode-hook where the buffer-file-name is non-nil for
> the temporary diff buffer.

Strange, when I tested the minimal patch, there were no errors anymore.

Before the patch, I got this error in the git master when trying
to use 'C-c C-r' (diff-reverse-direction) in the diff buffer:

  Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
    substring(nil 0 1)
    file-truename(nil)

But after applying the patch, after-change-major-mode-hook is not called
anymore in the temporary diff buffer.

> Case 2. With (add-to-list 'python-mode-hook 'eglot-ensure) the recipe
> fails in a post-command-hook, because eglot-ensure has this:
>
>       (when buffer-file-name
>         (add-hook 'post-command-hook #'maybe-connect 'append nil)))))
>
> And buffer-file-name is non-nil for the diff buffer during the execution
> of python-mode-hook.  But during the execution of maybe-connect in the
> post-command-hook, the buffer-file-name is nil and that leads to an
> error.

I guess Eglot should have more safeguarding, i.e. the same check
'when buffer-file-name' could be added to 'maybe-connect' as well.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-28  1:30           ` Stefan Monnier
  2020-01-28  3:32             ` Eli Zaretskii
@ 2020-01-30 22:50             ` Juri Linkov
  2020-01-30 23:09               ` Stefan Monnier
  2020-01-30 23:31               ` Dmitry Gutov
  1 sibling, 2 replies; 52+ messages in thread
From: Juri Linkov @ 2020-01-30 22:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

> And now that I think about it, maybe
>
>     (or buffer-file-name-for-mode buffer-file-name)

I encountered more problems with buffer-file-name-for-mode
because there are more unexpected places that expect buffer-file-name:

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  find-file-name-handler(nil file-name-sans-versions)
  file-name-sans-versions(nil)
  generic-mode-find-file-hook()
  diff-syntax-fontify-props(#("/dev/null" 0 9 (face (diff-file-header diff-header) fontified t)) "" (0 0) t)
  diff-syntax-fontify-hunk(1686 3081 t)
  diff-syntax-fontify(1686 3081)

because it relies on non-nil buffer-file-name:

(defun generic-mode-find-file-hook ()
  ...
  (when (and (eq major-mode 'fundamental-mode)
             (or (null generic-ignore-files-regexp)
                 (not (string-match-p
                       generic-ignore-files-regexp
                       (file-name-sans-versions buffer-file-name)))))
                                                ================

It would be hard to find all occurrences of buffer-file-name
where to add buffer-file-name-for-mode.

Maybe safer would be to use just (delay-mode-hooks (set-auto-mode))





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-30 22:50             ` Juri Linkov
@ 2020-01-30 23:09               ` Stefan Monnier
  2020-01-30 23:31               ` Dmitry Gutov
  1 sibling, 0 replies; 52+ messages in thread
From: Stefan Monnier @ 2020-01-30 23:09 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

>   generic-mode-find-file-hook()

Add that to the list of reasons why I loathe generic.el (and think that
diff-mode shouldn't call it explicitly).


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-30 22:50             ` Juri Linkov
  2020-01-30 23:09               ` Stefan Monnier
@ 2020-01-30 23:31               ` Dmitry Gutov
  1 sibling, 0 replies; 52+ messages in thread
From: Dmitry Gutov @ 2020-01-30 23:31 UTC (permalink / raw)
  To: Juri Linkov, Stefan Monnier; +Cc: 39190, Felician Nemeth

On 31.01.2020 1:50, Juri Linkov wrote:
> Maybe safer would be to use just (delay-mode-hooks (set-auto-mode))

That would be my choice as well.

BTW, xref--collect-matches uses buffer-file-name in a similar way, 
curious how a problem with Eglot (or etc) never came up.

Also, see the comment there why it couldn't use delay-mode-hooks at the 
time (maybe it can now, if we're okay with entirely unsupporting 
syntax-propertize-via-font-lock).





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-01-30 22:45                 ` Juri Linkov
@ 2020-02-02  9:42                   ` Felician Nemeth
  2020-02-02 13:50                     ` Stefan Monnier
  2020-02-03 22:45                     ` Juri Linkov
  0 siblings, 2 replies; 52+ messages in thread
From: Felician Nemeth @ 2020-02-02  9:42 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Stefan Monnier

Juri Linkov <juri@linkov.net> writes:

>>> Could you please try to reproduce the issue using Eglot with the
>>> following minimal patch.  If it really fixes the bug then it
>>> should be committed to Emacs 27 immediately, and more changes
>>> could be added later.
>>
>> Unfortunately the minimal patch doesn't fix the issue.
>>
>> Case 1. When Eglot is started manually, then the recipe fails in an
>> after-change-major-mode-hook where the buffer-file-name is non-nil for
>> the temporary diff buffer.
>
> Strange, when I tested the minimal patch, there were no errors anymore.

Maybe I wasn't clear enough.  I got no errors, but flymake incorrectly
fontified the buffer.  Anyway, I tried to look into why this happened
even after applying your patch and it turned out that
vc-find-revision-no-save also calls set-auto-mode.  So, I don't know if
the following patch is correct, but together with your patch it does
solve the original issue.

diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index f64b6c0631..c50ba132e7 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -2098,7 +2098,7 @@ vc-find-revision-no-save
                     ;; For non-interactive, skip any questions
                     (let ((enable-local-variables :safe) ;; to find `mode:'
                           (buffer-file-name file))
-                      (ignore-errors (set-auto-mode)))
+                      (ignore-errors (delay-mode-hooks (set-auto-mode))))
                   (normal-mode))
 	        (set-buffer-modified-p nil)
                 (setq buffer-read-only t))






^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-02  9:42                   ` Felician Nemeth
@ 2020-02-02 13:50                     ` Stefan Monnier
  2020-02-02 23:41                       ` Juri Linkov
  2020-02-03 22:45                     ` Juri Linkov
  1 sibling, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-02-02 13:50 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 39190, Juri Linkov

> vc-find-revision-no-save also calls set-auto-mode.  So, I don't know if
> the following patch is correct, but together with your patch it does
> solve the original issue.
>
> diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
> index f64b6c0631..c50ba132e7 100644
> --- a/lisp/vc/vc.el
> +++ b/lisp/vc/vc.el
> @@ -2098,7 +2098,7 @@ vc-find-revision-no-save
>                      ;; For non-interactive, skip any questions
>                      (let ((enable-local-variables :safe) ;; to find `mode:'
>                            (buffer-file-name file))
> -                      (ignore-errors (set-auto-mode)))
> +                      (ignore-errors (delay-mode-hooks (set-auto-mode))))
>                    (normal-mode))
>  	        (set-buffer-modified-p nil)
>                  (setq buffer-read-only t))

How 'bout we first consolidate the two cases into one by introducing
a new function `set-auto-mode-for-filename` that both
vc-find-revision-no-save and diff-mode can use?


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-02 13:50                     ` Stefan Monnier
@ 2020-02-02 23:41                       ` Juri Linkov
  2020-02-03 13:14                         ` Dmitry Gutov
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-02 23:41 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

[-- Attachment #1: Type: text/plain, Size: 1237 bytes --]

>> vc-find-revision-no-save also calls set-auto-mode.  So, I don't know if
>> the following patch is correct, but together with your patch it does
>> solve the original issue.
>>
>> diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
>> index f64b6c0631..c50ba132e7 100644
>> --- a/lisp/vc/vc.el
>> +++ b/lisp/vc/vc.el
>> @@ -2098,7 +2098,7 @@ vc-find-revision-no-save
>>                      ;; For non-interactive, skip any questions
>>                      (let ((enable-local-variables :safe) ;; to find `mode:'
>>                            (buffer-file-name file))
>> -                      (ignore-errors (set-auto-mode)))
>> +                      (ignore-errors (delay-mode-hooks (set-auto-mode))))
>>                    (normal-mode))
>>  	        (set-buffer-modified-p nil)
>>                  (setq buffer-read-only t))
>
> How 'bout we first consolidate the two cases into one by introducing
> a new function `set-auto-mode-for-filename` that both
> vc-find-revision-no-save and diff-mode can use?

Actually vc-find-revision-no-save when called as a command (e.g. by the
key 'f' from log-view) still should run hooks because the buffer it creates
is not internal.

Only its call from diff-syntax-fontify-hunk should not run hooks:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: delay-mode-hooks.patch --]
[-- Type: text/x-diff, Size: 2450 bytes --]

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 2dbab80208..9cdd732923 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2635,11 +2635,11 @@ diff-syntax-fontify-hunk
                          ;; Don't re-initialize the buffer (which would throw
                          ;; away the previous fontification work).
                          (setq file nil)
-                       (setq buffer (ignore-errors
+                       (setq buffer (ignore-errors (delay-mode-hooks
                                       (vc-find-revision-no-save
                                        file revision
                                        diff-vc-backend
-                                       (get-buffer-create buffer-name)))))
+                                       (get-buffer-create buffer-name))))))
                      (when buffer
                        (with-current-buffer buffer
                          (diff-syntax-fontify-props file text line-nb))))))))
@@ -2719,7 +2719,7 @@ diff-syntax-fontify-props
     (cl-assert (null buffer-file-name))
     (let ((enable-local-variables :safe) ;; to find `mode:'
           (buffer-file-name file))
-      (set-auto-mode)
+      (delay-mode-hooks (set-auto-mode))
       ;; FIXME: Is this really worth the trouble?
       (when (and (fboundp 'generic-mode-find-file-hook)
                  (memq #'generic-mode-find-file-hook
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el
index a6be04e313..e629674ea6 100644
--- a/lisp/gnus/mm-view.el
+++ b/lisp/gnus/mm-view.el
@@ -497,7 +497,7 @@ mm-display-inline-fontify
 	    (let ((auto-mode-alist
 		   (delq (rassq 'doc-view-mode-maybe auto-mode-alist)
 			 (copy-sequence auto-mode-alist))))
-	      (set-auto-mode)
+	      (delay-mode-hooks (set-auto-mode))
 	      (setq mode major-mode)))
 	  ;; Do not fontify if the guess mode is fundamental.
 	  (unless (eq major-mode 'fundamental-mode)
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 1a34456340..741ed73905 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1395,7 +1395,7 @@ xref--collect-matches
                 (inhibit-message t)
                 message-log-max)
             (ignore-errors
-              (set-auto-mode t)))
+              (delay-mode-hooks (set-auto-mode t))))
           (setq-local xref--temp-buffer-file-name file)
           (setq-local inhibit-read-only t)
           (erase-buffer))

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-02 23:41                       ` Juri Linkov
@ 2020-02-03 13:14                         ` Dmitry Gutov
  2020-02-03 22:44                           ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Dmitry Gutov @ 2020-02-03 13:14 UTC (permalink / raw)
  To: Juri Linkov, Stefan Monnier; +Cc: 39190, Felician Nemeth

On 03.02.2020 2:41, Juri Linkov wrote:
> --- a/lisp/progmodes/xref.el
> +++ b/lisp/progmodes/xref.el
> @@ -1395,7 +1395,7 @@ xref--collect-matches
>                   (inhibit-message t)
>                   message-log-max)
>               (ignore-errors
> -              (set-auto-mode t)))
> +              (delay-mode-hooks (set-auto-mode t))))

Nope.

There's even a comment above these lines explaining why I didn't use 
delay-mode-hooks there.

I've even mentioned it in this thread already.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-03 13:14                         ` Dmitry Gutov
@ 2020-02-03 22:44                           ` Juri Linkov
  2020-02-04 13:08                             ` Dmitry Gutov
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-03 22:44 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 39190, Felician Nemeth, Stefan Monnier

>> @@ -1395,7 +1395,7 @@ xref--collect-matches
>>                   (inhibit-message t)
>>                   message-log-max)
>>               (ignore-errors
>> -              (set-auto-mode t)))
>> +              (delay-mode-hooks (set-auto-mode t))))
>
> Nope.
>
> There's even a comment above these lines explaining why I didn't use
> delay-mode-hooks there.
>
> I've even mentioned it in this thread already.

I hoped that maybe this was solved somehow already.
But if there is no problem in using xref with Eglot,
then let's leave it unchanged.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-02  9:42                   ` Felician Nemeth
  2020-02-02 13:50                     ` Stefan Monnier
@ 2020-02-03 22:45                     ` Juri Linkov
  2020-02-04 13:36                       ` Stefan Monnier
  1 sibling, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-03 22:45 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 39190, Stefan Monnier

> Maybe I wasn't clear enough.  I got no errors, but flymake incorrectly
> fontified the buffer.  Anyway, I tried to look into why this happened
> even after applying your patch and it turned out that
> vc-find-revision-no-save also calls set-auto-mode.  So, I don't know if
> the following patch is correct, but together with your patch it does
> solve the original issue.
>
> diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
> index f64b6c0631..c50ba132e7 100644
> --- a/lisp/vc/vc.el
> +++ b/lisp/vc/vc.el
> @@ -2098,7 +2098,7 @@ vc-find-revision-no-save
>                      ;; For non-interactive, skip any questions
>                      (let ((enable-local-variables :safe) ;; to find `mode:'
>                            (buffer-file-name file))
> -                      (ignore-errors (set-auto-mode)))
> +                      (ignore-errors (delay-mode-hooks (set-auto-mode))))
>                    (normal-mode))
>  	        (set-buffer-modified-p nil)
>                  (setq buffer-read-only t))

vc-find-revision-no-save should not use delay-mode-hooks when called as
a command.  Could you please try again with the following patch:

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 2dbab80208..9cdd732923 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2635,11 +2635,11 @@ diff-syntax-fontify-hunk
                          ;; Don't re-initialize the buffer (which would throw
                          ;; away the previous fontification work).
                          (setq file nil)
-                       (setq buffer (ignore-errors
+                       (setq buffer (ignore-errors (delay-mode-hooks
                                       (vc-find-revision-no-save
                                        file revision
                                        diff-vc-backend
-                                       (get-buffer-create buffer-name)))))
+                                       (get-buffer-create buffer-name))))))
                      (when buffer
                        (with-current-buffer buffer
                          (diff-syntax-fontify-props file text line-nb))))))))
@@ -2719,7 +2719,7 @@ diff-syntax-fontify-props
     (cl-assert (null buffer-file-name))
     (let ((enable-local-variables :safe) ;; to find `mode:'
           (buffer-file-name file))
-      (set-auto-mode)
+      (delay-mode-hooks (set-auto-mode))
       ;; FIXME: Is this really worth the trouble?
       (when (and (fboundp 'generic-mode-find-file-hook)
                  (memq #'generic-mode-find-file-hook





^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-03 22:44                           ` Juri Linkov
@ 2020-02-04 13:08                             ` Dmitry Gutov
  0 siblings, 0 replies; 52+ messages in thread
From: Dmitry Gutov @ 2020-02-04 13:08 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth, Stefan Monnier

On 04.02.2020 1:44, Juri Linkov wrote:
> I hoped that maybe this was solved somehow already.
> But if there is no problem in using xref with Eglot,
> then let's leave it unchanged.

There is a related bug report. As long as we support 
syntax-propertize-via-font-lock, let's not change it (unless some 
related bug reports come).

Eglot should have its own xref backend, maybe that's why it doesn't 
trigger it.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-03 22:45                     ` Juri Linkov
@ 2020-02-04 13:36                       ` Stefan Monnier
  2020-02-04 23:20                         ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-02-04 13:36 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> vc-find-revision-no-save should not use delay-mode-hooks when called as
> a command.

That's the problem with the current approach: we end up making decisions
which can't be justified.  Whether mode hooks should be run or not
depends on the hook and various other things.  What we *do* know, OTOH
is that `vc-find-revision-no-save`s buffer is not associated with
a file, so setting `buffer-file-name` can result in bugs.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-04 13:36                       ` Stefan Monnier
@ 2020-02-04 23:20                         ` Juri Linkov
  2020-02-05 22:39                           ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-04 23:20 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

>> vc-find-revision-no-save should not use delay-mode-hooks when called as
>> a command.
>
> That's the problem with the current approach: we end up making decisions
> which can't be justified.  Whether mode hooks should be run or not
> depends on the hook and various other things.  What we *do* know, OTOH
> is that `vc-find-revision-no-save`s buffer is not associated with
> a file, so setting `buffer-file-name` can result in bugs.

delay-mode-hooks was intended as the safest workaround to install in emacs-27.

Using alternatives of buffer-file-name are not straightforward
and need more testing in emacs-28.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-04 23:20                         ` Juri Linkov
@ 2020-02-05 22:39                           ` Juri Linkov
  2020-02-09 16:06                             ` Felician Nemeth
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-05 22:39 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

>> That's the problem with the current approach: we end up making decisions
>> which can't be justified.  Whether mode hooks should be run or not
>> depends on the hook and various other things.  What we *do* know, OTOH
>> is that `vc-find-revision-no-save`s buffer is not associated with
>> a file, so setting `buffer-file-name` can result in bugs.
>
> delay-mode-hooks was intended as the safest workaround to install in emacs-27.

delay-mode-hooks is now in emacs-27.

> Using alternatives of buffer-file-name are not straightforward
> and need more testing in emacs-28.

I don't know how to handle this more properly because some hooks
should be run with buffer-file-name, e.g. generic-mode-find-file-hook
that uses buffer-file-name to add more font-lock highlighting.
But some hooks like in Eglot assume that buffer-file-name associates the
buffer with a file.

Also I tried to use indirect buffers:

(let ((buffer (make-indirect-buffer
               (current-buffer)
               (generate-new-buffer-name (buffer-name)))))
  (funcall
   (unwind-protect
       (with-current-buffer buffer
         (let ((buffer-file-name "/tmp/foo.el"))
           (set-auto-mode)
           major-mode))
     (kill-buffer buffer))))

but not sure if it's enough to just set its deduced mode.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-05 22:39                           ` Juri Linkov
@ 2020-02-09 16:06                             ` Felician Nemeth
  2020-02-18  0:06                               ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Felician Nemeth @ 2020-02-09 16:06 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Stefan Monnier

>> delay-mode-hooks was intended as the safest workaround to install in emacs-27.
>
> delay-mode-hooks is now in emacs-27.

This makes the original problem disappear.  Thank you.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-09 16:06                             ` Felician Nemeth
@ 2020-02-18  0:06                               ` Juri Linkov
  2020-02-18 13:33                                 ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-18  0:06 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 39190, Stefan Monnier

>>> delay-mode-hooks was intended as the safest workaround to install in emacs-27.
>>
>> delay-mode-hooks is now in emacs-27.
>
> This makes the original problem disappear.  Thank you.

Unfortunately, this change broke diff-syntax font-lock of conf-space-mode -
font-lock from files in conf-space-mode is not displayed in diffs anymore.

First, these steps show how it used to work when set-auto-mode was called
from diff-syntax-fontify-props without wrapping in delay-mode-hooks macro:

- diff-syntax-fontify-props calls set-auto-mode
- in auto-mode-alist a file extension is associated with conf-mode-maybe
- conf-mode-maybe calls conf-mode
- conf-mode checks for the variable 'delay-mode-hooks':
- initially delay-mode-hooks is nil, so call conf-space-mode
- conf-space-mode calls its parent mode conf-mode again
- when conf-mode is called again, its delay-mode-hooks is t
  and it sets its mode variables.

Now the failure caused by wrapping (delay-mode-hooks (set-auto-mode))
in diff-syntax-fontify-props is because on the first call of conf-mode,
the variable 'delay-mode-hooks' is already t, not nil as it was before
the change.

All this due to such trick used in conf-mode with these comments:

(defun conf-mode ()
  ...
  ;; `conf-mode' plays two roles: it's the parent of several sub-modes
  ;; but it's also the function that chooses between those submodes.
  ;; To tell the difference between those two cases where the function
  ;; might be called, we check `delay-mode-hooks'.
  ;; (adopted from tex-mode.el)
  (if (not delay-mode-hooks)
      ;; try to guess sub-mode of conf-mode based on buffer content

So it detects the situation when define-derived-mode runs the parent
with delay-mode-hooks.

I have no idea what to do in this case.





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-18  0:06                               ` Juri Linkov
@ 2020-02-18 13:33                                 ` Stefan Monnier
  2020-02-18 22:53                                   ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-02-18 13:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> (defun conf-mode ()
>   ...
>   ;; `conf-mode' plays two roles: it's the parent of several sub-modes
>   ;; but it's also the function that chooses between those submodes.
>   ;; To tell the difference between those two cases where the function
>   ;; might be called, we check `delay-mode-hooks'.
>   ;; (adopted from tex-mode.el)
>   (if (not delay-mode-hooks)
>       ;; try to guess sub-mode of conf-mode based on buffer content

The Right Thing™ to do is of course to split `conf-mode` into two
functions, one for the generic entry point and the other for the shared
parent mode.

How easy/realistic this is, I don't know.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-18 13:33                                 ` Stefan Monnier
@ 2020-02-18 22:53                                   ` Juri Linkov
  2020-02-18 23:07                                     ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-18 22:53 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

>> (defun conf-mode ()
>>   ...
>>   ;; `conf-mode' plays two roles: it's the parent of several sub-modes
>>   ;; but it's also the function that chooses between those submodes.
>>   ;; To tell the difference between those two cases where the function
>>   ;; might be called, we check `delay-mode-hooks'.
>>   ;; (adopted from tex-mode.el)
>>   (if (not delay-mode-hooks)
>>       ;; try to guess sub-mode of conf-mode based on buffer content
>
> The Right Thing™ to do is of course to split `conf-mode` into two
> functions, one for the generic entry point and the other for the shared
> parent mode.

Maybe a simpler variant would be to use some other variable to distinguish
sub-mode and its parent, instead of relying on delay-mode-hooks?





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-18 22:53                                   ` Juri Linkov
@ 2020-02-18 23:07                                     ` Stefan Monnier
  2020-02-18 23:31                                       ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-02-18 23:07 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> Maybe a simpler variant would be to use some other variable to distinguish
> sub-mode and its parent, instead of relying on delay-mode-hooks?

That's kinda hard if you want to use define-derived-mode and we do: when
we call `conf-foo-mode` the first things it does is: bind
`delay-mode-hooks` and call the parent (`conf-mode`), so the only
difference between this call to the parent and a direct call to the
generic entry point is the binding of `delay-mode-hooks`.


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-18 23:07                                     ` Stefan Monnier
@ 2020-02-18 23:31                                       ` Stefan Monnier
  2020-02-19  0:49                                         ` Juri Linkov
  2020-03-24 21:37                                         ` Juri Linkov
  0 siblings, 2 replies; 52+ messages in thread
From: Stefan Monnier @ 2020-02-18 23:31 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

>> Maybe a simpler variant would be to use some other variable to distinguish
>> sub-mode and its parent, instead of relying on delay-mode-hooks?
>
> That's kinda hard if you want to use define-derived-mode and we do: when
> we call `conf-foo-mode` the first things it does is: bind
> `delay-mode-hooks` and call the parent (`conf-mode`), so the only
> difference between this call to the parent and a direct call to the
> generic entry point is the binding of `delay-mode-hooks`.

IOW, I think we should start with something like the patch below which
makes `conf-guess-mode` available, after which we can start fixing the
various callers to call `conf-guess-mode` instead.


        Stefan


diff --git a/lisp/textmodes/conf-mode.el b/lisp/textmodes/conf-mode.el
index 86db698043..b3325eeff6 100644
--- a/lisp/textmodes/conf-mode.el
+++ b/lisp/textmodes/conf-mode.el
@@ -351,7 +351,37 @@ conf-outline-level
 \f
 
 ;;;###autoload
-(defun conf-mode ()
+(defun conf-guess-mode ()
+  "Enable the conf-*-mode that seems most appropriate."
+  (let ((unix 0) (win 0) (equal 0) (colon 0) (space 0) (jp 0))
+    (save-excursion
+      (goto-char (point-min))
+      (while (not (eobp))
+	(skip-chars-forward " \t\f")
+	(cond ((eq (char-after) ?\#) (setq unix (1+ unix)))
+	      ((eq (char-after) ?\;) (setq win (1+ win)))
+	      ((eq (char-after) ?\[))	; nop
+	      ((eolp))			; nop
+	      ((eq (char-after) ?}))	; nop
+	      ;; recognize at most double spaces within names
+	      ((looking-at "[^ \t\n=:]+\\(?:  ?[^ \t\n=:]+\\)*[ \t]*[=:]")
+	       (if (eq (char-before (match-end 0)) ?=)
+		   (setq equal (1+ equal))
+		 (setq colon (1+ colon))))
+	      ((looking-at "/[/*]") (setq jp (1+ jp)))
+	      ((looking-at ".*{"))		; nop
+	      ((setq space (1+ space))))
+	(forward-line)))
+    (cond
+     ((> jp (max unix win 3)) (conf-javaprop-mode))
+     ((> colon (max equal space)) (conf-colon-mode))
+     ((> space (max equal colon)) (conf-space-mode))
+     ((or (> win unix) (and (= win unix) (eq system-type 'windows-nt)))
+      (conf-windows-mode))
+     (t (conf-unix-mode)))))
+
+;;;###autoload
+(define-derived-mode conf-mode nil "Conf[?]"
   "Mode for Unix and Windows Conf files and Java properties.
 Most conf files know only three kinds of constructs: parameter
 assignments optionally grouped into sections and comments.  Yet
@@ -372,7 +402,7 @@ conf-mode
 quite right.  Patches that clearly identify some special case,
 without breaking the general ones, are welcome.
 
-If instead you start this mode with the generic `conf-mode'
+If instead you start this mode with the generic `conf-guess-mode'
 command, it will parse the buffer.  It will generally well
 identify the first four cases listed below.  If the buffer
 doesn't have enough contents to decide, this is identical to
@@ -381,46 +411,13 @@ conf-mode
 `conf-ppd-mode' and `conf-xdefaults-mode'.
 
 \\{conf-mode-map}"
-
-  (interactive)
-  ;; `conf-mode' plays two roles: it's the parent of several sub-modes
-  ;; but it's also the function that chooses between those submodes.
-  ;; To tell the difference between those two cases where the function
-  ;; might be called, we check `delay-mode-hooks'.
-  ;; (adopted from tex-mode.el)
+  ;; `conf-mode' is the parent of several sub-modes but it's also sometimes
+  ;; abused as the function that chooses between those submodes.  They should
+  ;; call `conf-guess-mode' directly, but for historical reasons, we try to
+  ;; accommodate those misuses with this ugly hack.
   (if (not delay-mode-hooks)
-      ;; try to guess sub-mode of conf-mode based on buffer content
-      (let ((unix 0) (win 0) (equal 0) (colon 0) (space 0) (jp 0))
-	(save-excursion
-	  (goto-char (point-min))
-	  (while (not (eobp))
-	    (skip-chars-forward " \t\f")
-	    (cond ((eq (char-after) ?\#) (setq unix (1+ unix)))
-		  ((eq (char-after) ?\;) (setq win (1+ win)))
-		  ((eq (char-after) ?\[))	; nop
-		  ((eolp))			; nop
-		  ((eq (char-after) ?}))	; nop
-		  ;; recognize at most double spaces within names
-		  ((looking-at "[^ \t\n=:]+\\(?:  ?[^ \t\n=:]+\\)*[ \t]*[=:]")
-		   (if (eq (char-before (match-end 0)) ?=)
-		       (setq equal (1+ equal))
-		     (setq colon (1+ colon))))
-		  ((looking-at "/[/*]") (setq jp (1+ jp)))
-		  ((looking-at ".*{"))		; nop
-		  ((setq space (1+ space))))
-	    (forward-line)))
-	(cond
-         ((> jp (max unix win 3)) (conf-javaprop-mode))
-         ((> colon (max equal space)) (conf-colon-mode))
-         ((> space (max equal colon)) (conf-space-mode))
-         ((or (> win unix) (and (= win unix) (eq system-type 'windows-nt)))
-          (conf-windows-mode))
-         (t (conf-unix-mode))))
-
-    (kill-all-local-variables)
-    (use-local-map conf-mode-map)
-    (setq major-mode 'conf-mode
-	  mode-name "Conf[?]")
+      ;; Try to guess sub-mode of conf-mode based on buffer content.
+      (conf-guess-mode)
     (set (make-local-variable 'font-lock-defaults)
          '(conf-font-lock-keywords nil t nil nil))
     ;; Let newcomment.el decide this for itself.
@@ -438,8 +435,7 @@ conf-mode
 	    ;; [section]
 	    (nil "^[ \t]*\\[[ \t]*\\(.+\\)[ \t]*\\]" 1)
 	    ;; section { ... }
-	    (nil "^[ \t]*\\([^=:{} \t\n][^=:{}\n]+\\)[ \t\n]*{" 1)))
-    (run-mode-hooks 'conf-mode-hook)))
+	    (nil "^[ \t]*\\([^=:{} \t\n][^=:{}\n]+\\)[ \t\n]*{" 1)))))
 
 (defun conf-mode-initialize (comment &optional font-lock)
   "Initializations for sub-modes of `conf-mode'.






^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-18 23:31                                       ` Stefan Monnier
@ 2020-02-19  0:49                                         ` Juri Linkov
  2020-02-19 13:20                                           ` Stefan Monnier
  2020-03-24 21:37                                         ` Juri Linkov
  1 sibling, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-02-19  0:49 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

>> That's kinda hard if you want to use define-derived-mode and we do: when
>> we call `conf-foo-mode` the first things it does is: bind
>> `delay-mode-hooks` and call the parent (`conf-mode`), so the only
>> difference between this call to the parent and a direct call to the
>> generic entry point is the binding of `delay-mode-hooks`.
>
> IOW, I think we should start with something like the patch below which
> makes `conf-guess-mode` available, after which we can start fixing the
> various callers to call `conf-guess-mode` instead.

I tested this with additional patch that replaces `conf-mode` calls with
`conf-guess-mode`, and see that syntax font-lock now is fixed in diff-mode
on some conf files (not tested on all possible conf submodes).

diff --git a/lisp/files.el b/lisp/files.el
index 683f4a8ce7..3e1cf5e526 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2813,7 +2813,7 @@ auto-mode-alist
      ("/config\\.\\(?:bat\\|log\\)\\'" . fundamental-mode)
      ("/\\.\\(authinfo\\|netrc\\)\\'" . authinfo-mode)
      ;; Windows candidates may be opened case sensitively on Unix
-     ("\\.\\(?:[iI][nN][iI]\\|[lL][sS][tT]\\|[rR][eE][gG]\\|[sS][yY][sS]\\)\\'" . conf-mode)
+     ("\\.\\(?:[iI][nN][iI]\\|[lL][sS][tT]\\|[rR][eE][gG]\\|[sS][yY][sS]\\)\\'" . conf-guess-mode)
      ("\\.la\\'" . conf-unix-mode)
      ("\\.ppd\\'" . conf-ppd-mode)
      ("java.+\\.conf\\'" . conf-javaprop-mode)
@@ -2822,15 +2822,15 @@ auto-mode-alist
      ("\\.desktop\\'" . conf-desktop-mode)
      ("/\\.redshift.conf\\'" . conf-windows-mode)
      ("\\`/etc/\\(?:DIR_COLORS\\|ethers\\|.?fstab\\|.*hosts\\|lesskey\\|login\\.?de\\(?:fs\\|vperm\\)\\|magic\\|mtab\\|pam\\.d/.*\\|permissions\\(?:\\.d/.+\\)?\\|protocols\\|rpc\\|services\\)\\'" . conf-space-mode)
-     ("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . conf-mode)
+     ("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . conf-guess-mode)
      ;; ChangeLog.old etc.  Other change-log-mode entries are above;
      ;; this has lower priority to avoid matching changelog.sgml etc.
      ("[cC]hange[lL]og[-.][-0-9a-z]+\\'" . change-log-mode)
      ;; either user's dot-files or under /etc or some such
-     ("/\\.?\\(?:gitconfig\\|gnokiirc\\|hgrc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . conf-mode)
+     ("/\\.?\\(?:gitconfig\\|gnokiirc\\|hgrc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . conf-guess-mode)
      ;; alas not all ~/.*rc files are like this
-     ("/\\.\\(?:asound\\|enigma\\|fetchmail\\|gltron\\|gtk\\|hxplayer\\|mairix\\|mbsync\\|msmtp\\|net\\|neverball\\|nvidia-settings-\\|offlineimap\\|qt/.+\\|realplayer\\|reportbug\\|rtorrent\\.\\|screen\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-mode)
-     ("/\\.\\(?:gdbtkinit\\|grip\\|mpdconf\\|notmuch-config\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . conf-mode)
+     ("/\\.\\(?:asound\\|enigma\\|fetchmail\\|gltron\\|gtk\\|hxplayer\\|mairix\\|mbsync\\|msmtp\\|net\\|neverball\\|nvidia-settings-\\|offlineimap\\|qt/.+\\|realplayer\\|reportbug\\|rtorrent\\.\\|screen\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-guess-mode)
+     ("/\\.\\(?:gdbtkinit\\|grip\\|mpdconf\\|notmuch-config\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . conf-guess-mode)
      ("/\\.?X\\(?:default\\|resource\\|re\\)s\\>" . conf-xdefaults-mode)
      ("/X11.+app-defaults/\\|\\.ad\\'" . conf-xdefaults-mode)
      ("/X11.+locale/.+/Compose\\'" . conf-colon-mode)
@@ -2920,7 +2920,7 @@ conf-mode-maybe
 	  (goto-char (point-min))
 	  (looking-at "<\\?xml \\|<!-- \\|<!DOCTYPE ")))
       (xml-mode)
-    (conf-mode)))
+    (conf-guess-mode)))
 
 (defvar interpreter-mode-alist
   ;; Note: The entries for the modes defined in cc-mode.el (awk-mode





^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-19  0:49                                         ` Juri Linkov
@ 2020-02-19 13:20                                           ` Stefan Monnier
  2020-02-20  0:58                                             ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-02-19 13:20 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> I tested this with additional patch that replaces `conf-mode` calls with
> `conf-guess-mode`, and see that syntax font-lock now is fixed in diff-mode
> on some conf files (not tested on all possible conf submodes).

This said.  Using delay-mode-hooks in the diff-syntax driver is an ugly
hack and is the real source of the problem, so splitting conf-mode into
two is basically a way to work around the breakage introduced by the hack.


        Stefan


> diff --git a/lisp/files.el b/lisp/files.el
> index 683f4a8ce7..3e1cf5e526 100644
> --- a/lisp/files.el
> +++ b/lisp/files.el
> @@ -2813,7 +2813,7 @@ auto-mode-alist
>       ("/config\\.\\(?:bat\\|log\\)\\'" . fundamental-mode)
>       ("/\\.\\(authinfo\\|netrc\\)\\'" . authinfo-mode)
>       ;; Windows candidates may be opened case sensitively on Unix
> -     ("\\.\\(?:[iI][nN][iI]\\|[lL][sS][tT]\\|[rR][eE][gG]\\|[sS][yY][sS]\\)\\'" . conf-mode)
> +     ("\\.\\(?:[iI][nN][iI]\\|[lL][sS][tT]\\|[rR][eE][gG]\\|[sS][yY][sS]\\)\\'" . conf-guess-mode)
>       ("\\.la\\'" . conf-unix-mode)
>       ("\\.ppd\\'" . conf-ppd-mode)
>       ("java.+\\.conf\\'" . conf-javaprop-mode)
> @@ -2822,15 +2822,15 @@ auto-mode-alist
>       ("\\.desktop\\'" . conf-desktop-mode)
>       ("/\\.redshift.conf\\'" . conf-windows-mode)
>       ("\\`/etc/\\(?:DIR_COLORS\\|ethers\\|.?fstab\\|.*hosts\\|lesskey\\|login\\.?de\\(?:fs\\|vperm\\)\\|magic\\|mtab\\|pam\\.d/.*\\|permissions\\(?:\\.d/.+\\)?\\|protocols\\|rpc\\|services\\)\\'" . conf-space-mode)
> -     ("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . conf-mode)
> +     ("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . conf-guess-mode)
>       ;; ChangeLog.old etc.  Other change-log-mode entries are above;
>       ;; this has lower priority to avoid matching changelog.sgml etc.
>       ("[cC]hange[lL]og[-.][-0-9a-z]+\\'" . change-log-mode)
>       ;; either user's dot-files or under /etc or some such
> -     ("/\\.?\\(?:gitconfig\\|gnokiirc\\|hgrc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . conf-mode)
> +     ("/\\.?\\(?:gitconfig\\|gnokiirc\\|hgrc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . conf-guess-mode)
>       ;; alas not all ~/.*rc files are like this
> -     ("/\\.\\(?:asound\\|enigma\\|fetchmail\\|gltron\\|gtk\\|hxplayer\\|mairix\\|mbsync\\|msmtp\\|net\\|neverball\\|nvidia-settings-\\|offlineimap\\|qt/.+\\|realplayer\\|reportbug\\|rtorrent\\.\\|screen\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-mode)
> -     ("/\\.\\(?:gdbtkinit\\|grip\\|mpdconf\\|notmuch-config\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . conf-mode)
> +     ("/\\.\\(?:asound\\|enigma\\|fetchmail\\|gltron\\|gtk\\|hxplayer\\|mairix\\|mbsync\\|msmtp\\|net\\|neverball\\|nvidia-settings-\\|offlineimap\\|qt/.+\\|realplayer\\|reportbug\\|rtorrent\\.\\|screen\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-guess-mode)
> +     ("/\\.\\(?:gdbtkinit\\|grip\\|mpdconf\\|notmuch-config\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . conf-guess-mode)
>       ("/\\.?X\\(?:default\\|resource\\|re\\)s\\>" . conf-xdefaults-mode)
>       ("/X11.+app-defaults/\\|\\.ad\\'" . conf-xdefaults-mode)
>       ("/X11.+locale/.+/Compose\\'" . conf-colon-mode)
> @@ -2920,7 +2920,7 @@ conf-mode-maybe
>  	  (goto-char (point-min))
>  	  (looking-at "<\\?xml \\|<!-- \\|<!DOCTYPE ")))
>        (xml-mode)
> -    (conf-mode)))
> +    (conf-guess-mode)))
>  
>  (defvar interpreter-mode-alist
>    ;; Note: The entries for the modes defined in cc-mode.el (awk-mode






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-19 13:20                                           ` Stefan Monnier
@ 2020-02-20  0:58                                             ` Juri Linkov
  0 siblings, 0 replies; 52+ messages in thread
From: Juri Linkov @ 2020-02-20  0:58 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

>> I tested this with additional patch that replaces `conf-mode` calls with
>> `conf-guess-mode`, and see that syntax font-lock now is fixed in diff-mode
>> on some conf files (not tested on all possible conf submodes).
>
> This said.  Using delay-mode-hooks in the diff-syntax driver is an ugly
> hack and is the real source of the problem, so splitting conf-mode into
> two is basically a way to work around the breakage introduced by the hack.

Indeed, but it seems it's too late to redesign this in the release
branch.  So unfontified conf-mode files in diff hunks is a trade-off
for not breaking the release.

As for changes in master, I tried something like this to use in
diff-syntax-fontify-props instead of direct set-auto-mode call:

(let ((buffer (make-indirect-buffer
               (current-buffer)
               (generate-new-buffer-name (buffer-name)))))
  (funcall
   (unwind-protect
       (with-current-buffer buffer
         (let ((buffer-file-name "/tmp/foo.el"))
           (set-auto-mode)
           major-mode))
     (kill-buffer buffer))))

It calls set-auto-mode in a temporary buffer.

Do you think this is the right direction?





^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-02-18 23:31                                       ` Stefan Monnier
  2020-02-19  0:49                                         ` Juri Linkov
@ 2020-03-24 21:37                                         ` Juri Linkov
  2020-03-24 22:29                                           ` Stefan Monnier
  1 sibling, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-03-24 21:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

> IOW, I think we should start with something like the patch below which
> makes `conf-guess-mode` available, after which we can start fixing the
> various callers to call `conf-guess-mode` instead.

Currently `conf-mode` is broken in master: visiting a conf file doesn't
activate `conf-mode`.  I don't know the right way to fix this, but this
patch demonstrates what basically needed to do to fix it, and it seems
something like this wrapper could be added:

(defun conf-guess-mode ()
  (funcall (conf--guess-mode)))

diff --git a/lisp/files.el b/lisp/files.el
index 8ce0187f5b..f0aa3447ac 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -2813,7 +2813,7 @@ auto-mode-alist
      ("/config\\.\\(?:bat\\|log\\)\\'" . fundamental-mode)
      ("/\\.\\(authinfo\\|netrc\\)\\'" . authinfo-mode)
      ;; Windows candidates may be opened case sensitively on Unix
-     ("\\.\\(?:[iI][nN][iI]\\|[lL][sS][tT]\\|[rR][eE][gG]\\|[sS][yY][sS]\\)\\'" . conf-mode)
+     ("\\.\\(?:[iI][nN][iI]\\|[lL][sS][tT]\\|[rR][eE][gG]\\|[sS][yY][sS]\\)\\'" . (lambda () (funcall (conf--guess-mode))))
      ("\\.la\\'" . conf-unix-mode)
      ("\\.ppd\\'" . conf-ppd-mode)
      ("java.+\\.conf\\'" . conf-javaprop-mode)
@@ -2822,15 +2822,15 @@ auto-mode-alist
      ("\\.desktop\\'" . conf-desktop-mode)
      ("/\\.redshift.conf\\'" . conf-windows-mode)
      ("\\`/etc/\\(?:DIR_COLORS\\|ethers\\|.?fstab\\|.*hosts\\|lesskey\\|login\\.?de\\(?:fs\\|vperm\\)\\|magic\\|mtab\\|pam\\.d/.*\\|permissions\\(?:\\.d/.+\\)?\\|protocols\\|rpc\\|services\\)\\'" . conf-space-mode)
-     ("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . conf-mode)
+     ("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . (lambda () (funcall (conf--guess-mode))))
      ;; ChangeLog.old etc.  Other change-log-mode entries are above;
      ;; this has lower priority to avoid matching changelog.sgml etc.
      ("[cC]hange[lL]og[-.][-0-9a-z]+\\'" . change-log-mode)
      ;; either user's dot-files or under /etc or some such
-     ("/\\.?\\(?:gitconfig\\|gnokiirc\\|hgrc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . conf-mode)
+     ("/\\.?\\(?:gitconfig\\|gnokiirc\\|hgrc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . (lambda () (funcall (conf--guess-mode))))
      ;; alas not all ~/.*rc files are like this
-     ("/\\.\\(?:asound\\|enigma\\|fetchmail\\|gltron\\|gtk\\|hxplayer\\|mairix\\|mbsync\\|msmtp\\|net\\|neverball\\|nvidia-settings-\\|offlineimap\\|qt/.+\\|realplayer\\|reportbug\\|rtorrent\\.\\|screen\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-mode)
-     ("/\\.\\(?:gdbtkinit\\|grip\\|mpdconf\\|notmuch-config\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . conf-mode)
+     ("/\\.\\(?:asound\\|enigma\\|fetchmail\\|gltron\\|gtk\\|hxplayer\\|mairix\\|mbsync\\|msmtp\\|net\\|neverball\\|nvidia-settings-\\|offlineimap\\|qt/.+\\|realplayer\\|reportbug\\|rtorrent\\.\\|screen\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . (lambda () (funcall (conf--guess-mode))))
+     ("/\\.\\(?:gdbtkinit\\|grip\\|mpdconf\\|notmuch-config\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . (lambda () (funcall (conf--guess-mode))))
      ("/\\.?X\\(?:default\\|resource\\|re\\)s\\>" . conf-xdefaults-mode)
      ("/X11.+app-defaults/\\|\\.ad\\'" . conf-xdefaults-mode)
      ("/X11.+locale/.+/Compose\\'" . conf-colon-mode)
@@ -2920,7 +2920,7 @@ conf-mode-maybe
 	  (goto-char (point-min))
 	  (looking-at "<\\?xml \\|<!-- \\|<!DOCTYPE ")))
       (xml-mode)
-    (conf-mode)))
+    (funcall (conf--guess-mode))))
 
 (defvar interpreter-mode-alist
   ;; Note: The entries for the modes defined in cc-mode.el (awk-mode





^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-03-24 21:37                                         ` Juri Linkov
@ 2020-03-24 22:29                                           ` Stefan Monnier
  2020-03-25 20:39                                             ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-03-24 22:29 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> Currently `conf-mode` is broken in master: visiting a conf file doesn't
> activate `conf-mode`.

In my tests it does, but it only activates the parent-mode and not the
specific submode applicable to the file, indeed.

> I don't know the right way to fix this, but this patch demonstrates
> what basically needed to do to fix it, and it seems something like
> this wrapper could be added:
>
> (defun conf-guess-mode ()
>   (funcall (conf--guess-mode)))

That shouldn't be needed!
[ I.e. the right fix should arrange for that not to be necessary.
  I'm looking into it, thanks.  ]


        Stefan






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-03-24 22:29                                           ` Stefan Monnier
@ 2020-03-25 20:39                                             ` Juri Linkov
  2020-03-25 21:13                                               ` Stefan Monnier
  0 siblings, 1 reply; 52+ messages in thread
From: Juri Linkov @ 2020-03-25 20:39 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

>> (defun conf-guess-mode ()
>>   (funcall (conf--guess-mode)))
>
> That shouldn't be needed!
> [ I.e. the right fix should arrange for that not to be necessary.
>   I'm looking into it, thanks.  ]

BTW, I noticed another problem related to diff-syntax-fontify:
when diff-font-lock-syntax is customized to 'hunk-also',
and a patch displayed by Gnus contains a truncated
local variables list, e.g. only the first line

 ;; Local Variables:

is presented in diff context without the terminating
"End:" then opening such attachment patch raises the error:

   "Local variables list is not properly terminated"

Not sure if this is the right way to fix this, but it works:

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 8171a58515..96baea8526 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2724,7 +2724,7 @@ diff-syntax-fontify-props
           (buffer-file-name file))
       ;; Don't run hooks that might assume buffer-file-name
       ;; really associates buffer with a file (bug#39190).
-      (delay-mode-hooks (set-auto-mode))
+      (delay-mode-hooks (ignore-errors (set-auto-mode)))
       ;; FIXME: Is this really worth the trouble?
       (when (and (fboundp 'generic-mode-find-file-hook)
                  (memq #'generic-mode-find-file-hook





^ permalink raw reply related	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-03-25 20:39                                             ` Juri Linkov
@ 2020-03-25 21:13                                               ` Stefan Monnier
  2020-03-25 21:48                                                 ` Juri Linkov
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Monnier @ 2020-03-25 21:13 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 39190, Felician Nemeth

> is presented in diff context without the terminating
> "End:" then opening such attachment patch raises the error:
>
>    "Local variables list is not properly terminated"

Really?  AFAICT the code does:

		  (unless (let ((case-fold-search t))
			    (re-search-forward
			     (concat prefix "[ \t]*End:[ \t]*" suffix)
			     nil t))
		    ;; This used to be an error, but really all it means is
		    ;; that this may simply not be a local-variables section,
		    ;; so just ignore it.
		    (message "Local variables list is not properly terminated"))

so it shouldn't signal an error but just emit a message.

> Not sure if this is the right way to fix this, but it works:

I think we should try and arrange for errors to really be "not normal",
and then use `with-demoted-errors`, yes.

But w.r.t file-local variables and diff-hunk, I think obeying "file-local
variables" doesn't make much sense when we only have a hunk to go on
since it's more common for the hunk not to include the actual file-local
vars, so if we find something it's likely to be a false-positive.


        Stefan


> diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
> index 8171a58515..96baea8526 100644
> --- a/lisp/vc/diff-mode.el
> +++ b/lisp/vc/diff-mode.el
> @@ -2724,7 +2724,7 @@ diff-syntax-fontify-props
>            (buffer-file-name file))
>        ;; Don't run hooks that might assume buffer-file-name
>        ;; really associates buffer with a file (bug#39190).
> -      (delay-mode-hooks (set-auto-mode))
> +      (delay-mode-hooks (ignore-errors (set-auto-mode)))
>        ;; FIXME: Is this really worth the trouble?
>        (when (and (fboundp 'generic-mode-find-file-hook)
>                   (memq #'generic-mode-find-file-hook






^ permalink raw reply	[flat|nested] 52+ messages in thread

* bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props)
  2020-03-25 21:13                                               ` Stefan Monnier
@ 2020-03-25 21:48                                                 ` Juri Linkov
  0 siblings, 0 replies; 52+ messages in thread
From: Juri Linkov @ 2020-03-25 21:48 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 39190, Felician Nemeth

>> is presented in diff context without the terminating
>> "End:" then opening such attachment patch raises the error:
>>
>>    "Local variables list is not properly terminated"
>
> Really?  AFAICT the code does:
>
> 		  (unless (let ((case-fold-search t))
> 			    (re-search-forward
> 			     (concat prefix "[ \t]*End:[ \t]*" suffix)
> 			     nil t))
> 		    ;; This used to be an error, but really all it means is
> 		    ;; that this may simply not be a local-variables section,
> 		    ;; so just ignore it.
> 		    (message "Local variables list is not properly terminated"))
>
> so it shouldn't signal an error but just emit a message.

Sorry, actually this is what is displayed in the echo area after I added
ignore-errors.  But before adding ignore-errors, there was such backtrace:

Debugger entered--Lisp error: (error "Malformed local variable line: \"Local Variables:\"")
  signal(error ("Malformed local variable line: \"Local Variables:\""))
  error("Malformed local variable line: %S" "Local Variables:")
  hack-local-variables(t)
  set-auto-mode()
  (let ((delay-mode-hooks t)) (set-auto-mode))
  (progn (make-local-variable 'delay-mode-hooks) (let ((delay-mode-hooks t)) (set-auto-mode)))
  diff-syntax-fontify-props(#("a/lisp/dired-aux.el" ...
  diff-syntax-fontify-hunk(136 1334 t)
  diff-syntax-fontify(136 1334)
  diff--iterate-hunks(3750 #f(compiled-function (beg end) #<bytecode 0x877598e526a1ebd>))
  diff--font-lock-syntax(3750)
  font-lock-fontify-keywords-region(1 3750 nil)
  font-lock-default-fontify-region(1 3750 nil)
  font-lock-fontify-region(1 3750)
  font-lock-ensure()
  mm-display-inline-fontify(...
  mm-display-patch-inline(...
  mm-display-inline(...
  gnus-mime-display-single(...
  gnus-mime-display-part(...
  gnus-mime-display-mixed(...
  gnus-mime-display-part(...
  gnus-display-mime()
  gnus-article-prepare-display()
  gnus-article-prepare(165466 nil)
  gnus-summary-display-article(165466 nil)
  gnus-summary-select-article(nil nil pseudo)
  gnus-summary-scroll-up(1)
  funcall-interactively(gnus-summary-scroll-up 1)
  call-interactively(gnus-summary-scroll-up nil nil)
  command-execute(gnus-summary-scroll-up)

>> Not sure if this is the right way to fix this, but it works:
>
> I think we should try and arrange for errors to really be "not normal",
> and then use `with-demoted-errors`, yes.
>
> But w.r.t file-local variables and diff-hunk, I think obeying "file-local
> variables" doesn't make much sense when we only have a hunk to go on
> since it's more common for the hunk not to include the actual file-local
> vars, so if we find something it's likely to be a false-positive.

I'll try to set enable-local-variables to nil in case of HUNK-ONLY.





^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2020-03-25 21:48 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-19 11:14 bug#39190: 28.0.50; two buffers with same buffer-file-name (diff-syntax-fontify-props) Felician Nemeth
2020-01-20 22:56 ` Juri Linkov
2020-01-20 23:34   ` Stefan Monnier
2020-01-24  0:13     ` Juri Linkov
2020-01-24 14:18       ` Stefan Monnier
2020-01-28  0:01         ` Juri Linkov
2020-01-28  1:30           ` Stefan Monnier
2020-01-28  3:32             ` Eli Zaretskii
2020-01-28 13:58               ` Stefan Monnier
2020-01-28 14:54                 ` Dmitry Gutov
2020-01-28 22:53                   ` Juri Linkov
2020-01-28 17:54                 ` Eli Zaretskii
2020-01-28 20:12                   ` Stefan Monnier
2020-01-28 20:23                     ` Eli Zaretskii
2020-01-28 23:17                       ` Stefan Monnier
2020-01-29 17:13                         ` Eli Zaretskii
2020-01-29 21:33                           ` Stefan Monnier
2020-01-30 14:17                             ` Eli Zaretskii
2020-01-30 14:34                               ` Stefan Monnier
2020-01-30 22:50             ` Juri Linkov
2020-01-30 23:09               ` Stefan Monnier
2020-01-30 23:31               ` Dmitry Gutov
2020-01-26 19:34       ` Felician Nemeth
2020-01-28  0:05         ` Juri Linkov
2020-01-28 17:18           ` Felician Nemeth
2020-01-29 23:07             ` Juri Linkov
2020-01-30 19:48               ` Felician Nemeth
2020-01-30 22:45                 ` Juri Linkov
2020-02-02  9:42                   ` Felician Nemeth
2020-02-02 13:50                     ` Stefan Monnier
2020-02-02 23:41                       ` Juri Linkov
2020-02-03 13:14                         ` Dmitry Gutov
2020-02-03 22:44                           ` Juri Linkov
2020-02-04 13:08                             ` Dmitry Gutov
2020-02-03 22:45                     ` Juri Linkov
2020-02-04 13:36                       ` Stefan Monnier
2020-02-04 23:20                         ` Juri Linkov
2020-02-05 22:39                           ` Juri Linkov
2020-02-09 16:06                             ` Felician Nemeth
2020-02-18  0:06                               ` Juri Linkov
2020-02-18 13:33                                 ` Stefan Monnier
2020-02-18 22:53                                   ` Juri Linkov
2020-02-18 23:07                                     ` Stefan Monnier
2020-02-18 23:31                                       ` Stefan Monnier
2020-02-19  0:49                                         ` Juri Linkov
2020-02-19 13:20                                           ` Stefan Monnier
2020-02-20  0:58                                             ` Juri Linkov
2020-03-24 21:37                                         ` Juri Linkov
2020-03-24 22:29                                           ` Stefan Monnier
2020-03-25 20:39                                             ` Juri Linkov
2020-03-25 21:13                                               ` Stefan Monnier
2020-03-25 21:48                                                 ` Juri Linkov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).