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.
This commit is contained in:
parent
b6a1a74522
commit
143bc75c41
5 changed files with 306 additions and 251 deletions
|
@ -1979,24 +1979,21 @@ still respecting file-local variables (@pxref{File Local Variables}).
|
|||
@section Connection Local Variables
|
||||
@cindex connection local variables
|
||||
|
||||
Connection-local variables provide a general mechanism for
|
||||
different variable settings in buffers with a remote default
|
||||
directory. They are bound and set depending on the remote connection
|
||||
a buffer is dedicated to. Per default, they are set in all process
|
||||
buffers for a remote connection, but they could be applied also in
|
||||
other buffers with a remote directory.
|
||||
Connection-local variables provide a general mechanism for different
|
||||
variable settings in buffers with a remote connection. They are bound
|
||||
and set depending on the remote connection a buffer is dedicated to.
|
||||
|
||||
@defun connection-local-set-class-variables class variables
|
||||
This function defines a set of variable settings for the named
|
||||
@var{class}, which is a symbol. You can later assign the class to one
|
||||
or more remote connections, and Emacs will apply those variable
|
||||
settings to all process buffers for those connections. The list in
|
||||
@var{variables} is an alist of the form @code{(@var{name}
|
||||
. @var{value})}. Example:
|
||||
@defun connection-local-set-profile-variables profile variables
|
||||
This function defines a set of variable settings for the connection
|
||||
@var{profile}, which is a symbol. You can later assign the connection
|
||||
profile to one or more remote connections, and Emacs will apply those
|
||||
variable settings to all process buffers for those connections. The
|
||||
list in @var{variables} is an alist of the form
|
||||
@code{(@var{name}@tie{}.@tie{}@var{value})}. Example:
|
||||
|
||||
@example
|
||||
@group
|
||||
(connection-local-set-class-variables
|
||||
(connection-local-set-profile-variables
|
||||
'remote-bash
|
||||
'((shell-file-name . "/bin/bash")
|
||||
(shell-command-switch . "-c")
|
||||
|
@ -2005,7 +2002,7 @@ settings to all process buffers for those connections. The list in
|
|||
@end group
|
||||
|
||||
@group
|
||||
(connection-local-set-class-variables
|
||||
(connection-local-set-profile-variables
|
||||
'remote-ksh
|
||||
'((shell-file-name . "/bin/ksh")
|
||||
(shell-command-switch . "-c")
|
||||
|
@ -2014,121 +2011,122 @@ settings to all process buffers for those connections. The list in
|
|||
@end group
|
||||
|
||||
@group
|
||||
(connection-local-set-class-variables
|
||||
(connection-local-set-profile-variables
|
||||
'remote-null-device
|
||||
'((null-device . "/dev/null")))
|
||||
@end group
|
||||
@end example
|
||||
@end defun
|
||||
|
||||
@defvar connection-local-class-alist
|
||||
This alist holds the class symbols and the associated variable
|
||||
settings. It is updated by @code{connection-local-set-class-variables}.
|
||||
@defvar connection-local-profile-alist
|
||||
This alist holds the connection profile symbols and the associated
|
||||
variable settings. It is updated by
|
||||
@code{connection-local-set-profile-variables}.
|
||||
@end defvar
|
||||
|
||||
@defun connection-local-set-classes criteria &rest classes
|
||||
This function assigns @var{classes}, which are symbols, to all remote
|
||||
connections identified by @var{criteria}. @var{criteria} is either a
|
||||
regular expression identifying a remote server, or a function with one
|
||||
argument @var{identification}, which must return non-nil when a remote
|
||||
server shall apply @var{classes} variables, or @code{nil}.
|
||||
|
||||
If @var{criteria} is a regexp, is must match the result of
|
||||
@code{(file-remote-p default-directory)} of a buffer in order to apply
|
||||
the variables setting. Example:
|
||||
@defun connection-local-set-profiles criteria &rest profiles
|
||||
This function assigns @var{profiles}, which are symbols, to all remote
|
||||
connections identified by @var{criteria}. @var{criteria} is a plist
|
||||
identifying a connection and the application using this connection.
|
||||
Property names might be @code{:application}, @code{:protocol},
|
||||
@code{:user} and @code{:machine}. The property value of
|
||||
@code{:application} is a symbol, all other property values are
|
||||
strings. All properties are optional; if @var{criteria} is nil, it
|
||||
always applies. Example:
|
||||
|
||||
@example
|
||||
@group
|
||||
(connection-local-set-classes
|
||||
"^/ssh:" 'remote-bash 'remote-null-device)
|
||||
(connection-local-set-profiles
|
||||
'(:application 'tramp :protocol "ssh" :machine "localhost")
|
||||
'remote-bash 'remote-null-device)
|
||||
@end group
|
||||
|
||||
@group
|
||||
(connection-local-set-classes
|
||||
"^/sudo:" 'remote-ksh 'remote-null-device)
|
||||
(connection-local-set-profiles
|
||||
'(:application 'tramp :protocol "sudo"
|
||||
:user "root" :machine "localhost")
|
||||
'remote-ksh 'remote-null-device)
|
||||
@end group
|
||||
@end example
|
||||
|
||||
If @var{criteria} is nil, it applies for all remote connections.
|
||||
Therefore, the example above would be equivalent to
|
||||
|
||||
@example
|
||||
(connection-local-set-classes "^/ssh:" 'remote-bash)
|
||||
(connection-local-set-classes "^/sudo:" 'remote-ksh)
|
||||
(connection-local-set-classes nil 'remote-null-device)
|
||||
@end example
|
||||
|
||||
If @var{criteria} is a lambda function it must accept one parameter,
|
||||
the identification. The example above could be rewritten as
|
||||
|
||||
@example
|
||||
@group
|
||||
(connection-local-set-classes
|
||||
(lambda (identification)
|
||||
(string-equal (file-remote-p identification 'method) "ssh"))
|
||||
(connection-local-set-profiles
|
||||
'(:application 'tramp :protocol "ssh" :machine "localhost")
|
||||
'remote-bash)
|
||||
@end group
|
||||
|
||||
@group
|
||||
(connection-local-set-classes
|
||||
(lambda (identification)
|
||||
(string-equal (file-remote-p identification 'method) "sudo"))
|
||||
(connection-local-set-profiles
|
||||
'(:application 'tramp :protocol "sudo"
|
||||
:user "root" :machine "localhost")
|
||||
'remote-ksh)
|
||||
@end group
|
||||
|
||||
@group
|
||||
(connection-local-set-classes
|
||||
(lambda (identification) t)
|
||||
'remote-null-device)
|
||||
(connection-local-set-profiles
|
||||
nil 'remote-null-device)
|
||||
@end group
|
||||
@end example
|
||||
|
||||
Thereafter, all the variable settings specified for @var{classes}
|
||||
will be applied to any buffer with a matching remote directory, when
|
||||
activated by @code{hack-connection-local-variables-apply}. Any class
|
||||
of @var{classes} must have been already defined by
|
||||
@code{connection-local-set-class-variables}.
|
||||
Any connection profile of @var{profiles} must have been already
|
||||
defined by @code{connection-local-set-profile-variables}.
|
||||
@end defun
|
||||
|
||||
@defvar connection-local-criteria-alist
|
||||
This alist contains remote server identifications and their assigned
|
||||
class names. The function @code{connection-local-set-classes} updates
|
||||
this list.
|
||||
This alist contains connection criteria and their assigned profile
|
||||
names. The function @code{connection-local-set-profiles} updates this
|
||||
list.
|
||||
@end defvar
|
||||
|
||||
@defun hack-connection-local-variables
|
||||
This function collects applicable connection-local variables in
|
||||
@code{connection-local-variables-alist} that is local to the buffer,
|
||||
without applying them. Whether a connection-local variable is
|
||||
applicable is specified by the remote identifier of a buffer,
|
||||
evaluated by @code{(file-remote-p default-directory)}.
|
||||
@defun hack-connection-local-variables criteria
|
||||
This function collects applicable connection-local variables
|
||||
associated with @var{criteria} in
|
||||
@code{connection-local-variables-alist}, without applying them.
|
||||
Example:
|
||||
|
||||
@example
|
||||
@group
|
||||
(hack-connection-local-variables
|
||||
'(:application 'tramp :protocol "ssh" :machine "localhost"))
|
||||
@end group
|
||||
|
||||
@group
|
||||
connection-local-variables-alist
|
||||
@result{} ((null-device . "/dev/null")
|
||||
(shell-login-switch . "-l")
|
||||
(shell-interactive-switch . "-i")
|
||||
(shell-command-switch . "-c")
|
||||
(shell-file-name . "/bin/bash"))
|
||||
@end group
|
||||
@end example
|
||||
@end defun
|
||||
|
||||
@defun hack-connection-local-variables-apply
|
||||
This function looks for connection-local variables, and immediately
|
||||
applies them in the current buffer. It is called per default for
|
||||
every process-buffer related to a remote connection. For other remote
|
||||
buffers, it could be called by any mode.
|
||||
@defun hack-connection-local-variables-apply criteria
|
||||
This function looks for connection-local variables according to
|
||||
@var{criteria}, and immediately applies them in the current buffer.
|
||||
@end defun
|
||||
|
||||
@defmac with-connection-local-classes classes &rest body
|
||||
All connection-local variables, which are specified by a class in
|
||||
@var{classes}, are applied. An implicit binding of the classes to the
|
||||
remote connection is enabled.
|
||||
@defmac with-connection-local-profiles profiles &rest body
|
||||
All connection-local variables, which are specified by a connection
|
||||
profile in @var{profiles}, are applied.
|
||||
|
||||
After that, @var{body} is executed, and the connection-local variables
|
||||
are unwound. Example:
|
||||
|
||||
@example
|
||||
@group
|
||||
(connection-local-set-class-variables
|
||||
(connection-local-set-profile-variables
|
||||
'remote-perl
|
||||
'((perl-command-name . "/usr/local/bin/perl")
|
||||
(perl-command-switch . "-e %s")))
|
||||
@end group
|
||||
|
||||
@group
|
||||
(with-connection-local-classes '(remote-perl)
|
||||
(with-connection-local-profiles '(remote-perl)
|
||||
do something useful)
|
||||
@end group
|
||||
@end example
|
||||
|
|
163
lisp/files-x.el
163
lisp/files-x.el
|
@ -559,119 +559,132 @@ changed by the user.")
|
|||
(setq ignored-local-variables
|
||||
(cons 'connection-local-variables-alist ignored-local-variables))
|
||||
|
||||
(defvar connection-local-class-alist '()
|
||||
"Alist mapping connection-local variable classes (symbols) to variable lists.
|
||||
Each element in this list has the form (CLASS VARIABLES).
|
||||
CLASS is the name of a variable class (a symbol).
|
||||
(defvar connection-local-profile-alist '()
|
||||
"Alist mapping connection profiles to variable lists.
|
||||
Each element in this list has the form (PROFILE VARIABLES).
|
||||
PROFILE is the name of a connection profile (a symbol).
|
||||
VARIABLES is a list that declares connection-local variables for
|
||||
CLASS. An element in VARIABLES is an alist whose elements are of
|
||||
the form (VAR . VALUE).")
|
||||
PROFILE. An element in VARIABLES is an alist whose elements are
|
||||
of the form (VAR . VALUE).")
|
||||
|
||||
(defvar connection-local-criteria-alist '()
|
||||
"Alist mapping criteria to connection-local variable classes (symbols).
|
||||
Each element in this list has the form (CRITERIA CLASSES).
|
||||
CRITERIA is either a regular expression identifying a remote
|
||||
server, or a function with one argument IDENTIFICATION, which
|
||||
returns non-nil when a remote server shall apply CLASS'es
|
||||
variables. If CRITERIA is nil, it always applies.
|
||||
CLASSES is a list of variable classes (symbols).")
|
||||
"Alist mapping connection criteria to connection profiles.
|
||||
Each element in this list has the form (CRITERIA PROFILES).
|
||||
CRITERIA is a plist identifying a connection and the application
|
||||
using this connection. Property names might be `:application',
|
||||
`:protocol', `:user' and `:machine'. The property value of
|
||||
`:application' is a symbol, all other property values are
|
||||
strings. All properties are optional; if CRITERIA is nil, it
|
||||
always applies.
|
||||
PROFILES is a list of connection profiles (symbols).")
|
||||
|
||||
(defsubst connection-local-get-classes (criteria &optional identification)
|
||||
"Return the connection-local classes list for CRITERIA.
|
||||
CRITERIA is either a regular expression identifying a remote
|
||||
server, or a function with one argument IDENTIFICATION, which
|
||||
returns non-nil when a remote server shall apply CLASS'es
|
||||
variables. If CRITERIA is nil, it always applies.
|
||||
If IDENTIFICATION is non-nil, CRITERIA must be nil, or match
|
||||
IDENTIFICATION accordingly."
|
||||
(and (cond ((null identification))
|
||||
((not (stringp identification))
|
||||
(error "Wrong identification `%s'" identification))
|
||||
((null criteria))
|
||||
((stringp criteria) (string-match criteria identification))
|
||||
((functionp criteria) (funcall criteria identification))
|
||||
(t "Wrong criteria `%s'" criteria))
|
||||
(cdr (assoc criteria connection-local-criteria-alist))))
|
||||
(defsubst connection-local-normalize-criteria (criteria &rest properties)
|
||||
"Normalize plist CRITERIA according to PROPERTIES.
|
||||
Return a new ordered plist list containing only property names from PROPERTIES."
|
||||
(delq
|
||||
nil
|
||||
(mapcar
|
||||
(lambda (property)
|
||||
(when (plist-member criteria property)
|
||||
(list property (plist-get criteria property))))
|
||||
properties)))
|
||||
|
||||
(defsubst connection-local-get-profiles (criteria)
|
||||
"Return the connection profiles list for CRITERIA.
|
||||
CRITERIA is a plist identifying a connection and the application
|
||||
using this connection, see `connection-local-criteria-alist'."
|
||||
(or (cdr
|
||||
(assoc
|
||||
(connection-local-normalize-criteria
|
||||
criteria :application :protocol :user :machine)
|
||||
connection-local-criteria-alist))
|
||||
;; Try it without :application.
|
||||
(cdr
|
||||
(assoc
|
||||
(connection-local-normalize-criteria criteria :protocol :user :machine)
|
||||
connection-local-criteria-alist))))
|
||||
|
||||
;;;###autoload
|
||||
(defun connection-local-set-classes (criteria &rest classes)
|
||||
"Add CLASSES for remote servers.
|
||||
(defun connection-local-set-profiles (criteria &rest profiles)
|
||||
"Add PROFILES for remote servers.
|
||||
CRITERIA is either a regular expression identifying a remote
|
||||
server, or a function with one argument IDENTIFICATION, which
|
||||
returns non-nil when a remote server shall apply CLASS'es
|
||||
returns non-nil when a remote server shall apply PROFILE's
|
||||
variables. If CRITERIA is nil, it always applies.
|
||||
CLASSES are the names of a variable class (a symbol).
|
||||
PROFILES are the names of a connection profile (a symbol).
|
||||
|
||||
When a connection to a remote server is opened and CRITERIA
|
||||
matches to that server, the connection-local variables from CLASSES
|
||||
are applied to the corresponding process buffer. The variables
|
||||
for a class are defined using `connection-local-set-class-variables'."
|
||||
(unless (or (null criteria) (stringp criteria) (functionp criteria))
|
||||
matches to that server, the connection-local variables from
|
||||
PROFILES are applied to the corresponding process buffer. The
|
||||
variables for a connection profile are defined using
|
||||
`connection-local-set-profile-variables'."
|
||||
(unless (listp criteria)
|
||||
(error "Wrong criteria `%s'" criteria))
|
||||
(dolist (class classes)
|
||||
(unless (assq class connection-local-class-alist)
|
||||
(error "No such class `%s'" (symbol-name class))))
|
||||
(let ((slot (assoc criteria connection-local-criteria-alist)))
|
||||
(dolist (profile profiles)
|
||||
(unless (assq profile connection-local-profile-alist)
|
||||
(error "No such connection profile `%s'" (symbol-name profile))))
|
||||
(let* ((criteria (connection-local-normalize-criteria
|
||||
criteria :application :protocol :user :machine))
|
||||
(slot (assoc criteria connection-local-criteria-alist)))
|
||||
(if slot
|
||||
(setcdr slot (delete-dups (append (cdr slot) classes)))
|
||||
(setcdr slot (delete-dups (append (cdr slot) profiles)))
|
||||
(setq connection-local-criteria-alist
|
||||
(cons (cons criteria (delete-dups classes))
|
||||
(cons (cons criteria (delete-dups profiles))
|
||||
connection-local-criteria-alist)))))
|
||||
|
||||
(defsubst connection-local-get-class-variables (class)
|
||||
"Return the connection-local variable list for CLASS."
|
||||
(cdr (assq class connection-local-class-alist)))
|
||||
(defsubst connection-local-get-profile-variables (profile)
|
||||
"Return the connection-local variable list for PROFILE."
|
||||
(cdr (assq profile connection-local-profile-alist)))
|
||||
|
||||
;;;###autoload
|
||||
(defun connection-local-set-class-variables (class variables)
|
||||
"Map the symbol CLASS to a list of variable settings.
|
||||
(defun connection-local-set-profile-variables (profile variables)
|
||||
"Map the symbol PROFILE to a list of variable settings.
|
||||
VARIABLES is a list that declares connection-local variables for
|
||||
the class. An element in VARIABLES is an alist whose elements
|
||||
are of the form (VAR . VALUE).
|
||||
the connection profile. An element in VARIABLES is an alist
|
||||
whose elements are of the form (VAR . VALUE).
|
||||
|
||||
When a connection to a remote server is opened, the server's
|
||||
classes are found. A server may be assigned a class using
|
||||
`connection-local-set-class'. Then variables are set in the
|
||||
server's process buffer according to the VARIABLES list of the
|
||||
class. The list is processed in order."
|
||||
(setf (alist-get class connection-local-class-alist) variables))
|
||||
connection profiles are found. A server may be assigned a
|
||||
connection profile using `connection-local-set-profile'. Then
|
||||
variables are set in the server's process buffer according to the
|
||||
VARIABLES list of the connection profile. The list is processed
|
||||
in order."
|
||||
(setf (alist-get profile connection-local-profile-alist) variables))
|
||||
|
||||
(defun hack-connection-local-variables ()
|
||||
"Read per-connection local variables for the current buffer.
|
||||
Store the connection-local variables in `connection-local-variables-alist'.
|
||||
(defun hack-connection-local-variables (criteria)
|
||||
"Read connection-local variables according to CRITERIA.
|
||||
Store the connection-local variables in buffer local
|
||||
variable`connection-local-variables-alist'.
|
||||
|
||||
This does nothing if `enable-connection-local-variables' is nil."
|
||||
(let ((identification (file-remote-p default-directory)))
|
||||
(when (and enable-connection-local-variables identification)
|
||||
;; Loop over criteria.
|
||||
(dolist (criteria (mapcar 'car connection-local-criteria-alist))
|
||||
;; Filter classes which map identification.
|
||||
(dolist (class (connection-local-get-classes criteria identification))
|
||||
;; Loop over variables.
|
||||
(dolist (variable (connection-local-get-class-variables class))
|
||||
(unless (assq (car variable) connection-local-variables-alist)
|
||||
(push variable connection-local-variables-alist))))))))
|
||||
(when enable-connection-local-variables
|
||||
;; Filter connection profiles.
|
||||
(dolist (profile (connection-local-get-profiles criteria))
|
||||
;; Loop over variables.
|
||||
(dolist (variable (connection-local-get-profile-variables profile))
|
||||
(unless (assq (car variable) connection-local-variables-alist)
|
||||
(push variable connection-local-variables-alist))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun hack-connection-local-variables-apply ()
|
||||
"Apply connection-local variables identified by `default-directory'.
|
||||
(defun hack-connection-local-variables-apply (criteria)
|
||||
"Apply connection-local variables identified by CRITERIA.
|
||||
Other local variables, like file-local and dir-local variables,
|
||||
will not be changed."
|
||||
(hack-connection-local-variables)
|
||||
(hack-connection-local-variables criteria)
|
||||
(let ((file-local-variables-alist
|
||||
(copy-tree connection-local-variables-alist)))
|
||||
(hack-local-variables-apply)))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro with-connection-local-classes (classes &rest body)
|
||||
"Apply connection-local variables according to CLASSES in current buffer.
|
||||
(defmacro with-connection-local-profiles (profiles &rest body)
|
||||
"Apply connection-local variables according to PROFILES in current buffer.
|
||||
Execute BODY, and unwind connection local variables."
|
||||
(declare (indent 1) (debug t))
|
||||
`(let ((enable-connection-local-variables t)
|
||||
(old-buffer-local-variables (buffer-local-variables))
|
||||
connection-local-variables-alist connection-local-criteria-alist)
|
||||
(apply 'connection-local-set-classes "" ,classes)
|
||||
(hack-connection-local-variables-apply)
|
||||
(apply 'connection-local-set-profiles nil ,profiles)
|
||||
(hack-connection-local-variables-apply nil)
|
||||
(unwind-protect
|
||||
(progn ,@body)
|
||||
;; Cleanup.
|
||||
|
|
|
@ -190,7 +190,7 @@ This includes password cache, file cache, connection cache, buffers."
|
|||
password-cache
|
||||
password-cache-expiry
|
||||
remote-file-name-inhibit-cache
|
||||
connection-local-class-alist
|
||||
connection-local-profile-alist
|
||||
connection-local-criteria-alist
|
||||
file-name-handler-alist))))
|
||||
(lambda (x y) (string< (symbol-name (car x)) (symbol-name (car y)))))
|
||||
|
|
|
@ -1342,10 +1342,18 @@ from the default one."
|
|||
"Set connection-local variables in the connection buffer used for VEC.
|
||||
If connection-local variables are not supported by this Emacs
|
||||
version, the function does nothing."
|
||||
;; `tramp-get-connection-buffer' sets proper `default-directory'."
|
||||
(with-current-buffer (tramp-get-connection-buffer vec)
|
||||
;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
|
||||
(tramp-compat-funcall 'hack-connection-local-variables-apply)))
|
||||
(tramp-compat-funcall
|
||||
'hack-connection-local-variables-apply
|
||||
(append
|
||||
'(tramp)
|
||||
(when (tramp-file-name-method vec)
|
||||
`(:protocol ,(tramp-file-name-method vec)))
|
||||
(when (tramp-file-name-user vec)
|
||||
`(:user ,(tramp-file-name-user vec)))
|
||||
(when (tramp-file-name-host vec)
|
||||
`(:machine ,(tramp-file-name-host vec)))))))
|
||||
|
||||
(defun tramp-debug-buffer-name (vec)
|
||||
"A name for the debug buffer for VEC."
|
||||
|
|
|
@ -24,130 +24,167 @@
|
|||
(require 'ert)
|
||||
(require 'files-x)
|
||||
|
||||
(defvar files-x-test--criteria1 "my-user@my-remote-host")
|
||||
(defvar files-x-test--criteria2
|
||||
(lambda (identification)
|
||||
(string-match "another-user@my-remote-host" identification)))
|
||||
(defvar files-x-test--criteria3 nil)
|
||||
|
||||
(defvar files-x-test--variables1
|
||||
(defconst files-x-test--variables1
|
||||
'((remote-shell-file-name . "/bin/bash")
|
||||
(remote-shell-command-switch . "-c")
|
||||
(remote-shell-interactive-switch . "-i")
|
||||
(remote-shell-login-switch . "-l")))
|
||||
(defvar files-x-test--variables2
|
||||
(defconst files-x-test--variables2
|
||||
'((remote-shell-file-name . "/bin/ksh")))
|
||||
(defvar files-x-test--variables3
|
||||
(defconst files-x-test--variables3
|
||||
'((remote-null-device . "/dev/null")))
|
||||
(defvar files-x-test--variables4
|
||||
(defconst files-x-test--variables4
|
||||
'((remote-null-device . "null")))
|
||||
|
||||
(ert-deftest files-x-test-connection-local-set-class-variables ()
|
||||
"Test setting connection-local class variables."
|
||||
(defconst files-x-test--application '(:application 'my-application))
|
||||
(defconst files-x-test--another-application
|
||||
'(:application 'another-application))
|
||||
(defconst files-x-test--protocol '(:protocol "my-protocol"))
|
||||
(defconst files-x-test--user '(:user "my-user"))
|
||||
(defconst files-x-test--machine '(:machine "my-machine"))
|
||||
|
||||
;; Declare (CLASS VARIABLES) objects.
|
||||
(let (connection-local-class-alist connection-local-criteria-alist)
|
||||
(connection-local-set-class-variables 'remote-bash files-x-test--variables1)
|
||||
(defvar files-x-test--criteria nil)
|
||||
(defconst files-x-test--criteria1
|
||||
(append files-x-test--application files-x-test--protocol
|
||||
files-x-test--user files-x-test--machine))
|
||||
(defconst files-x-test--criteria2
|
||||
(append files-x-test--another-application files-x-test--protocol
|
||||
files-x-test--user files-x-test--machine))
|
||||
|
||||
(ert-deftest files-x-test-connection-local-set-profile-variables ()
|
||||
"Test setting connection-local profile variables."
|
||||
|
||||
;; Declare (PROFILE VARIABLES) objects.
|
||||
(let (connection-local-profile-alist connection-local-criteria-alist)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-bash files-x-test--variables1)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-class-variables 'remote-bash)
|
||||
(connection-local-get-profile-variables 'remote-bash)
|
||||
files-x-test--variables1))
|
||||
|
||||
(connection-local-set-class-variables 'remote-ksh files-x-test--variables2)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-ksh files-x-test--variables2)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-class-variables 'remote-ksh)
|
||||
(connection-local-get-profile-variables 'remote-ksh)
|
||||
files-x-test--variables2))
|
||||
|
||||
(connection-local-set-class-variables
|
||||
(connection-local-set-profile-variables
|
||||
'remote-nullfile files-x-test--variables3)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-class-variables 'remote-nullfile)
|
||||
(connection-local-get-profile-variables 'remote-nullfile)
|
||||
files-x-test--variables3))
|
||||
|
||||
;; A redefinition overwrites existing values.
|
||||
(connection-local-set-class-variables
|
||||
(connection-local-set-profile-variables
|
||||
'remote-nullfile files-x-test--variables4)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-class-variables 'remote-nullfile)
|
||||
(connection-local-get-profile-variables 'remote-nullfile)
|
||||
files-x-test--variables4))))
|
||||
|
||||
(ert-deftest files-x-test-connection-local-set-classes ()
|
||||
"Test setting connection-local classes."
|
||||
(ert-deftest files-x-test-connection-local-set-profiles ()
|
||||
"Test setting connection-local profiles."
|
||||
|
||||
;; Declare (CRITERIA CLASSES) objects.
|
||||
(let (connection-local-class-alist connection-local-criteria-alist)
|
||||
(connection-local-set-class-variables 'remote-bash files-x-test--variables1)
|
||||
(connection-local-set-class-variables 'remote-ksh files-x-test--variables2)
|
||||
(connection-local-set-class-variables
|
||||
;; Declare (CRITERIA PROFILES) objects.
|
||||
(let (connection-local-profile-alist connection-local-criteria-alist)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-bash files-x-test--variables1)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-ksh files-x-test--variables2)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-nullfile files-x-test--variables3)
|
||||
|
||||
(connection-local-set-classes
|
||||
files-x-test--criteria1 'remote-bash 'remote-ksh)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-classes files-x-test--criteria1)
|
||||
'(remote-bash remote-ksh)))
|
||||
|
||||
(connection-local-set-classes files-x-test--criteria2 'remote-ksh)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-classes files-x-test--criteria2)
|
||||
'(remote-ksh)))
|
||||
;; A further call adds classes.
|
||||
(connection-local-set-classes files-x-test--criteria2 'remote-nullfile)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-classes files-x-test--criteria2)
|
||||
'(remote-ksh remote-nullfile)))
|
||||
;; Adding existing classes doesn't matter.
|
||||
(connection-local-set-classes
|
||||
files-x-test--criteria2 'remote-bash 'remote-nullfile)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-classes files-x-test--criteria2)
|
||||
'(remote-ksh remote-nullfile remote-bash)))
|
||||
|
||||
;; Use a criteria with all properties.
|
||||
(setq files-x-test--criteria
|
||||
(append files-x-test--application files-x-test--protocol
|
||||
files-x-test--user files-x-test--machine))
|
||||
;; An empty variable list is accepted (but makes no sense).
|
||||
(connection-local-set-classes files-x-test--criteria3)
|
||||
(should-not (connection-local-get-classes files-x-test--criteria3))
|
||||
|
||||
;; Using a nil criteria also works. Duplicate classes are trashed.
|
||||
(connection-local-set-classes
|
||||
files-x-test--criteria3 'remote-bash 'remote-ksh 'remote-ksh 'remote-bash)
|
||||
(connection-local-set-profiles files-x-test--criteria)
|
||||
(should-not (connection-local-get-profiles files-x-test--criteria))
|
||||
(connection-local-set-profiles
|
||||
files-x-test--criteria 'remote-bash 'remote-ksh)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-classes files-x-test--criteria3)
|
||||
(connection-local-get-profiles files-x-test--criteria)
|
||||
'(remote-bash remote-ksh)))
|
||||
;; Changing the order of properties doesn't matter.
|
||||
(setq files-x-test--criteria
|
||||
(append files-x-test--protocol files-x-test--application
|
||||
files-x-test--machine files-x-test--user))
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-profiles files-x-test--criteria)
|
||||
'(remote-bash remote-ksh)))
|
||||
;; A further call adds profiles.
|
||||
(connection-local-set-profiles files-x-test--criteria 'remote-nullfile)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-profiles files-x-test--criteria)
|
||||
'(remote-bash remote-ksh remote-nullfile)))
|
||||
;; Adding existing profiles doesn't matter.
|
||||
(connection-local-set-profiles
|
||||
files-x-test--criteria 'remote-bash 'remote-nullfile)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-profiles files-x-test--criteria)
|
||||
'(remote-bash remote-ksh remote-nullfile)))
|
||||
|
||||
;; Use a criteria without application.
|
||||
(setq files-x-test--criteria
|
||||
(append files-x-test--protocol
|
||||
files-x-test--user files-x-test--machine))
|
||||
(connection-local-set-profiles files-x-test--criteria 'remote-ksh)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-profiles files-x-test--criteria)
|
||||
'(remote-ksh)))
|
||||
;; An application not used in any registered criteria matches also this.
|
||||
(setq files-x-test--criteria
|
||||
(append files-x-test--another-application files-x-test--protocol
|
||||
files-x-test--user files-x-test--machine))
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-profiles files-x-test--criteria)
|
||||
'(remote-ksh)))
|
||||
|
||||
;; Using a nil criteria also works. Duplicate profiles are trashed.
|
||||
(connection-local-set-profiles
|
||||
nil 'remote-bash 'remote-ksh 'remote-ksh 'remote-bash)
|
||||
(should
|
||||
(equal
|
||||
(connection-local-get-profiles nil)
|
||||
'(remote-bash remote-ksh)))
|
||||
|
||||
;; A criteria other than nil, regexp or lambda function is wrong.
|
||||
(should-error (connection-local-set-classes 'dummy))))
|
||||
;; A criteria other than plist is wrong.
|
||||
(should-error (connection-local-set-profiles 'dummy))))
|
||||
|
||||
(ert-deftest files-x-test-hack-connection-local-variables-apply ()
|
||||
"Test setting connection-local variables."
|
||||
|
||||
(let (connection-local-class-alist connection-local-criteria-alist)
|
||||
(let (connection-local-profile-alist connection-local-criteria-alist)
|
||||
|
||||
(connection-local-set-class-variables 'remote-bash files-x-test--variables1)
|
||||
(connection-local-set-class-variables 'remote-ksh files-x-test--variables2)
|
||||
(connection-local-set-class-variables
|
||||
(connection-local-set-profile-variables
|
||||
'remote-bash files-x-test--variables1)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-ksh files-x-test--variables2)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-nullfile files-x-test--variables3)
|
||||
|
||||
(connection-local-set-classes
|
||||
(connection-local-set-profiles
|
||||
files-x-test--criteria1 'remote-bash 'remote-ksh)
|
||||
(connection-local-set-classes
|
||||
(connection-local-set-profiles
|
||||
files-x-test--criteria2 'remote-ksh 'remote-nullfile)
|
||||
|
||||
;; Apply the variables.
|
||||
(with-temp-buffer
|
||||
(let ((enable-connection-local-variables t)
|
||||
(default-directory "/sudo:my-user@my-remote-host:"))
|
||||
(let ((enable-connection-local-variables t))
|
||||
(should-not connection-local-variables-alist)
|
||||
(should-not (local-variable-p 'remote-shell-file-name))
|
||||
(should-not (boundp 'remote-shell-file-name))
|
||||
(hack-connection-local-variables-apply)
|
||||
(hack-connection-local-variables-apply files-x-test--criteria1)
|
||||
;; All connection-local variables are set. They apply in
|
||||
;; reverse order in `connection-local-variables-alist'. The
|
||||
;; settings from `remote-ksh' are not contained, because they
|
||||
|
@ -163,12 +200,11 @@
|
|||
|
||||
;; The second test case.
|
||||
(with-temp-buffer
|
||||
(let ((enable-connection-local-variables t)
|
||||
(default-directory "/ssh:another-user@my-remote-host:"))
|
||||
(let ((enable-connection-local-variables t))
|
||||
(should-not connection-local-variables-alist)
|
||||
(should-not (local-variable-p 'remote-shell-file-name))
|
||||
(should-not (boundp 'remote-shell-file-name))
|
||||
(hack-connection-local-variables-apply)
|
||||
(hack-connection-local-variables-apply files-x-test--criteria2)
|
||||
;; All connection-local variables are set. They apply in
|
||||
;; reverse order in `connection-local-variables-alist'.
|
||||
(should
|
||||
|
@ -182,18 +218,17 @@
|
|||
(should
|
||||
(string-equal (symbol-value 'remote-shell-file-name) "/bin/ksh"))))
|
||||
|
||||
;; The third test case. Both `files-x-test--criteria1' and
|
||||
;; `files-x-test--criteria3' apply, but there are no double
|
||||
;; The third test case. Both criteria `files-x-test--criteria1'
|
||||
;; and `files-x-test--criteria2' apply, but there are no double
|
||||
;; entries.
|
||||
(connection-local-set-classes
|
||||
files-x-test--criteria3 'remote-bash 'remote-ksh)
|
||||
(connection-local-set-profiles
|
||||
nil 'remote-bash 'remote-ksh)
|
||||
(with-temp-buffer
|
||||
(let ((enable-connection-local-variables t)
|
||||
(default-directory "/sudo:my-user@my-remote-host:"))
|
||||
(let ((enable-connection-local-variables t))
|
||||
(should-not connection-local-variables-alist)
|
||||
(should-not (local-variable-p 'remote-shell-file-name))
|
||||
(should-not (boundp 'remote-shell-file-name))
|
||||
(hack-connection-local-variables-apply)
|
||||
(hack-connection-local-variables-apply nil)
|
||||
;; All connection-local variables are set. They apply in
|
||||
;; reverse order in `connection-local-variables-alist'. The
|
||||
;; settings from `remote-ksh' are not contained, because they
|
||||
|
@ -209,31 +244,32 @@
|
|||
|
||||
;; When `enable-connection-local-variables' is nil, nothing happens.
|
||||
(with-temp-buffer
|
||||
(let ((enable-connection-local-variables nil)
|
||||
(default-directory "/ssh:another-user@my-remote-host:"))
|
||||
(let ((enable-connection-local-variables nil))
|
||||
(should-not connection-local-variables-alist)
|
||||
(should-not (local-variable-p 'remote-shell-file-name))
|
||||
(should-not (boundp 'remote-shell-file-name))
|
||||
(hack-connection-local-variables-apply)
|
||||
(hack-connection-local-variables-apply nil)
|
||||
(should-not connection-local-variables-alist)
|
||||
(should-not (local-variable-p 'remote-shell-file-name))
|
||||
(should-not (boundp 'remote-shell-file-name))))))
|
||||
|
||||
(ert-deftest files-x-test-with-connection-local-classes ()
|
||||
(ert-deftest files-x-test-with-connection-local-profiles ()
|
||||
"Test setting connection-local variables."
|
||||
|
||||
(let (connection-local-class-alist connection-local-criteria-alist)
|
||||
(connection-local-set-class-variables 'remote-bash files-x-test--variables1)
|
||||
(connection-local-set-class-variables 'remote-ksh files-x-test--variables2)
|
||||
(connection-local-set-class-variables
|
||||
(let (connection-local-profile-alist connection-local-criteria-alist)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-bash files-x-test--variables1)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-ksh files-x-test--variables2)
|
||||
(connection-local-set-profile-variables
|
||||
'remote-nullfile files-x-test--variables3)
|
||||
(connection-local-set-classes
|
||||
files-x-test--criteria3 'remote-ksh 'remote-nullfile)
|
||||
|
||||
(connection-local-set-profiles
|
||||
nil 'remote-ksh 'remote-nullfile)
|
||||
|
||||
(with-temp-buffer
|
||||
(let ((enable-connection-local-variables t)
|
||||
(default-directory "/sudo:my-user@my-remote-host:"))
|
||||
(hack-connection-local-variables-apply)
|
||||
(let ((enable-connection-local-variables t))
|
||||
(hack-connection-local-variables-apply nil)
|
||||
|
||||
;; All connection-local variables are set. They apply in
|
||||
;; reverse order in `connection-local-variables-alist'.
|
||||
|
@ -255,7 +291,7 @@
|
|||
(should-not (local-variable-p 'remote-shell-command-switch))
|
||||
|
||||
;; Use the macro.
|
||||
(with-connection-local-classes '(remote-bash remote-ksh)
|
||||
(with-connection-local-profiles '(remote-bash remote-ksh)
|
||||
;; All connection-local variables are set. They apply in
|
||||
;; reverse order in `connection-local-variables-alist'.
|
||||
;; This variable keeps only the variables to be set inside
|
||||
|
|
Loading…
Add table
Reference in a new issue