Previous: , Up: How file names, directories and localnames are mangled and managed [Contents][Index]


8.5 Handling further operations in TRAMP

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.

Function: tramp-add-external-operation operation function backend &optional arg-type

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

  • file
    The first argument of operation is the remote file name to be checked. This is the default, if arg-type is nil.
  • default-directory
    default-directory is the remote file name to be checked.
  • process
    default-directory of the process buffer of the first argument of operation, a process, is the remote file name to be checked.
  • tramp-file-name
    The tramp-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)
Function: tramp-external-operation-p operation backend

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
Function: tramp-remove-external-operation operation backend

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.


Previous: Adding new methods to TRAMP, Up: How file names, directories and localnames are mangled and managed [Contents][Index]

AltStyle によって変換されたページ (->オリジナル) /