Subject: Re: bug#32090: 26.1; connection-local-variables do not match as described

From: Michael Albinus <[email-masked]>
Date: Sun, 08 Jul 2018 11:46:55 +0200

Christopher Cooper <[email-masked]> writes:

Hi Christopher,

> According to the docstring for 'connection-local-criteria-alist',
> "CRITERIA is a plist identifying a connection and the application
> using this connection. ... All properties are optional; if
> CRITERIA is nil, it always applies."
>
> This does not appear to be true. In fact, this is plainly evident by
> simple visual inspection of 'connection-local-get-profiles'. Only
> :application seems to be optional.
>
> Reproduction is quite simple. Run emacs -Q and eval the following elisp:
>
> (defvar test--var nil)
> (setf enable-connection-local-variables t)
> (connection-local-set-profile-variables 'test-profile '((test--var . t)))
> (connection-local-set-profiles nil 'test-profile)
>
> Now open any TRAMP connection. Switch to the TRAMP buffer (where
> connection-local-variables should have taken effect) and do
> M-: test--var. The result is nil.
>
> If you conduct the same test, but specify the :protocol, :user, and
> :machine as part of the criteria in the 'connection-local-set-profiles'
> call, test--var will evaluate to t, which is correct.
>
> At best this is a case of misleading documentation, and at worst it is a
> feature that never got implemented. Connection-local variables would be
> very useful to me if they worked as described. I am glad to provide more
> info or help in any capacity.

It is not misleading documentation. It is the Tramp implementation, how
connection-local variables are set. In
tramp-set-connection-local-variables, you'll see

--8<---------------cut here---------------start------------->8---
(tramp-compat-funcall
 'hack-connection-local-variables-apply
 `(:application tramp
   :protocol    ,(tramp-file-name-method vec)
   :user        ,(tramp-file-name-user-domain vec)
   :machine     ,(tramp-file-name-host-port vec)))))
--8<---------------cut here---------------end--------------->8---

That means, the Tramp implementation requires :application to be 'tramp
or nil, *and* it requires setting of :protocol, :user and :machine in
your criteria, which match the respective remote file name.

Connection-lcal variables in general work as expected. Eval in the
*scratch* buffer:

--8<---------------cut here---------------start------------->8---
(defvar test--var nil)
(setf enable-connection-local-variables t)
(connection-local-set-profile-variables 'test-profile '((test--var . t)))
(connection-local-set-profiles nil 'test-profile)

;; Check initial value.
(describe-variable 'test--var)

;; Set connection local variables for a random criteria.
(hack-connection-local-variables-apply '(:application foo))

;; Check the value, again.
(describe-variable 'test--var)
--8<---------------cut here---------------end--------------->8---

In fact, properties in criteria are optional only in case the
application allows this in its `hack-connection-local-variables-apply'
call, except for :application. This must either match, or be nil.

The Tramp manual gives you an example how to use connection-local
variables fo Tramp itself, see (info "(tramp) Remote processes") . I
agree, it should be more verbose to explain, how a criteria for Tramp
must look like. Will add it.

Best regards, Michael.