Adding new methods to TRAMP
There are two ways to add new methods to TRAMP: writing a new backend including an own file name handler, or adding the new method, using the existing tramp-sh-file-name-handler. The former shall happen inside the TRAMP repository, and it isn’t discussed here. The latter means usually a new ELPA package. see Using Non-Standard Methods for some examples.
- Writing an own ELPA package
- Making a customized method optional
- Activating a customized method without loading the package
8.4.1 Writing an own ELPA package
An external ELPA package foo-tramp.el, which intends to provide a new TRAMP method, say foo, must add this new method to the variable tramp-methods. This variable is an alist with elements (name param1 param2 …).
name is the method name, "foo" in this case. param``x is a pair of the form (key value). See the docstring of variable tramp-methods for possible keys and values. An example would be
(add-to-list
'tramp-methods
`("foo"
(tramp-login-program ,foo-tramp-executable)
(tramp-login-args (("exec") ("%h") ("--") ("su - %u")))
(tramp-remote-shell "/bin/sh")
(tramp-remote-shell-args ("-i" "-c"))))foo-tramp-executable in this example would be a Lisp constant, which is the program name of foo.
If a parameter doesn’t have a static value but must be computed at runtime, a format specifier can be used, like "%h" in the example above. See the docstring of tramp-methods, which patterns are expanded in which parameter. Furthermore, other format specifiers can be added via the variable tramp-extra-expand-args.
The following parameters expand format specifiers for the tramp-sh backend: tramp-copy-args, tramp-copy-env, tramp-copy-file-name, tramp-login-args, tramp-login-program, tramp-remote-copy-args.
The example above could use
(tramp-login-program "%b")And you could set tramp-extra-expand-args as connection-local value:
(defun foo-tramp-get-login-program (vec)
"Return connection-local value of `tramp-login-program'."
...)(connection-local-set-profile-variables
'foo-tramp-connection-local-default-profile
'((tramp-extra-expand-args
?b (foo-tramp-get-login-program (car tramp-current-connection)))))
(connection-local-set-profiles
'(:application tramp :protocol "foo")
foo-tramp-connection-local-default-profile)Another initialization could tell TRAMP which are the default user and host name for method foo. This is done by calling tramp-set-completion-function:
(tramp-set-completion-function
"foo"
'((tramp-foo--completion-function arg)))tramp-foo--completion-function is a function, which returns completion candidates. arg, a string, is the argument for the completion function, for example a file name to read from. see Selecting config files for user/host name completion for details.
Finally, it might also be helpful to define default user or host names for method foo, in case a remote file name leaves them empty. This can be performed by calling
(add-to-list 'tramp-default-user-alist '("foo" nil "root"))
(add-to-list 'tramp-default-host-alist '("foo" nil "localhost"))see Selecting a default user and Selecting a default host explaining the user options tramp-default-user-alist and tramp-default-host-alist.
8.4.2 Making a customized method optional
The settings of the previous subsection are global in the package foo-tramp.el, meaning they are activated when loading foo-tramp. Sometimes, it is desired to make these settings available without loading the whole package foo-tramp, but declaring the new method foo as optional method only. In this case, declare a function tramp-enable-foo-method which collects the initialization. This function must be auto loaded.
;;;###autoload
(defun tramp-enable-foo-method ()
(add-to-list 'tramp-methods '("foo" ...))
(tramp-set-completion-function "foo" ...)
(add-to-list 'tramp-default-user-alist '("foo" ...))
(add-to-list 'tramp-default-host-alist '("foo" ...)))Then, you can activate method foo by calling M-x tramp-enable-method RET foo RET. see Optional methods which must be enabled first.
8.4.3 Activating a customized method without loading the package
If you want to make method foo known after loading TRAMP, without loading the package foo-tramp.el, you must autoload the implementation of function tramp-enable-foo-method. Add the following code in foo-tramp.el:
;;;###autoload
(progn
(defun tramp-enable-foo-method ()
(add-to-list 'tramp-methods '("foo" ...))
(tramp-set-completion-function "foo" ...)
(add-to-list 'tramp-default-user-alist '("foo" ...))
(add-to-list 'tramp-default-host-alist '("foo" ...))))
;;;###autoload
(with-eval-after-load 'tramp (tramp-enable-method "foo"))The trick is to wrap the function definition of tramp-enable-foo-method with progn for the ;;;###autoload cookie.