From cbcb5718761dc645c291110ceb7250628510b1dc Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Sun, 24 Feb 2019 11:15:49 +0100 Subject: [PATCH] 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 --- doc/misc/tramp.texi | 3 +- lisp/net/tramp-cmds.el | 11 ++- lisp/net/tramp-integration.el | 159 ++++++++++++++++++++++++++++++++++ lisp/net/tramp.el | 98 +-------------------- 4 files changed, 171 insertions(+), 100 deletions(-) create mode 100644 lisp/net/tramp-integration.el diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 7587059f393..3630c317b2f 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3166,7 +3166,8 @@ interactively, this command lists active remote connections in the minibuffer. Each connection is of the format @file{@trampfn{method,user@@host,}}. Flushing remote connections also cleans the password cache (@pxref{Password handling}), file cache, -connection cache (@pxref{Connection caching}), and connection buffers. +connection cache (@pxref{Connection caching}), recentf cache +(@pxref{File Conveniences, , , emacs}), and connection buffers. @end deffn @deffn Command tramp-cleanup-this-connection diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 325d19361cb..38e440e0930 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -118,7 +118,10 @@ When called interactively, a Tramp connection has to be selected." (unless keep-debug (get-buffer (tramp-debug-buffer-name vec))) (tramp-get-connection-property vec "process-buffer" nil))) - (when (bufferp buf) (kill-buffer buf))))) + (when (bufferp buf) (kill-buffer buf))) + + ;; Remove recentf files. + (tramp-recentf-cleanup vec))) ;;;###tramp-autoload (defun tramp-cleanup-this-connection () @@ -162,7 +165,11 @@ This includes password cache, file cache, connection cache, buffers." ;; Remove buffers. (dolist (name (tramp-list-tramp-buffers)) - (when (bufferp (get-buffer name)) (kill-buffer name)))) + (when (bufferp (get-buffer name)) (kill-buffer name))) + + ;; Remove recentf files. + (dolist (v (tramp-list-connections)) + (tramp-recentf-cleanup v))) ;;;###tramp-autoload (defun tramp-cleanup-all-buffers () 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 +;; 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 . + +;;; 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 diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index efe75033f77..c2636274a34 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -56,13 +56,13 @@ ;;; Code: (require 'tramp-compat) +(require 'tramp-integration) (require 'trampver) ;; Pacify byte-compiler. (require 'cl-lib) (declare-function netrc-parse "netrc") (defvar auto-save-file-name-transforms) -(defvar eshell-path-env) (defvar ls-lisp-use-insert-directory-program) (defvar outline-regexp) @@ -2056,77 +2056,6 @@ For definition of that list see `tramp-set-completion-function'." ;; The method related defaults. (cdr (assoc method tramp-completion-function-alist)))) -;;; 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))) - ;; Inodes don't exist for some file systems. Therefore we must ;; generate virtual ones. Used in `find-buffer-visiting'. The method ;; applied might be not so efficient (Ange-FTP uses hashes). But @@ -4899,31 +4828,6 @@ Only works for Bourne-like shells." (lambda () (remove-hook 'interrupt-process-functions #'tramp-interrupt-process)))) -;;; 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))))) - ;; Checklist for `tramp-unload-hook' ;; - Unload all `tramp-*' packages ;; - Reset `file-name-handler-alist' -- 2.39.2