aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2017-02-19 17:14:35 +0100
committerMichael Albinus2017-02-19 17:14:35 +0100
commit143bc75c414434badcb324db056ad37c15893bd9 (patch)
treeedb4c926bd940e39ec9a88ea13324d55f925223c
parentb6a1a74522120979fe1a63b2d5517a490ee572b0 (diff)
downloademacs-143bc75c414434badcb324db056ad37c15893bd9.tar.gz
emacs-143bc75c414434badcb324db056ad37c15893bd9.zip
Rework connection local variables
For connection local variables interface, `class' is renamed to `profile'. All arguments `criteria' are a plist now. * doc/lispref/variables.texi (Connection Local Variables): Rewrite. * lisp/files-x.el (connection-local-profile-alist): Rename from `connection-local-class-alist'. Adapt docstring. (connection-local-criteria-alist): Adapt docstring. (connection-local-normalize-criteria): New defun. (connection-local-get-profiles): Rename from `connection-local-get-classes'. Rewrite. (connection-local-set-profiles): Rename from `connection-local-set-classes'. Rewrite. (connection-local-get-profile-variables): Rename from `connection-local-get-class-variables'. Rewrite. (connection-local-set-profile-variables): Rename from `connection-local-set-class-variables'. Rewrite. (hack-connection-local-variables) (hack-connection-local-variables-apply)): Rewrite. (with-connection-local-profiles): Rename from `ith-connection-local-classes'. Rewrite. * lisp/net/tramp.el (tramp-set-connection-local-variables): Compute criteria. * lisp/net/tramp-cmds.el (tramp-bug): Use `connection-local-profile-alist'. * test/lisp/files-x-tests.el (files-x-test--variables1) (files-x-test--variables2, files-x-test--variables3) (files-x-test--variables4, files-x-test--criteria1) (files-x-test--criteria2): Make them a defconst. (files-x-test--application) (files-x-test--another-application, files-x-test--protocol) (files-x-test--user, files-x-test--machine): New defconst. (files-x-test--criteria): New defvar. (files-x-test--criteria3): Remove. (files-x-test-connection-local-set-profile-variables): Rename from `files-x-test-connection-local-set-class-variables'. Rewrite. (files-x-test-connection-local-set-profiles): Rename from `files-x-test-connection-local-set-classes'. Rewrite. (files-x-test-hack-connection-local-variables-apply) Rewrite. (files-x-test-with-connection-local-profiles): Rename from `files-x-test-with-connection-local-classes'. Rewrite.
-rw-r--r--doc/lispref/variables.texi152
-rw-r--r--lisp/files-x.el167
-rw-r--r--lisp/net/tramp-cmds.el2
-rw-r--r--lisp/net/tramp.el12
-rw-r--r--test/lisp/files-x-tests.el214
5 files changed, 301 insertions, 246 deletions
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 8a61018a612..2818ea067d2 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -1979,24 +1979,21 @@ still respecting file-local variables (@pxref{File Local Variables}).
1979@section Connection Local Variables 1979@section Connection Local Variables
1980@cindex connection local variables 1980@cindex connection local variables
1981 1981
1982 Connection-local variables provide a general mechanism for 1982 Connection-local variables provide a general mechanism for different
1983different variable settings in buffers with a remote default 1983variable settings in buffers with a remote connection. They are bound
1984directory. They are bound and set depending on the remote connection 1984and set depending on the remote connection a buffer is dedicated to.
1985a buffer is dedicated to. Per default, they are set in all process 1985
1986buffers for a remote connection, but they could be applied also in 1986@defun connection-local-set-profile-variables profile variables
1987other buffers with a remote directory. 1987This function defines a set of variable settings for the connection
1988 1988@var{profile}, which is a symbol. You can later assign the connection
1989@defun connection-local-set-class-variables class variables 1989profile to one or more remote connections, and Emacs will apply those
1990This function defines a set of variable settings for the named 1990variable settings to all process buffers for those connections. The
1991@var{class}, which is a symbol. You can later assign the class to one 1991list in @var{variables} is an alist of the form
1992or more remote connections, and Emacs will apply those variable 1992@code{(@var{name}@tie{}.@tie{}@var{value})}. Example:
1993settings to all process buffers for those connections. The list in
1994@var{variables} is an alist of the form @code{(@var{name}
1995. @var{value})}. Example:
1996 1993
1997@example 1994@example
1998@group 1995@group
1999(connection-local-set-class-variables 1996(connection-local-set-profile-variables
2000 'remote-bash 1997 'remote-bash
2001 '((shell-file-name . "/bin/bash") 1998 '((shell-file-name . "/bin/bash")
2002 (shell-command-switch . "-c") 1999 (shell-command-switch . "-c")
@@ -2005,7 +2002,7 @@ settings to all process buffers for those connections. The list in
2005@end group 2002@end group
2006 2003
2007@group 2004@group
2008(connection-local-set-class-variables 2005(connection-local-set-profile-variables
2009 'remote-ksh 2006 'remote-ksh
2010 '((shell-file-name . "/bin/ksh") 2007 '((shell-file-name . "/bin/ksh")
2011 (shell-command-switch . "-c") 2008 (shell-command-switch . "-c")
@@ -2014,38 +2011,41 @@ settings to all process buffers for those connections. The list in
2014@end group 2011@end group
2015 2012
2016@group 2013@group
2017(connection-local-set-class-variables 2014(connection-local-set-profile-variables
2018 'remote-null-device 2015 'remote-null-device
2019 '((null-device . "/dev/null"))) 2016 '((null-device . "/dev/null")))
2020@end group 2017@end group
2021@end example 2018@end example
2022@end defun 2019@end defun
2023 2020
2024@defvar connection-local-class-alist 2021@defvar connection-local-profile-alist
2025This alist holds the class symbols and the associated variable 2022This alist holds the connection profile symbols and the associated
2026settings. It is updated by @code{connection-local-set-class-variables}. 2023variable settings. It is updated by
2024@code{connection-local-set-profile-variables}.
2027@end defvar 2025@end defvar
2028 2026
2029@defun connection-local-set-classes criteria &rest classes 2027@defun connection-local-set-profiles criteria &rest profiles
2030This function assigns @var{classes}, which are symbols, to all remote 2028This function assigns @var{profiles}, which are symbols, to all remote
2031connections identified by @var{criteria}. @var{criteria} is either a 2029connections identified by @var{criteria}. @var{criteria} is a plist
2032regular expression identifying a remote server, or a function with one 2030identifying a connection and the application using this connection.
2033argument @var{identification}, which must return non-nil when a remote 2031Property names might be @code{:application}, @code{:protocol},
2034server shall apply @var{classes} variables, or @code{nil}. 2032@code{:user} and @code{:machine}. The property value of
2035 2033@code{:application} is a symbol, all other property values are
2036If @var{criteria} is a regexp, is must match the result of 2034strings. All properties are optional; if @var{criteria} is nil, it
2037@code{(file-remote-p default-directory)} of a buffer in order to apply 2035always applies. Example:
2038the variables setting. Example:
2039 2036
2040@example 2037@example
2041@group 2038@group
2042(connection-local-set-classes 2039(connection-local-set-profiles
2043 "^/ssh:" 'remote-bash 'remote-null-device) 2040 '(:application 'tramp :protocol "ssh" :machine "localhost")
2041 'remote-bash 'remote-null-device)
2044@end group 2042@end group
2045 2043
2046@group 2044@group
2047(connection-local-set-classes 2045(connection-local-set-profiles
2048 "^/sudo:" 'remote-ksh 'remote-null-device) 2046 '(:application 'tramp :protocol "sudo"
2047 :user "root" :machine "localhost")
2048 'remote-ksh 'remote-null-device)
2049@end group 2049@end group
2050@end example 2050@end example
2051 2051
@@ -2053,82 +2053,80 @@ the variables setting. Example:
2053Therefore, the example above would be equivalent to 2053Therefore, the example above would be equivalent to
2054 2054
2055@example 2055@example
2056(connection-local-set-classes "^/ssh:" 'remote-bash)
2057(connection-local-set-classes "^/sudo:" 'remote-ksh)
2058(connection-local-set-classes nil 'remote-null-device)
2059@end example
2060
2061 If @var{criteria} is a lambda function it must accept one parameter,
2062the identification. The example above could be rewritten as
2063
2064@example
2065@group 2056@group
2066(connection-local-set-classes 2057(connection-local-set-profiles
2067 (lambda (identification) 2058 '(:application 'tramp :protocol "ssh" :machine "localhost")
2068 (string-equal (file-remote-p identification 'method) "ssh"))
2069 'remote-bash) 2059 'remote-bash)
2070@end group 2060@end group
2071 2061
2072@group 2062@group
2073(connection-local-set-classes 2063(connection-local-set-profiles
2074 (lambda (identification) 2064 '(:application 'tramp :protocol "sudo"
2075 (string-equal (file-remote-p identification 'method) "sudo")) 2065 :user "root" :machine "localhost")
2076 'remote-ksh) 2066 'remote-ksh)
2077@end group 2067@end group
2078 2068
2079@group 2069@group
2080(connection-local-set-classes 2070(connection-local-set-profiles
2081 (lambda (identification) t) 2071 nil 'remote-null-device)
2082 'remote-null-device)
2083@end group 2072@end group
2084@end example 2073@end example
2085 2074
2086 Thereafter, all the variable settings specified for @var{classes} 2075 Any connection profile of @var{profiles} must have been already
2087will be applied to any buffer with a matching remote directory, when 2076defined by @code{connection-local-set-profile-variables}.
2088activated by @code{hack-connection-local-variables-apply}. Any class
2089of @var{classes} must have been already defined by
2090@code{connection-local-set-class-variables}.
2091@end defun 2077@end defun
2092 2078
2093@defvar connection-local-criteria-alist 2079@defvar connection-local-criteria-alist
2094This alist contains remote server identifications and their assigned 2080This alist contains connection criteria and their assigned profile
2095class names. The function @code{connection-local-set-classes} updates 2081names. The function @code{connection-local-set-profiles} updates this
2096this list. 2082list.
2097@end defvar 2083@end defvar
2098 2084
2099@defun hack-connection-local-variables 2085@defun hack-connection-local-variables criteria
2100This function collects applicable connection-local variables in 2086This function collects applicable connection-local variables
2101@code{connection-local-variables-alist} that is local to the buffer, 2087associated with @var{criteria} in
2102without applying them. Whether a connection-local variable is 2088@code{connection-local-variables-alist}, without applying them.
2103applicable is specified by the remote identifier of a buffer, 2089Example:
2104evaluated by @code{(file-remote-p default-directory)}. 2090
2091@example
2092@group
2093(hack-connection-local-variables
2094 '(:application 'tramp :protocol "ssh" :machine "localhost"))
2095@end group
2096
2097@group
2098connection-local-variables-alist
2099 @result{} ((null-device . "/dev/null")
2100 (shell-login-switch . "-l")
2101 (shell-interactive-switch . "-i")
2102 (shell-command-switch . "-c")
2103 (shell-file-name . "/bin/bash"))
2104@end group
2105@end example
2105@end defun 2106@end defun
2106 2107
2107@defun hack-connection-local-variables-apply 2108@defun hack-connection-local-variables-apply criteria
2108This function looks for connection-local variables, and immediately 2109This function looks for connection-local variables according to
2109applies them in the current buffer. It is called per default for 2110@var{criteria}, and immediately applies them in the current buffer.
2110every process-buffer related to a remote connection. For other remote
2111buffers, it could be called by any mode.
2112@end defun 2111@end defun
2113 2112
2114@defmac with-connection-local-classes classes &rest body 2113@defmac with-connection-local-profiles profiles &rest body
2115All connection-local variables, which are specified by a class in 2114All connection-local variables, which are specified by a connection
2116@var{classes}, are applied. An implicit binding of the classes to the 2115profile in @var{profiles}, are applied.
2117remote connection is enabled.
2118 2116
2119After that, @var{body} is executed, and the connection-local variables 2117After that, @var{body} is executed, and the connection-local variables
2120are unwound. Example: 2118are unwound. Example:
2121 2119
2122@example 2120@example
2123@group 2121@group
2124(connection-local-set-class-variables 2122(connection-local-set-profile-variables
2125 'remote-perl 2123 'remote-perl
2126 '((perl-command-name . "/usr/local/bin/perl") 2124 '((perl-command-name . "/usr/local/bin/perl")
2127 (perl-command-switch . "-e %s"))) 2125 (perl-command-switch . "-e %s")))
2128@end group 2126@end group
2129 2127
2130@group 2128@group
2131(with-connection-local-classes '(remote-perl) 2129(with-connection-local-profiles '(remote-perl)
2132 do something useful) 2130 do something useful)
2133@end group 2131@end group
2134@end example 2132@end example
diff --git a/lisp/files-x.el b/lisp/files-x.el
index 2b4658f6429..a0cad708425 100644
--- a/lisp/files-x.el
+++ b/lisp/files-x.el
@@ -559,119 +559,132 @@ changed by the user.")
559(setq ignored-local-variables 559(setq ignored-local-variables
560 (cons 'connection-local-variables-alist ignored-local-variables)) 560 (cons 'connection-local-variables-alist ignored-local-variables))
561 561
562(defvar connection-local-class-alist '() 562(defvar connection-local-profile-alist '()
563 "Alist mapping connection-local variable classes (symbols) to variable lists. 563 "Alist mapping connection profiles to variable lists.
564Each element in this list has the form (CLASS VARIABLES). 564Each element in this list has the form (PROFILE VARIABLES).
565CLASS is the name of a variable class (a symbol). 565PROFILE is the name of a connection profile (a symbol).
566VARIABLES is a list that declares connection-local variables for 566VARIABLES is a list that declares connection-local variables for
567CLASS. An element in VARIABLES is an alist whose elements are of 567PROFILE. An element in VARIABLES is an alist whose elements are
568the form (VAR . VALUE).") 568of the form (VAR . VALUE).")
569 569
570(defvar connection-local-criteria-alist '() 570(defvar connection-local-criteria-alist '()
571 "Alist mapping criteria to connection-local variable classes (symbols). 571 "Alist mapping connection criteria to connection profiles.
572Each element in this list has the form (CRITERIA CLASSES). 572Each element in this list has the form (CRITERIA PROFILES).
573CRITERIA is either a regular expression identifying a remote 573CRITERIA is a plist identifying a connection and the application
574server, or a function with one argument IDENTIFICATION, which 574using this connection. Property names might be `:application',
575returns non-nil when a remote server shall apply CLASS'es 575`:protocol', `:user' and `:machine'. The property value of
576variables. If CRITERIA is nil, it always applies. 576`:application' is a symbol, all other property values are
577CLASSES is a list of variable classes (symbols).") 577strings. All properties are optional; if CRITERIA is nil, it
578 578always applies.
579(defsubst connection-local-get-classes (criteria &optional identification) 579PROFILES is a list of connection profiles (symbols).")
580 "Return the connection-local classes list for CRITERIA. 580
581CRITERIA is either a regular expression identifying a remote 581(defsubst connection-local-normalize-criteria (criteria &rest properties)
582server, or a function with one argument IDENTIFICATION, which 582 "Normalize plist CRITERIA according to PROPERTIES.
583returns non-nil when a remote server shall apply CLASS'es 583Return a new ordered plist list containing only property names from PROPERTIES."
584variables. If CRITERIA is nil, it always applies. 584 (delq
585If IDENTIFICATION is non-nil, CRITERIA must be nil, or match 585 nil
586IDENTIFICATION accordingly." 586 (mapcar
587 (and (cond ((null identification)) 587 (lambda (property)
588 ((not (stringp identification)) 588 (when (plist-member criteria property)
589 (error "Wrong identification `%s'" identification)) 589 (list property (plist-get criteria property))))
590 ((null criteria)) 590 properties)))
591 ((stringp criteria) (string-match criteria identification)) 591
592 ((functionp criteria) (funcall criteria identification)) 592(defsubst connection-local-get-profiles (criteria)
593 (t "Wrong criteria `%s'" criteria)) 593 "Return the connection profiles list for CRITERIA.
594 (cdr (assoc criteria connection-local-criteria-alist)))) 594CRITERIA is a plist identifying a connection and the application
595using this connection, see `connection-local-criteria-alist'."
596 (or (cdr
597 (assoc
598 (connection-local-normalize-criteria
599 criteria :application :protocol :user :machine)
600 connection-local-criteria-alist))
601 ;; Try it without :application.
602 (cdr
603 (assoc
604 (connection-local-normalize-criteria criteria :protocol :user :machine)
605 connection-local-criteria-alist))))
595 606
596;;;###autoload 607;;;###autoload
597(defun connection-local-set-classes (criteria &rest classes) 608(defun connection-local-set-profiles (criteria &rest profiles)
598 "Add CLASSES for remote servers. 609 "Add PROFILES for remote servers.
599CRITERIA is either a regular expression identifying a remote 610CRITERIA is either a regular expression identifying a remote
600server, or a function with one argument IDENTIFICATION, which 611server, or a function with one argument IDENTIFICATION, which
601returns non-nil when a remote server shall apply CLASS'es 612returns non-nil when a remote server shall apply PROFILE's
602variables. If CRITERIA is nil, it always applies. 613variables. If CRITERIA is nil, it always applies.
603CLASSES are the names of a variable class (a symbol). 614PROFILES are the names of a connection profile (a symbol).
604 615
605When a connection to a remote server is opened and CRITERIA 616When a connection to a remote server is opened and CRITERIA
606matches to that server, the connection-local variables from CLASSES 617matches to that server, the connection-local variables from
607are applied to the corresponding process buffer. The variables 618PROFILES are applied to the corresponding process buffer. The
608for a class are defined using `connection-local-set-class-variables'." 619variables for a connection profile are defined using
609 (unless (or (null criteria) (stringp criteria) (functionp criteria)) 620`connection-local-set-profile-variables'."
621 (unless (listp criteria)
610 (error "Wrong criteria `%s'" criteria)) 622 (error "Wrong criteria `%s'" criteria))
611 (dolist (class classes) 623 (dolist (profile profiles)
612 (unless (assq class connection-local-class-alist) 624 (unless (assq profile connection-local-profile-alist)
613 (error "No such class `%s'" (symbol-name class)))) 625 (error "No such connection profile `%s'" (symbol-name profile))))
614 (let ((slot (assoc criteria connection-local-criteria-alist))) 626 (let* ((criteria (connection-local-normalize-criteria
627 criteria :application :protocol :user :machine))
628 (slot (assoc criteria connection-local-criteria-alist)))
615 (if slot 629 (if slot
616 (setcdr slot (delete-dups (append (cdr slot) classes))) 630 (setcdr slot (delete-dups (append (cdr slot) profiles)))
617 (setq connection-local-criteria-alist 631 (setq connection-local-criteria-alist
618 (cons (cons criteria (delete-dups classes)) 632 (cons (cons criteria (delete-dups profiles))
619 connection-local-criteria-alist))))) 633 connection-local-criteria-alist)))))
620 634
621(defsubst connection-local-get-class-variables (class) 635(defsubst connection-local-get-profile-variables (profile)
622 "Return the connection-local variable list for CLASS." 636 "Return the connection-local variable list for PROFILE."
623 (cdr (assq class connection-local-class-alist))) 637 (cdr (assq profile connection-local-profile-alist)))
624 638
625;;;###autoload 639;;;###autoload
626(defun connection-local-set-class-variables (class variables) 640(defun connection-local-set-profile-variables (profile variables)
627 "Map the symbol CLASS to a list of variable settings. 641 "Map the symbol PROFILE to a list of variable settings.
628VARIABLES is a list that declares connection-local variables for 642VARIABLES is a list that declares connection-local variables for
629the class. An element in VARIABLES is an alist whose elements 643the connection profile. An element in VARIABLES is an alist
630are of the form (VAR . VALUE). 644whose elements are of the form (VAR . VALUE).
631 645
632When a connection to a remote server is opened, the server's 646When a connection to a remote server is opened, the server's
633classes are found. A server may be assigned a class using 647connection profiles are found. A server may be assigned a
634`connection-local-set-class'. Then variables are set in the 648connection profile using `connection-local-set-profile'. Then
635server's process buffer according to the VARIABLES list of the 649variables are set in the server's process buffer according to the
636class. The list is processed in order." 650VARIABLES list of the connection profile. The list is processed
637 (setf (alist-get class connection-local-class-alist) variables)) 651in order."
638 652 (setf (alist-get profile connection-local-profile-alist) variables))
639(defun hack-connection-local-variables () 653
640 "Read per-connection local variables for the current buffer. 654(defun hack-connection-local-variables (criteria)
641Store the connection-local variables in `connection-local-variables-alist'. 655 "Read connection-local variables according to CRITERIA.
656Store the connection-local variables in buffer local
657variable`connection-local-variables-alist'.
642 658
643This does nothing if `enable-connection-local-variables' is nil." 659This does nothing if `enable-connection-local-variables' is nil."
644 (let ((identification (file-remote-p default-directory))) 660 (when enable-connection-local-variables
645 (when (and enable-connection-local-variables identification) 661 ;; Filter connection profiles.
646 ;; Loop over criteria. 662 (dolist (profile (connection-local-get-profiles criteria))
647 (dolist (criteria (mapcar 'car connection-local-criteria-alist)) 663 ;; Loop over variables.
648 ;; Filter classes which map identification. 664 (dolist (variable (connection-local-get-profile-variables profile))
649 (dolist (class (connection-local-get-classes criteria identification)) 665 (unless (assq (car variable) connection-local-variables-alist)
650 ;; Loop over variables. 666 (push variable connection-local-variables-alist))))))
651 (dolist (variable (connection-local-get-class-variables class))
652 (unless (assq (car variable) connection-local-variables-alist)
653 (push variable connection-local-variables-alist))))))))
654 667
655;;;###autoload 668;;;###autoload
656(defun hack-connection-local-variables-apply () 669(defun hack-connection-local-variables-apply (criteria)
657 "Apply connection-local variables identified by `default-directory'. 670 "Apply connection-local variables identified by CRITERIA.
658Other local variables, like file-local and dir-local variables, 671Other local variables, like file-local and dir-local variables,
659will not be changed." 672will not be changed."
660 (hack-connection-local-variables) 673 (hack-connection-local-variables criteria)
661 (let ((file-local-variables-alist 674 (let ((file-local-variables-alist
662 (copy-tree connection-local-variables-alist))) 675 (copy-tree connection-local-variables-alist)))
663 (hack-local-variables-apply))) 676 (hack-local-variables-apply)))
664 677
665;;;###autoload 678;;;###autoload
666(defmacro with-connection-local-classes (classes &rest body) 679(defmacro with-connection-local-profiles (profiles &rest body)
667 "Apply connection-local variables according to CLASSES in current buffer. 680 "Apply connection-local variables according to PROFILES in current buffer.
668Execute BODY, and unwind connection local variables." 681Execute BODY, and unwind connection local variables."
669 (declare (indent 1) (debug t)) 682 (declare (indent 1) (debug t))
670 `(let ((enable-connection-local-variables t) 683 `(let ((enable-connection-local-variables t)
671 (old-buffer-local-variables (buffer-local-variables)) 684 (old-buffer-local-variables (buffer-local-variables))
672 connection-local-variables-alist connection-local-criteria-alist) 685 connection-local-variables-alist connection-local-criteria-alist)
673 (apply 'connection-local-set-classes "" ,classes) 686 (apply 'connection-local-set-profiles nil ,profiles)
674 (hack-connection-local-variables-apply) 687 (hack-connection-local-variables-apply nil)
675 (unwind-protect 688 (unwind-protect
676 (progn ,@body) 689 (progn ,@body)
677 ;; Cleanup. 690 ;; Cleanup.
diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el
index 05adaa49e3e..576f9b1eadc 100644
--- a/lisp/net/tramp-cmds.el
+++ b/lisp/net/tramp-cmds.el
@@ -190,7 +190,7 @@ This includes password cache, file cache, connection cache, buffers."
190 password-cache 190 password-cache
191 password-cache-expiry 191 password-cache-expiry
192 remote-file-name-inhibit-cache 192 remote-file-name-inhibit-cache
193 connection-local-class-alist 193 connection-local-profile-alist
194 connection-local-criteria-alist 194 connection-local-criteria-alist
195 file-name-handler-alist)))) 195 file-name-handler-alist))))
196 (lambda (x y) (string< (symbol-name (car x)) (symbol-name (car y))))) 196 (lambda (x y) (string< (symbol-name (car x)) (symbol-name (car y)))))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index b05d55f9e04..891f9612458 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1342,10 +1342,18 @@ from the default one."
1342 "Set connection-local variables in the connection buffer used for VEC. 1342 "Set connection-local variables in the connection buffer used for VEC.
1343If connection-local variables are not supported by this Emacs 1343If connection-local variables are not supported by this Emacs
1344version, the function does nothing." 1344version, the function does nothing."
1345 ;; `tramp-get-connection-buffer' sets proper `default-directory'."
1346 (with-current-buffer (tramp-get-connection-buffer vec) 1345 (with-current-buffer (tramp-get-connection-buffer vec)
1347 ;; `hack-connection-local-variables-apply' exists since Emacs 26.1. 1346 ;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
1348 (tramp-compat-funcall 'hack-connection-local-variables-apply))) 1347 (tramp-compat-funcall
1348 'hack-connection-local-variables-apply
1349 (append
1350 '(tramp)
1351 (when (tramp-file-name-method vec)
1352 `(:protocol ,(tramp-file-name-method vec)))
1353 (when (tramp-file-name-user vec)
1354 `(:user ,(tramp-file-name-user vec)))
1355 (when (tramp-file-name-host vec)
1356 `(:machine ,(tramp-file-name-host vec)))))))
1349 1357
1350(defun tramp-debug-buffer-name (vec) 1358(defun tramp-debug-buffer-name (vec)
1351 "A name for the debug buffer for VEC." 1359 "A name for the debug buffer for VEC."
diff --git a/test/lisp/files-x-tests.el b/test/lisp/files-x-tests.el
index 88b58fe9576..21d0087ebcf 100644
--- a/test/lisp/files-x-tests.el
+++ b/test/lisp/files-x-tests.el
@@ -24,130 +24,167 @@
24(require 'ert) 24(require 'ert)
25(require 'files-x) 25(require 'files-x)
26 26
27(defvar files-x-test--criteria1 "my-user@my-remote-host") 27(defconst files-x-test--variables1
28(defvar files-x-test--criteria2
29 (lambda (identification)
30 (string-match "another-user@my-remote-host" identification)))
31(defvar files-x-test--criteria3 nil)
32
33(defvar files-x-test--variables1
34 '((remote-shell-file-name . "/bin/bash") 28 '((remote-shell-file-name . "/bin/bash")
35 (remote-shell-command-switch . "-c") 29 (remote-shell-command-switch . "-c")
36 (remote-shell-interactive-switch . "-i") 30 (remote-shell-interactive-switch . "-i")
37 (remote-shell-login-switch . "-l"))) 31 (remote-shell-login-switch . "-l")))
38(defvar files-x-test--variables2 32(defconst files-x-test--variables2
39 '((remote-shell-file-name . "/bin/ksh"))) 33 '((remote-shell-file-name . "/bin/ksh")))
40(defvar files-x-test--variables3 34(defconst files-x-test--variables3
41 '((remote-null-device . "/dev/null"))) 35 '((remote-null-device . "/dev/null")))
42(defvar files-x-test--variables4 36(defconst files-x-test--variables4
43 '((remote-null-device . "null"))) 37 '((remote-null-device . "null")))
44 38
45(ert-deftest files-x-test-connection-local-set-class-variables () 39(defconst files-x-test--application '(:application 'my-application))
46 "Test setting connection-local class variables." 40(defconst files-x-test--another-application
47 41 '(:application 'another-application))
48 ;; Declare (CLASS VARIABLES) objects. 42(defconst files-x-test--protocol '(:protocol "my-protocol"))
49 (let (connection-local-class-alist connection-local-criteria-alist) 43(defconst files-x-test--user '(:user "my-user"))
50 (connection-local-set-class-variables 'remote-bash files-x-test--variables1) 44(defconst files-x-test--machine '(:machine "my-machine"))
45
46(defvar files-x-test--criteria nil)
47(defconst files-x-test--criteria1
48 (append files-x-test--application files-x-test--protocol
49 files-x-test--user files-x-test--machine))
50(defconst files-x-test--criteria2
51 (append files-x-test--another-application files-x-test--protocol
52 files-x-test--user files-x-test--machine))
53
54(ert-deftest files-x-test-connection-local-set-profile-variables ()
55 "Test setting connection-local profile variables."
56
57 ;; Declare (PROFILE VARIABLES) objects.
58 (let (connection-local-profile-alist connection-local-criteria-alist)
59 (connection-local-set-profile-variables
60 'remote-bash files-x-test--variables1)
51 (should 61 (should
52 (equal 62 (equal
53 (connection-local-get-class-variables 'remote-bash) 63 (connection-local-get-profile-variables 'remote-bash)
54 files-x-test--variables1)) 64 files-x-test--variables1))
55 65
56 (connection-local-set-class-variables 'remote-ksh files-x-test--variables2) 66 (connection-local-set-profile-variables
67 'remote-ksh files-x-test--variables2)
57 (should 68 (should
58 (equal 69 (equal
59 (connection-local-get-class-variables 'remote-ksh) 70 (connection-local-get-profile-variables 'remote-ksh)
60 files-x-test--variables2)) 71 files-x-test--variables2))
61 72
62 (connection-local-set-class-variables 73 (connection-local-set-profile-variables
63 'remote-nullfile files-x-test--variables3) 74 'remote-nullfile files-x-test--variables3)
64 (should 75 (should
65 (equal 76 (equal
66 (connection-local-get-class-variables 'remote-nullfile) 77 (connection-local-get-profile-variables 'remote-nullfile)
67 files-x-test--variables3)) 78 files-x-test--variables3))
68 79
69 ;; A redefinition overwrites existing values. 80 ;; A redefinition overwrites existing values.
70 (connection-local-set-class-variables 81 (connection-local-set-profile-variables
71 'remote-nullfile files-x-test--variables4) 82 'remote-nullfile files-x-test--variables4)
72 (should 83 (should
73 (equal 84 (equal
74 (connection-local-get-class-variables 'remote-nullfile) 85 (connection-local-get-profile-variables 'remote-nullfile)
75 files-x-test--variables4)))) 86 files-x-test--variables4))))
76 87
77(ert-deftest files-x-test-connection-local-set-classes () 88(ert-deftest files-x-test-connection-local-set-profiles ()
78 "Test setting connection-local classes." 89 "Test setting connection-local profiles."
79 90
80 ;; Declare (CRITERIA CLASSES) objects. 91 ;; Declare (CRITERIA PROFILES) objects.
81 (let (connection-local-class-alist connection-local-criteria-alist) 92 (let (connection-local-profile-alist connection-local-criteria-alist)
82 (connection-local-set-class-variables 'remote-bash files-x-test--variables1) 93 (connection-local-set-profile-variables
83 (connection-local-set-class-variables 'remote-ksh files-x-test--variables2) 94 'remote-bash files-x-test--variables1)
84 (connection-local-set-class-variables 95 (connection-local-set-profile-variables
96 'remote-ksh files-x-test--variables2)
97 (connection-local-set-profile-variables
85 'remote-nullfile files-x-test--variables3) 98 'remote-nullfile files-x-test--variables3)
86 99
87 (connection-local-set-classes 100 ;; Use a criteria with all properties.
88 files-x-test--criteria1 'remote-bash 'remote-ksh) 101 (setq files-x-test--criteria
102 (append files-x-test--application files-x-test--protocol
103 files-x-test--user files-x-test--machine))
104 ;; An empty variable list is accepted (but makes no sense).
105 (connection-local-set-profiles files-x-test--criteria)
106 (should-not (connection-local-get-profiles files-x-test--criteria))
107 (connection-local-set-profiles
108 files-x-test--criteria 'remote-bash 'remote-ksh)
89 (should 109 (should
90 (equal 110 (equal
91 (connection-local-get-classes files-x-test--criteria1) 111 (connection-local-get-profiles files-x-test--criteria)
92 '(remote-bash remote-ksh))) 112 '(remote-bash remote-ksh)))
93 113 ;; Changing the order of properties doesn't matter.
94 (connection-local-set-classes files-x-test--criteria2 'remote-ksh) 114 (setq files-x-test--criteria
115 (append files-x-test--protocol files-x-test--application
116 files-x-test--machine files-x-test--user))
95 (should 117 (should
96 (equal 118 (equal
97 (connection-local-get-classes files-x-test--criteria2) 119 (connection-local-get-profiles files-x-test--criteria)
98 '(remote-ksh))) 120 '(remote-bash remote-ksh)))
99 ;; A further call adds classes. 121 ;; A further call adds profiles.
100 (connection-local-set-classes files-x-test--criteria2 'remote-nullfile) 122 (connection-local-set-profiles files-x-test--criteria 'remote-nullfile)
101 (should 123 (should
102 (equal 124 (equal
103 (connection-local-get-classes files-x-test--criteria2) 125 (connection-local-get-profiles files-x-test--criteria)
104 '(remote-ksh remote-nullfile))) 126 '(remote-bash remote-ksh remote-nullfile)))
105 ;; Adding existing classes doesn't matter. 127 ;; Adding existing profiles doesn't matter.
106 (connection-local-set-classes 128 (connection-local-set-profiles
107 files-x-test--criteria2 'remote-bash 'remote-nullfile) 129 files-x-test--criteria 'remote-bash 'remote-nullfile)
108 (should 130 (should
109 (equal 131 (equal
110 (connection-local-get-classes files-x-test--criteria2) 132 (connection-local-get-profiles files-x-test--criteria)
111 '(remote-ksh remote-nullfile remote-bash))) 133 '(remote-bash remote-ksh remote-nullfile)))
112 134
113 ;; An empty variable list is accepted (but makes no sense). 135 ;; Use a criteria without application.
114 (connection-local-set-classes files-x-test--criteria3) 136 (setq files-x-test--criteria
115 (should-not (connection-local-get-classes files-x-test--criteria3)) 137 (append files-x-test--protocol
138 files-x-test--user files-x-test--machine))
139 (connection-local-set-profiles files-x-test--criteria 'remote-ksh)
140 (should
141 (equal
142 (connection-local-get-profiles files-x-test--criteria)
143 '(remote-ksh)))
144 ;; An application not used in any registered criteria matches also this.
145 (setq files-x-test--criteria
146 (append files-x-test--another-application files-x-test--protocol
147 files-x-test--user files-x-test--machine))
148 (should
149 (equal
150 (connection-local-get-profiles files-x-test--criteria)
151 '(remote-ksh)))
116 152
117 ;; Using a nil criteria also works. Duplicate classes are trashed. 153 ;; Using a nil criteria also works. Duplicate profiles are trashed.
118 (connection-local-set-classes 154 (connection-local-set-profiles
119 files-x-test--criteria3 'remote-bash 'remote-ksh 'remote-ksh 'remote-bash) 155 nil 'remote-bash 'remote-ksh 'remote-ksh 'remote-bash)
120 (should 156 (should
121 (equal 157 (equal
122 (connection-local-get-classes files-x-test--criteria3) 158 (connection-local-get-profiles nil)
123 '(remote-bash remote-ksh))) 159 '(remote-bash remote-ksh)))
124 160
125 ;; A criteria other than nil, regexp or lambda function is wrong. 161 ;; A criteria other than plist is wrong.
126 (should-error (connection-local-set-classes 'dummy)))) 162 (should-error (connection-local-set-profiles 'dummy))))
127 163
128(ert-deftest files-x-test-hack-connection-local-variables-apply () 164(ert-deftest files-x-test-hack-connection-local-variables-apply ()
129 "Test setting connection-local variables." 165 "Test setting connection-local variables."
130 166
131 (let (connection-local-class-alist connection-local-criteria-alist) 167 (let (connection-local-profile-alist connection-local-criteria-alist)
132 168
133 (connection-local-set-class-variables 'remote-bash files-x-test--variables1) 169 (connection-local-set-profile-variables
134 (connection-local-set-class-variables 'remote-ksh files-x-test--variables2) 170 'remote-bash files-x-test--variables1)
135 (connection-local-set-class-variables 171 (connection-local-set-profile-variables
172 'remote-ksh files-x-test--variables2)
173 (connection-local-set-profile-variables
136 'remote-nullfile files-x-test--variables3) 174 'remote-nullfile files-x-test--variables3)
137 175
138 (connection-local-set-classes 176 (connection-local-set-profiles
139 files-x-test--criteria1 'remote-bash 'remote-ksh) 177 files-x-test--criteria1 'remote-bash 'remote-ksh)
140 (connection-local-set-classes 178 (connection-local-set-profiles
141 files-x-test--criteria2 'remote-ksh 'remote-nullfile) 179 files-x-test--criteria2 'remote-ksh 'remote-nullfile)
142 180
143 ;; Apply the variables. 181 ;; Apply the variables.
144 (with-temp-buffer 182 (with-temp-buffer
145 (let ((enable-connection-local-variables t) 183 (let ((enable-connection-local-variables t))
146 (default-directory "/sudo:my-user@my-remote-host:"))
147 (should-not connection-local-variables-alist) 184 (should-not connection-local-variables-alist)
148 (should-not (local-variable-p 'remote-shell-file-name)) 185 (should-not (local-variable-p 'remote-shell-file-name))
149 (should-not (boundp 'remote-shell-file-name)) 186 (should-not (boundp 'remote-shell-file-name))
150 (hack-connection-local-variables-apply) 187 (hack-connection-local-variables-apply files-x-test--criteria1)
151 ;; All connection-local variables are set. They apply in 188 ;; All connection-local variables are set. They apply in
152 ;; reverse order in `connection-local-variables-alist'. The 189 ;; reverse order in `connection-local-variables-alist'. The
153 ;; settings from `remote-ksh' are not contained, because they 190 ;; settings from `remote-ksh' are not contained, because they
@@ -163,12 +200,11 @@
163 200
164 ;; The second test case. 201 ;; The second test case.
165 (with-temp-buffer 202 (with-temp-buffer
166 (let ((enable-connection-local-variables t) 203 (let ((enable-connection-local-variables t))
167 (default-directory "/ssh:another-user@my-remote-host:"))
168 (should-not connection-local-variables-alist) 204 (should-not connection-local-variables-alist)
169 (should-not (local-variable-p 'remote-shell-file-name)) 205 (should-not (local-variable-p 'remote-shell-file-name))
170 (should-not (boundp 'remote-shell-file-name)) 206 (should-not (boundp 'remote-shell-file-name))
171 (hack-connection-local-variables-apply) 207 (hack-connection-local-variables-apply files-x-test--criteria2)
172 ;; All connection-local variables are set. They apply in 208 ;; All connection-local variables are set. They apply in
173 ;; reverse order in `connection-local-variables-alist'. 209 ;; reverse order in `connection-local-variables-alist'.
174 (should 210 (should
@@ -182,18 +218,17 @@
182 (should 218 (should
183 (string-equal (symbol-value 'remote-shell-file-name) "/bin/ksh")))) 219 (string-equal (symbol-value 'remote-shell-file-name) "/bin/ksh"))))
184 220
185 ;; The third test case. Both `files-x-test--criteria1' and 221 ;; The third test case. Both criteria `files-x-test--criteria1'
186 ;; `files-x-test--criteria3' apply, but there are no double 222 ;; and `files-x-test--criteria2' apply, but there are no double
187 ;; entries. 223 ;; entries.
188 (connection-local-set-classes 224 (connection-local-set-profiles
189 files-x-test--criteria3 'remote-bash 'remote-ksh) 225 nil 'remote-bash 'remote-ksh)
190 (with-temp-buffer 226 (with-temp-buffer
191 (let ((enable-connection-local-variables t) 227 (let ((enable-connection-local-variables t))
192 (default-directory "/sudo:my-user@my-remote-host:"))
193 (should-not connection-local-variables-alist) 228 (should-not connection-local-variables-alist)
194 (should-not (local-variable-p 'remote-shell-file-name)) 229 (should-not (local-variable-p 'remote-shell-file-name))
195 (should-not (boundp 'remote-shell-file-name)) 230 (should-not (boundp 'remote-shell-file-name))
196 (hack-connection-local-variables-apply) 231 (hack-connection-local-variables-apply nil)
197 ;; All connection-local variables are set. They apply in 232 ;; All connection-local variables are set. They apply in
198 ;; reverse order in `connection-local-variables-alist'. The 233 ;; reverse order in `connection-local-variables-alist'. The
199 ;; settings from `remote-ksh' are not contained, because they 234 ;; settings from `remote-ksh' are not contained, because they
@@ -209,31 +244,32 @@
209 244
210 ;; When `enable-connection-local-variables' is nil, nothing happens. 245 ;; When `enable-connection-local-variables' is nil, nothing happens.
211 (with-temp-buffer 246 (with-temp-buffer
212 (let ((enable-connection-local-variables nil) 247 (let ((enable-connection-local-variables nil))
213 (default-directory "/ssh:another-user@my-remote-host:"))
214 (should-not connection-local-variables-alist) 248 (should-not connection-local-variables-alist)
215 (should-not (local-variable-p 'remote-shell-file-name)) 249 (should-not (local-variable-p 'remote-shell-file-name))
216 (should-not (boundp 'remote-shell-file-name)) 250 (should-not (boundp 'remote-shell-file-name))
217 (hack-connection-local-variables-apply) 251 (hack-connection-local-variables-apply nil)
218 (should-not connection-local-variables-alist) 252 (should-not connection-local-variables-alist)
219 (should-not (local-variable-p 'remote-shell-file-name)) 253 (should-not (local-variable-p 'remote-shell-file-name))
220 (should-not (boundp 'remote-shell-file-name)))))) 254 (should-not (boundp 'remote-shell-file-name))))))
221 255
222(ert-deftest files-x-test-with-connection-local-classes () 256(ert-deftest files-x-test-with-connection-local-profiles ()
223 "Test setting connection-local variables." 257 "Test setting connection-local variables."
224 258
225 (let (connection-local-class-alist connection-local-criteria-alist) 259 (let (connection-local-profile-alist connection-local-criteria-alist)
226 (connection-local-set-class-variables 'remote-bash files-x-test--variables1) 260 (connection-local-set-profile-variables
227 (connection-local-set-class-variables 'remote-ksh files-x-test--variables2) 261 'remote-bash files-x-test--variables1)
228 (connection-local-set-class-variables 262 (connection-local-set-profile-variables
263 'remote-ksh files-x-test--variables2)
264 (connection-local-set-profile-variables
229 'remote-nullfile files-x-test--variables3) 265 'remote-nullfile files-x-test--variables3)
230 (connection-local-set-classes 266
231 files-x-test--criteria3 'remote-ksh 'remote-nullfile) 267 (connection-local-set-profiles
268 nil 'remote-ksh 'remote-nullfile)
232 269
233 (with-temp-buffer 270 (with-temp-buffer
234 (let ((enable-connection-local-variables t) 271 (let ((enable-connection-local-variables t))
235 (default-directory "/sudo:my-user@my-remote-host:")) 272 (hack-connection-local-variables-apply nil)
236 (hack-connection-local-variables-apply)
237 273
238 ;; All connection-local variables are set. They apply in 274 ;; All connection-local variables are set. They apply in
239 ;; reverse order in `connection-local-variables-alist'. 275 ;; reverse order in `connection-local-variables-alist'.
@@ -255,7 +291,7 @@
255 (should-not (local-variable-p 'remote-shell-command-switch)) 291 (should-not (local-variable-p 'remote-shell-command-switch))
256 292
257 ;; Use the macro. 293 ;; Use the macro.
258 (with-connection-local-classes '(remote-bash remote-ksh) 294 (with-connection-local-profiles '(remote-bash remote-ksh)
259 ;; All connection-local variables are set. They apply in 295 ;; All connection-local variables are set. They apply in
260 ;; reverse order in `connection-local-variables-alist'. 296 ;; reverse order in `connection-local-variables-alist'.
261 ;; This variable keeps only the variables to be set inside 297 ;; This variable keeps only the variables to be set inside