summaryrefslogtreecommitdiff
path: root/lisp/net/tramp-integration.el
diff options
context:
space:
mode:
authorMichael Albinus <michael.albinus@gmx.de>2019-02-24 11:15:49 +0100
committerMichael Albinus <michael.albinus@gmx.de>2019-02-24 11:15:49 +0100
commitcbcb5718761dc645c291110ceb7250628510b1dc (patch)
tree038ecc23b83b8e6a1ff6b8d33b372af7d03d21a6 /lisp/net/tramp-integration.el
parent975893b229072aa1b5565cc1a73987fa83ed5b21 (diff)
downloademacs-cbcb5718761dc645c291110ceb7250628510b1dc.tar.gz
Cleanup also recentf files in Tramp
* doc/misc/tramp.texi (Cleanup remote connections): Mention also recentf cache. * lisp/net/tramp-cmds.el (tramp-cleanup-connection) (tramp-cleanup-all-connections): Call `tramp-recentf-cleanup'. * lisp/net/tramp-integration.el: New package. * lisp/net/tramp.el (tramp-rfn-eshadow-overlay) (tramp-rfn-eshadow-setup-minibuffer) (tramp-rfn-eshadow-update-overlay-regexp) (tramp-rfn-eshadow-update-overlay): (tramp-eshell-directory-change): Move to tramp-integration.el
Diffstat (limited to 'lisp/net/tramp-integration.el')
-rw-r--r--lisp/net/tramp-integration.el159
1 files changed, 159 insertions, 0 deletions
diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el
new file mode 100644
index 00000000000..f3f95f1b69c
--- /dev/null
+++ b/lisp/net/tramp-integration.el
@@ -0,0 +1,159 @@
+;;; tramp-integration.el --- Tramp integration into other packages -*- lexical-binding:t -*-
+
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; 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:
+
+;; Pacify byte-compiler.
+(require 'cl-lib)
+(declare-function tramp-compat-exec-path "tramp")
+(declare-function tramp-dissect-file-name "tramp")
+(declare-function tramp-file-name-equal-p "tramp")
+(declare-function tramp-tramp-file-p "tramp")
+(declare-function recentf-cleanup "recentf")
+(defvar eshell-path-env)
+(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
+ 'tramp-rfn-eshadow-setup-minibuffer)
+(add-hook 'tramp-unload-hook
+ (lambda ()
+ (remove-hook 'rfn-eshadow-setup-minibuffer-hook
+ 'tramp-rfn-eshadow-setup-minibuffer)))
+
+(defun tramp-rfn-eshadow-update-overlay-regexp ()
+ (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
+ 'tramp-rfn-eshadow-update-overlay)
+(add-hook 'tramp-unload-hook
+ (lambda ()
+ (remove-hook 'rfn-eshadow-update-overlay-hook
+ 'tramp-rfn-eshadow-update-overlay)))
+
+;;; 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
+ 'identity (butlast (tramp-compat-exec-path)) path-separator)))
+
+(eval-after-load "esh-util"
+ '(progn
+ (add-hook 'eshell-mode-hook
+ 'tramp-eshell-directory-change)
+ (add-hook 'eshell-directory-change-hook
+ 'tramp-eshell-directory-change)
+ (add-hook 'tramp-unload-hook
+ (lambda ()
+ (remove-hook 'eshell-mode-hook
+ 'tramp-eshell-directory-change)
+ (remove-hook 'eshell-directory-change-hook
+ 'tramp-eshell-directory-change)))))
+
+;;; 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))))
+
+(add-hook 'tramp-unload-hook
+ (lambda () (unload-feature 'tramp-integration 'force)))
+
+(provide 'tramp-integration)
+
+;;; tramp-integration.el ends here