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

From: Christopher Cooper <[email-masked]>
Date: Sun, 8 Jul 2018 09:09:59 -0400

Thank you for the speedy response!

On Sun, Jul 8, 2018 at 5:46 AM, Michael Albinus <[email-masked]> wrote:
> 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.

This makes sense, except that I'm still confused on why :application
can be nil but :protocol, :user, and :machine cannot be.

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

This works, but only because the criteria passed to
'hack-connection-local-variables-apply' does not supply a :machine,
:user, or :host.

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

I think I am beginning to understand... it is essentially up to the
application to make the other properties optional. Obviously it
wouldn't make sense for the application to make :application optional,
so that is the only one that is optional everywhere.

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

The Tramp info page seems pretty fine to me. The real issue is in two places:

(info "(elisp) Connection Local Variables"):
> -- Function: connection-local-set-profiles criteria &rest profiles
>     ...
>     All properties are optional; if
>     CRITERIA is ‘nil’, it always applies.

But as determined above, if CRITERIA is 'nil', it does not always
apply. It is up to the application to provide this feature, and Tramp
does not.
In fact, there is even an example showing this feature, which appears
be plain wrong:

>     If CRITERIA is ‘nil’, it applies for all remote connections.
>     Therefore, the example above would be equivalent to
>
>          (connection-local-set-profiles
>            '(:application 'tramp :protocol "ssh" :machine "localhost")
>            'remote-bash)
>
>          (connection-local-set-profiles
>            '(:application 'tramp :protocol "sudo"
>              :user "root" :machine "localhost")
>            'remote-ksh)
>
>          (connection-local-set-profiles
>            nil 'remote-null-device)

At least with current Tramp, the 'remote-null-device profile will
never apply, since it does not provide the properties needed by Tramp.
This also means that this example is not equivalent to the above
example as stated.

The other place of confusion was the docstring for
'connection-local-criteria-alist' that I mentioned initially.

I think ultimately, it comes down to a confusion over what "optional"
means. I took it to mean: "It this property is provided, it will be
checked when matching. If not, we don't care about the value of this
property." And, as I stated earlier, I don't understand how the
sentence "If CRITERIA is 'nil', it always applies." is try in any
sense of those words. If the feature is working as intended, those are
the worst offenders as far as confusing documentation.

Once again, I appreciate this feature and your explanation here. I
hope this is helpful in clarifying the documentation.

Christopher