2019-02-24 11:15:49 +01:00
|
|
|
|
;;; tramp-integration.el --- Tramp integration into other packages -*- lexical-binding:t -*-
|
|
|
|
|
|
2020-01-01 00:19:43 +00:00
|
|
|
|
;; Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
2019-02-24 11:15:49 +01:00
|
|
|
|
|
|
|
|
|
;; Author: Michael Albinus <michael.albinus@gmx.de>
|
|
|
|
|
;; Keywords: comm, processes
|
|
|
|
|
;; Package: tramp
|
|
|
|
|
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; This assembles all integration of Tramp with other packages.
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2019-03-09 16:44:24 +01:00
|
|
|
|
(require 'tramp-compat)
|
|
|
|
|
|
2019-02-24 11:15:49 +01:00
|
|
|
|
;; Pacify byte-compiler.
|
|
|
|
|
(require 'cl-lib)
|
2019-12-06 19:28:01 +01:00
|
|
|
|
(declare-function info-lookup->cache "info-look")
|
2019-12-07 13:40:04 +01:00
|
|
|
|
(declare-function info-lookup->mode-cache "info-look")
|
2019-12-06 19:28:01 +01:00
|
|
|
|
(declare-function info-lookup->mode-value "info-look")
|
|
|
|
|
(declare-function info-lookup->other-modes "info-look")
|
2019-12-07 13:40:04 +01:00
|
|
|
|
(declare-function info-lookup->topic-cache "info-look")
|
2019-12-06 19:28:01 +01:00
|
|
|
|
(declare-function info-lookup->topic-value "info-look")
|
|
|
|
|
(declare-function info-lookup-maybe-add-help "info-look")
|
2019-05-18 16:04:02 +02:00
|
|
|
|
(declare-function recentf-cleanup "recentf")
|
2019-02-24 11:15:49 +01:00
|
|
|
|
(declare-function tramp-dissect-file-name "tramp")
|
|
|
|
|
(declare-function tramp-file-name-equal-p "tramp")
|
|
|
|
|
(declare-function tramp-tramp-file-p "tramp")
|
|
|
|
|
(defvar eshell-path-env)
|
2019-11-20 13:45:30 +01:00
|
|
|
|
(defvar ido-read-file-name-non-ido)
|
2019-12-07 13:40:04 +01:00
|
|
|
|
(defvar info-lookup-alist)
|
2019-11-20 13:45:30 +01:00
|
|
|
|
(defvar ivy-completing-read-handlers-alist)
|
2019-02-24 11:15:49 +01:00
|
|
|
|
(defvar recentf-exclude)
|
|
|
|
|
(defvar tramp-current-connection)
|
|
|
|
|
(defvar tramp-postfix-host-format)
|
|
|
|
|
|
|
|
|
|
;;; Fontification of `read-file-name':
|
|
|
|
|
|
|
|
|
|
(defvar tramp-rfn-eshadow-overlay)
|
|
|
|
|
(make-variable-buffer-local 'tramp-rfn-eshadow-overlay)
|
|
|
|
|
|
|
|
|
|
(defun tramp-rfn-eshadow-setup-minibuffer ()
|
|
|
|
|
"Set up a minibuffer for `file-name-shadow-mode'.
|
|
|
|
|
Adds another overlay hiding filename parts according to Tramp's
|
|
|
|
|
special handling of `substitute-in-file-name'."
|
|
|
|
|
(when minibuffer-completing-file-name
|
|
|
|
|
(setq tramp-rfn-eshadow-overlay
|
|
|
|
|
(make-overlay (minibuffer-prompt-end) (minibuffer-prompt-end)))
|
|
|
|
|
;; Copy rfn-eshadow-overlay properties.
|
|
|
|
|
(let ((props (overlay-properties rfn-eshadow-overlay)))
|
|
|
|
|
(while props
|
|
|
|
|
;; The `field' property prevents correct minibuffer
|
|
|
|
|
;; completion; we exclude it.
|
|
|
|
|
(if (not (eq (car props) 'field))
|
|
|
|
|
(overlay-put tramp-rfn-eshadow-overlay (pop props) (pop props))
|
|
|
|
|
(pop props) (pop props))))))
|
|
|
|
|
|
|
|
|
|
(add-hook 'rfn-eshadow-setup-minibuffer-hook
|
2019-02-28 10:33:05 +01:00
|
|
|
|
#'tramp-rfn-eshadow-setup-minibuffer)
|
2019-02-24 11:15:49 +01:00
|
|
|
|
(add-hook 'tramp-unload-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(remove-hook 'rfn-eshadow-setup-minibuffer-hook
|
2019-02-28 10:33:05 +01:00
|
|
|
|
#'tramp-rfn-eshadow-setup-minibuffer)))
|
2019-02-24 11:15:49 +01:00
|
|
|
|
|
|
|
|
|
(defun tramp-rfn-eshadow-update-overlay-regexp ()
|
Adapt Tramp docstrings according to checkdoc
* lisp/net/tramp.el (tramp-backup-directory-alist)
(tramp-echoed-echo-mark-regexp, tramp-syntax-values)
(tramp-lookup-syntax, tramp-build-prefix-format)
(tramp-build-prefix-regexp, tramp-build-method-regexp)
(tramp-build-postfix-method-format)
(tramp-build-postfix-method-regexp)
(tramp-build-prefix-ipv6-format, tramp-build-prefix-ipv6-regexp)
(tramp-build-postfix-ipv6-format)
(tramp-build-postfix-ipv6-regexp)
(tramp-build-postfix-host-format)
(tramp-build-postfix-host-regexp, tramp-unknown-id-string)
(tramp-unknown-id-integer, tramp-build-file-name-regexp)
(tramp-build-completion-file-name-regexp, tramp-chunksize)
(tramp-find-method, tramp-find-user, tramp-find-host)
(tramp-dissect-file-name, tramp-get-buffer)
(tramp-get-connection-buffer, tramp-debug-message, tramp-error)
(with-tramp-connection-property, tramp-run-real-handler)
(tramp-file-name-for-operation, tramp-file-name-handler)
(tramp-completion-file-name-handler)
(tramp-completion-handle-file-name-completion)
(tramp-completion-dissect-file-name)
(tramp-completion-dissect-file-name1)
(tramp-handle-file-name-as-directory)
(tramp-handle-file-name-directory)
(tramp-handle-file-name-nondirectory, tramp-mode-string-to-int)
(tramp-file-mode-from-int):
* lisp/net/tramp-adb.el (tramp-adb-file-name-p):
* lisp/net/tramp-archive.el (tramp-archive-run-real-handler)
(tramp-archive-file-name-handler)
(tramp-archive-dissect-file-name)
(with-parsed-tramp-archive-file-name)
(tramp-archive-gvfs-file-name, tramp-archive-handle-access-file):
* lisp/net/tramp-cmds.el (tramp-list-remote-buffers):
* lisp/net/tramp-compat.el (tramp-unload-file-name-handlers)
(tramp-compat-funcall, tramp-compat-tramp-file-name-slots):
* lisp/net/tramp-ftp.el (tramp-ftp-file-name-handler)
(tramp-ftp-file-name-p):
* lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-p)
(tramp-gvfs-file-name-handler)
(tramp-gvfs-stringify-dbus-message)
(tramp-gvfs-monitor-process-filter)
(tramp-gvfs-handler-mounted-unmounted):
* lisp/net/tramp-integration.el
(tramp-rfn-eshadow-update-overlay-regexp):
* lisp/net/tramp-rclone.el (tramp-rclone-file-name-p)
(tramp-rclone-file-name-handler, tramp-rclone-send-command):
* lisp/net/tramp-sh.el (tramp-sh--quoting-style-options)
(tramp-sh-gio-monitor-process-filter)
(tramp-sh-gvfs-monitor-dir-process-filter)
(tramp-sh-inotifywait-process-filter, tramp-find-executable)
(tramp-set-remote-path, tramp-open-shell, tramp-find-shell)
(tramp-send-command-and-check, tramp-shell-case-fold)
(tramp-get-remote-path):
* lisp/net/tramp-smb.el (tramp-smb-file-name-p)
(tramp-smb-file-name-handler)
(tramp-smb-do-file-attributes-with-stat)
(tramp-smb-handle-substitute-in-file-name)
(tramp-smb-get-stat-capability, tramp-smb-shell-quote-argument):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-p)
(tramp-sudoedit-file-name-handler)
(tramp-sudoedit-send-command-string):
* test/lisp/net/tramp-archive-tests.el (tramp-archive-test-all):
* test/lisp/net/tramp-tests.el (tramp--test-gvfs-p)
(tramp--test-with-proper-process-name-and-buffer)
(tramp-test-all): Adapt docstrings according to `checkdoc'.
2019-11-13 13:10:58 +01:00
|
|
|
|
"An overlay covering the shadowed part of the filename."
|
2019-02-24 11:15:49 +01:00
|
|
|
|
(format "[^%s/~]*\\(/\\|~\\)" tramp-postfix-host-format))
|
|
|
|
|
|
|
|
|
|
;; Package rfn-eshadow is preloaded in Emacs, but for some reason,
|
|
|
|
|
;; it only did (defvar rfn-eshadow-overlay) without giving it a global
|
|
|
|
|
;; value, so it was only declared as dynamically-scoped within the
|
|
|
|
|
;; rfn-eshadow.el file. This is now fixed in Emacs>26.1 but we still need
|
|
|
|
|
;; this defvar here for older releases.
|
|
|
|
|
(defvar rfn-eshadow-overlay)
|
|
|
|
|
|
|
|
|
|
(defun tramp-rfn-eshadow-update-overlay ()
|
|
|
|
|
"Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input.
|
|
|
|
|
This is intended to be used as a minibuffer `post-command-hook' for
|
|
|
|
|
`file-name-shadow-mode'; the minibuffer should have already
|
|
|
|
|
been set up by `rfn-eshadow-setup-minibuffer'."
|
|
|
|
|
;; In remote files name, there is a shadowing just for the local part.
|
|
|
|
|
(ignore-errors
|
|
|
|
|
(let ((end (or (overlay-end rfn-eshadow-overlay)
|
|
|
|
|
(minibuffer-prompt-end)))
|
|
|
|
|
;; We do not want to send any remote command.
|
|
|
|
|
(non-essential t))
|
|
|
|
|
(when (tramp-tramp-file-p (buffer-substring end (point-max)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region
|
|
|
|
|
(1+ (or (string-match-p
|
|
|
|
|
(tramp-rfn-eshadow-update-overlay-regexp)
|
|
|
|
|
(buffer-string) end)
|
|
|
|
|
end))
|
|
|
|
|
(point-max))
|
|
|
|
|
(let ((rfn-eshadow-overlay tramp-rfn-eshadow-overlay)
|
|
|
|
|
(rfn-eshadow-update-overlay-hook nil)
|
|
|
|
|
file-name-handler-alist)
|
|
|
|
|
(move-overlay rfn-eshadow-overlay (point-max) (point-max))
|
|
|
|
|
(rfn-eshadow-update-overlay))))))))
|
|
|
|
|
|
|
|
|
|
(add-hook 'rfn-eshadow-update-overlay-hook
|
2019-02-28 10:33:05 +01:00
|
|
|
|
#'tramp-rfn-eshadow-update-overlay)
|
2019-02-24 11:15:49 +01:00
|
|
|
|
(add-hook 'tramp-unload-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(remove-hook 'rfn-eshadow-update-overlay-hook
|
2019-02-28 10:33:05 +01:00
|
|
|
|
#'tramp-rfn-eshadow-update-overlay)))
|
2019-02-24 11:15:49 +01:00
|
|
|
|
|
|
|
|
|
;;; Integration of eshell.el:
|
|
|
|
|
|
|
|
|
|
;; eshell.el keeps the path in `eshell-path-env'. We must change it
|
|
|
|
|
;; when `default-directory' points to another host.
|
|
|
|
|
(defun tramp-eshell-directory-change ()
|
|
|
|
|
"Set `eshell-path-env' to $PATH of the host related to `default-directory'."
|
|
|
|
|
;; Remove last element of `(exec-path)', which is `exec-directory'.
|
|
|
|
|
;; Use `path-separator' as it does eshell.
|
|
|
|
|
(setq eshell-path-env
|
|
|
|
|
(mapconcat
|
2019-02-28 10:33:05 +01:00
|
|
|
|
#'identity (butlast (tramp-compat-exec-path)) path-separator)))
|
2019-02-24 11:15:49 +01:00
|
|
|
|
|
2019-06-28 16:32:12 +02:00
|
|
|
|
(with-eval-after-load 'esh-util
|
2019-06-29 12:18:59 +02:00
|
|
|
|
(add-hook 'eshell-mode-hook
|
|
|
|
|
#'tramp-eshell-directory-change)
|
|
|
|
|
(add-hook 'eshell-directory-change-hook
|
|
|
|
|
#'tramp-eshell-directory-change)
|
|
|
|
|
(add-hook 'tramp-integration-unload-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(remove-hook 'eshell-mode-hook
|
|
|
|
|
#'tramp-eshell-directory-change)
|
|
|
|
|
(remove-hook 'eshell-directory-change-hook
|
|
|
|
|
#'tramp-eshell-directory-change))))
|
2019-02-24 11:15:49 +01:00
|
|
|
|
|
|
|
|
|
;;; Integration of recentf.el:
|
|
|
|
|
|
|
|
|
|
(defun tramp-recentf-exclude-predicate (name)
|
|
|
|
|
"Predicate to exclude a remote file name from recentf.
|
|
|
|
|
NAME must be equal to `tramp-current-connection'."
|
|
|
|
|
(when (file-remote-p name)
|
|
|
|
|
(tramp-file-name-equal-p
|
|
|
|
|
(tramp-dissect-file-name name) (car tramp-current-connection))))
|
|
|
|
|
|
|
|
|
|
(defun tramp-recentf-cleanup (vec)
|
|
|
|
|
"Remove all file names related to VEC from recentf."
|
|
|
|
|
(when (bound-and-true-p recentf-list)
|
|
|
|
|
(let ((tramp-current-connection `(,vec))
|
|
|
|
|
(recentf-exclude '(tramp-recentf-exclude-predicate)))
|
|
|
|
|
(recentf-cleanup))))
|
|
|
|
|
|
2019-02-25 11:59:52 +01:00
|
|
|
|
(defun tramp-recentf-cleanup-all ()
|
|
|
|
|
"Remove all remote file names from recentf."
|
|
|
|
|
(when (bound-and-true-p recentf-list)
|
|
|
|
|
(let ((recentf-exclude '(file-remote-p)))
|
|
|
|
|
(recentf-cleanup))))
|
|
|
|
|
|
2019-06-28 16:32:12 +02:00
|
|
|
|
(with-eval-after-load 'recentf
|
2019-06-29 12:18:59 +02:00
|
|
|
|
(add-hook 'tramp-cleanup-connection-hook
|
|
|
|
|
#'tramp-recentf-cleanup)
|
|
|
|
|
(add-hook 'tramp-cleanup-all-connections-hook
|
|
|
|
|
#'tramp-recentf-cleanup-all)
|
|
|
|
|
(add-hook 'tramp-integration-unload-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(remove-hook 'tramp-cleanup-connection-hook
|
|
|
|
|
#'tramp-recentf-cleanup)
|
|
|
|
|
(remove-hook 'tramp-cleanup-all-connections-hook
|
|
|
|
|
#'tramp-recentf-cleanup-all))))
|
2019-02-25 11:59:52 +01:00
|
|
|
|
|
2019-11-20 13:45:30 +01:00
|
|
|
|
;;; Integration of ido.el:
|
|
|
|
|
|
|
|
|
|
(with-eval-after-load 'ido
|
|
|
|
|
(add-to-list 'ido-read-file-name-non-ido 'tramp-rename-files)
|
2019-12-07 13:40:04 +01:00
|
|
|
|
(add-to-list 'ido-read-file-name-non-ido 'tramp-these-rename-files)
|
|
|
|
|
(add-hook 'tramp-integration-unload-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(setq ido-read-file-name-non-ido
|
|
|
|
|
(delq 'tramp-these-rename-files ido-read-file-name-non-ido)
|
|
|
|
|
ido-read-file-name-non-ido
|
|
|
|
|
(delq 'tramp-rename-files ido-read-file-name-non-ido)))))
|
2019-11-20 13:45:30 +01:00
|
|
|
|
|
|
|
|
|
;;; Integration of ivy.el:
|
|
|
|
|
|
|
|
|
|
(with-eval-after-load 'ivy
|
|
|
|
|
(add-to-list 'ivy-completing-read-handlers-alist
|
|
|
|
|
'(tramp-rename-files . completing-read-default))
|
|
|
|
|
(add-to-list 'ivy-completing-read-handlers-alist
|
2019-12-07 13:40:04 +01:00
|
|
|
|
'(tramp-these-rename-files . completing-read-default))
|
|
|
|
|
(add-hook
|
|
|
|
|
'tramp-integration-unload-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(setq ivy-completing-read-handlers-alist
|
|
|
|
|
(delete
|
|
|
|
|
(assq 'tramp-these-rename-files ivy-completing-read-handlers-alist)
|
|
|
|
|
ivy-completing-read-handlers-alist)
|
|
|
|
|
ivy-completing-read-handlers-alist
|
|
|
|
|
(delete
|
|
|
|
|
(assq 'tramp-rename-files ivy-completing-read-handlers-alist)
|
|
|
|
|
ivy-completing-read-handlers-alist)))))
|
2019-11-20 13:45:30 +01:00
|
|
|
|
|
2019-12-06 19:28:01 +01:00
|
|
|
|
;;; Integration of info-look.el:
|
|
|
|
|
|
|
|
|
|
(with-eval-after-load 'info-look
|
|
|
|
|
;; Create a pseudo mode `tramp-info-lookup-mode' for Tramp symbol lookup.
|
|
|
|
|
(info-lookup-maybe-add-help
|
|
|
|
|
:mode 'tramp-info-lookup-mode :topic 'symbol
|
|
|
|
|
:regexp "[^][()`'‘’,\" \t\n]+"
|
|
|
|
|
:doc-spec '(("(tramp)Function Index" nil "^ -+ .*: " "\\( \\|$\\)")
|
|
|
|
|
("(tramp)Variable Index" nil "^ -+ .*: " "\\( \\|$\\)")))
|
|
|
|
|
|
2019-12-07 13:40:04 +01:00
|
|
|
|
(add-hook
|
|
|
|
|
'tramp-integration-unload-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(setcdr (assq 'symbol info-lookup-alist)
|
|
|
|
|
(delete (info-lookup->mode-value 'symbol 'tramp-info-lookup-mode)
|
|
|
|
|
(info-lookup->topic-value 'symbol)))
|
|
|
|
|
(setcdr (info-lookup->cache 'symbol)
|
|
|
|
|
(delete (info-lookup->mode-cache 'symbol 'tramp-info-lookup-mode)
|
|
|
|
|
(info-lookup->topic-cache 'symbol)))))
|
|
|
|
|
|
2019-12-06 19:28:01 +01:00
|
|
|
|
(dolist (mode (mapcar 'car (info-lookup->topic-value 'symbol)))
|
2019-12-07 13:40:04 +01:00
|
|
|
|
;; Add `tramp-info-lookup-mode' to `other-modes' for either
|
|
|
|
|
;; `emacs-lisp-mode' itself, or to modes which use
|
|
|
|
|
;; `emacs-lisp-mode' as `other-modes'. Reset `info-lookup-cache'.
|
2019-12-06 19:28:01 +01:00
|
|
|
|
(when (and (or (equal mode 'emacs-lisp-mode)
|
2019-12-07 13:40:04 +01:00
|
|
|
|
(memq
|
2019-12-06 19:28:01 +01:00
|
|
|
|
'emacs-lisp-mode (info-lookup->other-modes 'symbol mode)))
|
2019-12-07 13:40:04 +01:00
|
|
|
|
(not (memq 'tramp-info-lookup-mode
|
|
|
|
|
(info-lookup->other-modes 'symbol mode))))
|
|
|
|
|
(setcdr (info-lookup->mode-value 'symbol mode)
|
|
|
|
|
(append (butlast (cdr (info-lookup->mode-value 'symbol mode)))
|
|
|
|
|
`((tramp-info-lookup-mode
|
|
|
|
|
. ,(info-lookup->other-modes 'symbol mode)))))
|
|
|
|
|
(setcdr (info-lookup->cache 'symbol)
|
|
|
|
|
(delete (info-lookup->mode-cache 'symbol mode)
|
|
|
|
|
(info-lookup->topic-cache 'symbol)))
|
|
|
|
|
|
|
|
|
|
(add-hook
|
|
|
|
|
'tramp-integration-unload-hook
|
|
|
|
|
`(lambda ()
|
|
|
|
|
(setcdr (info-lookup->mode-value 'symbol ',mode)
|
|
|
|
|
(append (butlast
|
|
|
|
|
(cdr (info-lookup->mode-value 'symbol ',mode)))
|
|
|
|
|
(list
|
|
|
|
|
(delq 'tramp-info-lookup-mode
|
|
|
|
|
(info-lookup->other-modes 'symbol ',mode)))))
|
|
|
|
|
(setcdr (info-lookup->cache 'symbol)
|
|
|
|
|
(delete (info-lookup->mode-cache 'symbol ',mode)
|
|
|
|
|
(info-lookup->topic-cache 'symbol))))))))
|
2019-12-06 19:28:01 +01:00
|
|
|
|
|
2019-03-09 16:44:24 +01:00
|
|
|
|
;;; Default connection-local variables for Tramp:
|
|
|
|
|
|
|
|
|
|
(defconst tramp-connection-local-default-profile
|
2019-06-10 17:48:08 +02:00
|
|
|
|
'((shell-file-name . "/bin/sh")
|
|
|
|
|
(shell-command-switch . "-c"))
|
2019-03-09 16:44:24 +01:00
|
|
|
|
"Default connection-local variables for remote connections.")
|
|
|
|
|
|
|
|
|
|
;; `connection-local-set-profile-variables' and
|
|
|
|
|
;; `connection-local-set-profiles' exists since Emacs 26.1.
|
2019-06-28 16:32:12 +02:00
|
|
|
|
(with-eval-after-load 'shell
|
2019-06-29 12:18:59 +02:00
|
|
|
|
(tramp-compat-funcall
|
|
|
|
|
'connection-local-set-profile-variables
|
|
|
|
|
'tramp-connection-local-default-profile
|
|
|
|
|
tramp-connection-local-default-profile)
|
|
|
|
|
(tramp-compat-funcall
|
|
|
|
|
'connection-local-set-profiles
|
|
|
|
|
`(:application tramp)
|
|
|
|
|
'tramp-connection-local-default-profile))
|
2019-03-09 16:44:24 +01:00
|
|
|
|
|
2019-02-24 11:15:49 +01:00
|
|
|
|
(add-hook 'tramp-unload-hook
|
|
|
|
|
(lambda () (unload-feature 'tramp-integration 'force)))
|
|
|
|
|
|
|
|
|
|
(provide 'tramp-integration)
|
|
|
|
|
|
|
|
|
|
;;; tramp-integration.el ends here
|