Previous: Adding new methods to TRAMP, Up: How file names, directories and localnames are mangled and managed [Contents][Index]
By default, TRAMP handles the basic operations listed in Magic File Name Operations. Sometimes, it is desired to support more complex operations directly, mainly for performance reasons.
An external package package could add an own implementation of an operation to TRAMP, which avoids the performance overhead caused by using the basic operations which are aware of remote files. For example, it could implement this by using an own shell script which collects the information on the remote host for this very special purpose with one round-trip per-call.
This adds an implementation of operation to TRAMP’s backend backend. function is the new implementation.
Both operation and function shall be function symbols. They must have the same argument list.
backend, also a symbol, is the feature name of a TRAMP
backend (except tramp-ftp). The new implementation will be
applied only for this backend. Example:
(defun my-test-operation (file) (message "Original implementation for %s" file))
(defun my-handle-test-operation (file) (message "Handler implementation for %s" file))
(tramp-add-external-operation #'my-test-operation #'my-handle-test-operation 'tramp-sh)
Then we have the different use cases:
;; Local file name. (my-test-operation "/a/b") ⇒ "Original implementation for /a/b"
;; Remote file name, handled by `tramp-sh'. (my-test-operation "/ssh::/a/b") ⇒ "Handler implementation for /ssh::/a/b"
;; Remote file name, handled by `tramp-gvfs'. (my-test-operation "/sftp::/a/b") ⇒ "Original implementation for /sftp::/a/b"
function is implemented like an ordinary TRAMP backend
handler, see the examples in tramp-<backend>-handle-* and
tramp-handle-*. It can expect, that the first argument (or
default-directory, if that is nil) has remote file name
syntax. It shall use TRAMP internal macros and functions like
with-parsed-tramp-file-name and the different cache functions.
If function must call the original function, this can be done
via tramp-run-real-handler. The implementation of the example
could look like:
(defun my-handle-test-operation (file) (message "Entry handler implementation for %s" file) (tramp-run-real-handler #'my-test-operation (list file)) (message "Exit handler implementation for %s" file))
(my-test-operation "/ssh::/a/b") ⇒ "Entry handler implementation for /ssh::/a/b Original implementation for /ssh::/a/b Exit handler implementation for /ssh::/a/b"
If the same function shall be used for different TRAMP
backends, tramp-add-external-operation must be called for every
backend, respectively.
The optional argument arg-type specifies, which argument of operation shall be used in order to determine, whether the handler function should be called. It can be
filenil.
default-directorydefault-directory is the remote file name to be checked.
processdefault-directory of the process buffer of the first argument
of operation, a process, is the remote file name to be checked.
tramp-file-nametramp-file-name structure of the first argument of
operation is the remote file name to be checked.
If the first argument of operation is nil,
default-directory is the remote file name to be checked in case
of arg-type being file or process.
If arg-type is a function symbol, it will be called with the
same arguments as tramp-file-name-for-operation. It must
return a string, which is the remote file name to be checked.
The example above could be changed like this:
(defun my-file-name-for-test-operation (operation &rest args) (if (stringp (car args)) (car args) default-directory))
(tramp-add-external-operation #'my-test-operation #'my-handle-test-operation 'tramp-sh #'my-file-name-for-test-operation)
This checks, whether TRAMP’s backend backend supports
external operation. It returns the function registered as
handler, or nil. Example:
(tramp-external-operation-p #'my-test-operation 'tramp-sh) ⇒ my-handle-test-operation
(tramp-external-operation-p #'my-test-operation 'tramp-gvfs) ⇒ nil
The handler for operation, added by
tramp-add-external-operation, is removed from backend.
If there are handlers of operation for other backends,
they are kept. Example:
(tramp-remove-external-operation #'my-test-operation 'tramp-sh)
Shell scripts intended for the tramp-sh backend are used as a
format string. They must observe the restrictions for format
specifiers, as documented in tramp-expand-script.
An example implementing this mechanism is the GNU ELPA package
tramp-hlo. It implements specialized versions of
dir-locals--all-files, locate-dominating-file and
dir-locals-find-file for TRAMP’s tramp-sh
backend.