mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
Optimize host name completion in Tramp
* lisp/net/tramp-adb.el (tramp-adb-maybe-open-connection): * lisp/net/tramp-gvfs.el (tramp-gvfs-maybe-open-connection): * lisp/net/tramp-rclone.el (tramp-rclone-maybe-open-connection): * lisp/net/tramp-sh.el (tramp-maybe-open-connection): * lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-maybe-open-connection): Throw `non-essential' at the beginning of the function. * lisp/net/tramp.el (tramp-handle-file-exists-p): * lisp/net/tramp-sh.el (tramp-sh-handle-file-exists-p): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-file-exists-p): Run only when host is connectable. This is due to host name completion, which shall be optimized. * lisp/net/tramp-smb.el (tramp-smb-do-file-attributes-with-stat) (tramp-smb-get-file-entries): Access connection buffer only after sending the command. * lisp/net/tramp.el (tramp-get-buffer, tramp-get-connection-buffer): New argument DONT-CREATE. (tramp-message): Use it. (tramp-get-mutex): Check, whether host is connectable. (tramp-file-name-handler): Set thread only when host is connectable. (tramp-connectable-p): Allow also VEC as argument. (tramp-completion-handle-file-name-completion): Do not expand directory.
This commit is contained in:
parent
997415504c
commit
5e8d477d63
7 changed files with 116 additions and 116 deletions
|
|
@ -1191,6 +1191,10 @@ FMT and ARGS are passed to `error'."
|
|||
"Maybe open a connection VEC.
|
||||
Does not do anything if a connection is already open, but re-opens the
|
||||
connection if a previous connection has died for some reason."
|
||||
;; During completion, don't reopen a new connection.
|
||||
(unless (tramp-connectable-p vec)
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(let* ((buf (tramp-get-connection-buffer vec))
|
||||
(p (get-buffer-process buf))
|
||||
(host (tramp-file-name-host vec))
|
||||
|
|
@ -1204,14 +1208,6 @@ connection if a previous connection has died for some reason."
|
|||
(tramp-error vec 'file-error "Cannot switch to user `%s'" user))
|
||||
|
||||
(unless (process-live-p p)
|
||||
;; During completion, don't reopen a new connection. We check
|
||||
;; this for the process related to `tramp-buffer-name';
|
||||
;; otherwise `start-file-process' wouldn't run ever when
|
||||
;; `non-essential' is non-nil.
|
||||
(when (and (tramp-completion-mode-p)
|
||||
(null (get-process (tramp-buffer-name vec))))
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(save-match-data
|
||||
(when (and p (processp p)) (delete-process p))
|
||||
(if (zerop (length device))
|
||||
|
|
|
|||
|
|
@ -1787,6 +1787,10 @@ This is relevant for GNOME Online Accounts."
|
|||
"Maybe open a connection VEC.
|
||||
Does not do anything if a connection is already open, but re-opens the
|
||||
connection if a previous connection has died for some reason."
|
||||
;; During completion, don't reopen a new connection.
|
||||
(unless (tramp-connectable-p vec)
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
;; We set the file name, in case there are incoming D-Bus signals or
|
||||
;; D-Bus errors.
|
||||
(setq tramp-gvfs-dbus-event-vector vec)
|
||||
|
|
|
|||
|
|
@ -520,19 +520,14 @@ file names."
|
|||
"Maybe open a connection VEC.
|
||||
Does not do anything if a connection is already open, but re-opens the
|
||||
connection if a previous connection has died for some reason."
|
||||
;; During completion, don't reopen a new connection.
|
||||
(unless (tramp-connectable-p vec)
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(let ((host (tramp-file-name-host vec)))
|
||||
(when (rassoc `(,host) (tramp-rclone-parse-device-names nil))
|
||||
(if (zerop (length host))
|
||||
(tramp-error vec 'file-error "Storage %s not connected" host))
|
||||
|
||||
;; During completion, don't reopen a new connection. We check
|
||||
;; this for the process related to `tramp-buffer-name';
|
||||
;; otherwise `start-file-process' wouldn't run ever when
|
||||
;; `non-essential' is non-nil.
|
||||
(when (and (tramp-completion-mode-p)
|
||||
(null (get-process (tramp-buffer-name vec))))
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
;; We need a process bound to the connection buffer. Therefore,
|
||||
;; we create a dummy process. Maybe there is a better solution?
|
||||
(unless (get-buffer-process (tramp-get-connection-buffer vec))
|
||||
|
|
|
|||
|
|
@ -1198,18 +1198,22 @@ component is used as the target of the symlink."
|
|||
|
||||
(defun tramp-sh-handle-file-exists-p (filename)
|
||||
"Like `file-exists-p' for Tramp files."
|
||||
(with-parsed-tramp-file-name filename nil
|
||||
(with-tramp-file-property v localname "file-exists-p"
|
||||
(or (not (null (tramp-get-file-property
|
||||
v localname "file-attributes-integer" nil)))
|
||||
(not (null (tramp-get-file-property
|
||||
v localname "file-attributes-string" nil)))
|
||||
(tramp-send-command-and-check
|
||||
v
|
||||
(format
|
||||
"%s %s"
|
||||
(tramp-get-file-exists-command v)
|
||||
(tramp-shell-quote-argument localname)))))))
|
||||
;; `file-exists-p' is used as predicate in file name completion.
|
||||
;; We don't want to run it when `non-essential' is t, or there is
|
||||
;; no connection process yet.
|
||||
(when (tramp-connectable-p filename)
|
||||
(with-parsed-tramp-file-name filename nil
|
||||
(with-tramp-file-property v localname "file-exists-p"
|
||||
(or (not (null (tramp-get-file-property
|
||||
v localname "file-attributes-integer" nil)))
|
||||
(not (null (tramp-get-file-property
|
||||
v localname "file-attributes-string" nil)))
|
||||
(tramp-send-command-and-check
|
||||
v
|
||||
(format
|
||||
"%s %s"
|
||||
(tramp-get-file-exists-command v)
|
||||
(tramp-shell-quote-argument localname))))))))
|
||||
|
||||
(defun tramp-sh-handle-file-attributes (filename &optional id-format)
|
||||
"Like `file-attributes' for Tramp files."
|
||||
|
|
@ -4762,6 +4766,10 @@ If there is just some editing, retry it after 5 seconds."
|
|||
"Maybe open a connection VEC.
|
||||
Does not do anything if a connection is already open, but re-opens the
|
||||
connection if a previous connection has died for some reason."
|
||||
;; During completion, don't reopen a new connection.
|
||||
(unless (tramp-connectable-p vec)
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(let ((p (tramp-get-connection-process vec))
|
||||
(process-name (tramp-get-connection-property vec "process-name" nil))
|
||||
(process-environment (copy-sequence process-environment))
|
||||
|
|
@ -4806,15 +4814,6 @@ connection if a previous connection has died for some reason."
|
|||
;; New connection must be opened.
|
||||
(condition-case err
|
||||
(unless (process-live-p p)
|
||||
|
||||
;; During completion, don't reopen a new connection. We
|
||||
;; check this for the process related to
|
||||
;; `tramp-buffer-name'; otherwise `start-file-process'
|
||||
;; wouldn't run ever when `non-essential' is non-nil.
|
||||
(when (and (tramp-completion-mode-p)
|
||||
(null (get-process (tramp-buffer-name vec))))
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(with-tramp-progress-reporter
|
||||
vec 3
|
||||
(if (zerop (length (tramp-file-name-user vec)))
|
||||
|
|
|
|||
|
|
@ -832,12 +832,12 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
|
|||
"Implement `file-attributes' for Tramp files using stat command."
|
||||
(tramp-message
|
||||
vec 5 "file attributes with stat: %s" (tramp-file-name-localname vec))
|
||||
(with-current-buffer (tramp-get-connection-buffer vec)
|
||||
(let* (size id link uid gid atime mtime ctime mode inode)
|
||||
(when (tramp-smb-send-command
|
||||
vec (format "stat \"%s\"" (tramp-smb-get-localname vec)))
|
||||
(let* (size id link uid gid atime mtime ctime mode inode)
|
||||
(when (tramp-smb-send-command
|
||||
vec (format "stat \"%s\"" (tramp-smb-get-localname vec)))
|
||||
|
||||
;; Loop the listing.
|
||||
;; Loop the listing.
|
||||
(with-current-buffer (tramp-get-connection-buffer vec)
|
||||
(goto-char (point-min))
|
||||
(unless (re-search-forward tramp-smb-errors nil t)
|
||||
(while (not (eobp))
|
||||
|
|
@ -1628,40 +1628,40 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
|
|||
(with-parsed-tramp-file-name (file-name-as-directory directory) nil
|
||||
(setq localname (or localname "/"))
|
||||
(with-tramp-file-property v localname "file-entries"
|
||||
(with-current-buffer (tramp-get-connection-buffer v)
|
||||
(let* ((share (tramp-smb-get-share v))
|
||||
(cache (tramp-get-connection-property v "share-cache" nil))
|
||||
res entry)
|
||||
(let* ((share (tramp-smb-get-share v))
|
||||
(cache (tramp-get-connection-property v "share-cache" nil))
|
||||
res entry)
|
||||
|
||||
(if (and (not share) cache)
|
||||
;; Return cached shares.
|
||||
(setq res cache)
|
||||
(if (and (not share) cache)
|
||||
;; Return cached shares.
|
||||
(setq res cache)
|
||||
|
||||
;; Read entries.
|
||||
(if share
|
||||
(tramp-smb-send-command
|
||||
v (format "dir \"%s*\"" (tramp-smb-get-localname v)))
|
||||
;; `tramp-smb-maybe-open-connection' lists also the share names.
|
||||
(tramp-smb-maybe-open-connection v))
|
||||
;; Read entries.
|
||||
(if share
|
||||
(tramp-smb-send-command
|
||||
v (format "dir \"%s*\"" (tramp-smb-get-localname v)))
|
||||
;; `tramp-smb-maybe-open-connection' lists also the share names.
|
||||
(tramp-smb-maybe-open-connection v))
|
||||
|
||||
;; Loop the listing.
|
||||
;; Loop the listing.
|
||||
(with-current-buffer (tramp-get-connection-buffer v)
|
||||
(goto-char (point-min))
|
||||
(if (re-search-forward tramp-smb-errors nil t)
|
||||
(tramp-error v 'file-error "%s `%s'" (match-string 0) directory)
|
||||
(while (not (eobp))
|
||||
(setq entry (tramp-smb-read-file-entry share))
|
||||
(forward-line)
|
||||
(when entry (push entry res))))
|
||||
(when entry (push entry res)))))
|
||||
|
||||
;; Cache share entries.
|
||||
(unless share
|
||||
(tramp-set-connection-property v "share-cache" res)))
|
||||
;; Cache share entries.
|
||||
(unless share
|
||||
(tramp-set-connection-property v "share-cache" res)))
|
||||
|
||||
;; Add directory itself.
|
||||
(push '("" "drwxrwxrwx" 0 (0 0)) res)
|
||||
;; Add directory itself.
|
||||
(push '("" "drwxrwxrwx" 0 (0 0)) res)
|
||||
|
||||
;; Return entries.
|
||||
(delq nil res))))))
|
||||
;; Return entries.
|
||||
(delq nil res)))))
|
||||
|
||||
;; Return either a share name (if SHARE is nil), or a file name.
|
||||
;;
|
||||
|
|
@ -1855,6 +1855,10 @@ Does not do anything if a connection is already open, but re-opens the
|
|||
connection if a previous connection has died for some reason.
|
||||
If ARGUMENT is non-nil, use it as argument for
|
||||
`tramp-smb-winexe-program', and suppress any checks."
|
||||
;; During completion, don't reopen a new connection.
|
||||
(unless (tramp-connectable-p vec)
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(let* ((share (tramp-smb-get-share vec))
|
||||
(buf (tramp-get-connection-buffer vec))
|
||||
(p (get-buffer-process buf)))
|
||||
|
|
@ -1909,15 +1913,6 @@ If ARGUMENT is non-nil, use it as argument for
|
|||
(string-equal
|
||||
share
|
||||
(tramp-get-connection-property p "smb-share" ""))))
|
||||
|
||||
;; During completion, don't reopen a new connection. We
|
||||
;; check this for the process related to
|
||||
;; `tramp-buffer-name'; otherwise `start-file-process'
|
||||
;; wouldn't run ever when `non-essential' is non-nil.
|
||||
(when (and (tramp-completion-mode-p)
|
||||
(null (get-process (tramp-buffer-name vec))))
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(save-match-data
|
||||
;; There might be unread output from checking for share names.
|
||||
(when buf (with-current-buffer buf (erase-buffer)))
|
||||
|
|
|
|||
|
|
@ -424,10 +424,14 @@ the result will be a local, non-Tramp, file name."
|
|||
|
||||
(defun tramp-sudoedit-handle-file-exists-p (filename)
|
||||
"Like `file-exists-p' for Tramp files."
|
||||
(with-parsed-tramp-file-name filename nil
|
||||
(with-tramp-file-property v localname "file-exists-p"
|
||||
(tramp-sudoedit-send-command
|
||||
v "test" "-e" (tramp-compat-file-name-unquote localname)))))
|
||||
;; `file-exists-p' is used as predicate in file name completion.
|
||||
;; We don't want to run it when `non-essential' is t, or there is
|
||||
;; no connection process yet.
|
||||
(when (tramp-connectable-p filename)
|
||||
(with-parsed-tramp-file-name filename nil
|
||||
(with-tramp-file-property v localname "file-exists-p"
|
||||
(tramp-sudoedit-send-command
|
||||
v "test" "-e" (tramp-compat-file-name-unquote localname))))))
|
||||
|
||||
(defun tramp-sudoedit-handle-file-name-all-completions (filename directory)
|
||||
"Like `file-name-all-completions' for Tramp files."
|
||||
|
|
@ -760,18 +764,13 @@ Remove unneeded output."
|
|||
"Maybe open a connection VEC.
|
||||
Does not do anything if a connection is already open, but re-opens the
|
||||
connection if a previous connection has died for some reason."
|
||||
;; During completion, don't reopen a new connection.
|
||||
(unless (tramp-connectable-p vec)
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
;; We need a process bound to the connection buffer. Therefore, we
|
||||
;; create a dummy process. Maybe there is a better solution?
|
||||
(unless (tramp-get-connection-process vec)
|
||||
|
||||
;; During completion, don't reopen a new connection. We check
|
||||
;; this for the process related to `tramp-buffer-name'; otherwise
|
||||
;; `start-file-process' wouldn't run ever when `non-essential' is
|
||||
;; non-nil.
|
||||
(when (and (tramp-completion-mode-p)
|
||||
(null (get-process (tramp-buffer-name vec))))
|
||||
(throw 'non-essential 'non-essential))
|
||||
|
||||
(let ((p (make-network-process
|
||||
:name (tramp-get-connection-name vec)
|
||||
:buffer (tramp-get-connection-buffer vec)
|
||||
|
|
|
|||
|
|
@ -1566,25 +1566,27 @@ necessary only. This function will be used in file name completion."
|
|||
tramp-postfix-host-format))
|
||||
(when localname localname)))
|
||||
|
||||
(defun tramp-get-buffer (vec)
|
||||
(defun tramp-get-buffer (vec &optional dont-create)
|
||||
"Get the connection buffer to be used for VEC."
|
||||
(or (get-buffer (tramp-buffer-name vec))
|
||||
(with-current-buffer (get-buffer-create (tramp-buffer-name vec))
|
||||
;; We use the existence of connection property "process-buffer"
|
||||
;; as indication, whether a connection is active.
|
||||
(tramp-set-connection-property
|
||||
vec "process-buffer"
|
||||
(tramp-get-connection-property vec "process-buffer" nil))
|
||||
(setq buffer-undo-list t
|
||||
default-directory (tramp-make-tramp-file-name vec 'noloc 'nohop))
|
||||
(current-buffer))))
|
||||
(unless dont-create
|
||||
(with-current-buffer (get-buffer-create (tramp-buffer-name vec))
|
||||
;; We use the existence of connection property "process-buffer"
|
||||
;; as indication, whether a connection is active.
|
||||
(tramp-set-connection-property
|
||||
vec "process-buffer"
|
||||
(tramp-get-connection-property vec "process-buffer" nil))
|
||||
(setq buffer-undo-list t
|
||||
default-directory
|
||||
(tramp-make-tramp-file-name vec 'noloc 'nohop))
|
||||
(current-buffer)))))
|
||||
|
||||
(defun tramp-get-connection-buffer (vec)
|
||||
(defun tramp-get-connection-buffer (vec &optional dont-create)
|
||||
"Get the connection buffer to be used for VEC.
|
||||
In case a second asynchronous communication has been started, it is different
|
||||
from `tramp-get-buffer'."
|
||||
(or (tramp-get-connection-property vec "process-buffer" nil)
|
||||
(tramp-get-buffer vec)))
|
||||
(tramp-get-buffer vec dont-create)))
|
||||
|
||||
(defun tramp-get-connection-name (vec)
|
||||
"Get the connection name to be used for VEC.
|
||||
|
|
@ -1770,14 +1772,15 @@ applicable)."
|
|||
;; Log only when there is a minimum level.
|
||||
(when (>= tramp-verbose 4)
|
||||
(let ((tramp-verbose 0))
|
||||
;; Append connection buffer for error messages.
|
||||
;; Append connection buffer for error messages, if exists.
|
||||
(when (= level 1)
|
||||
(with-current-buffer
|
||||
(if (processp vec-or-proc)
|
||||
(process-buffer vec-or-proc)
|
||||
(tramp-get-connection-buffer vec-or-proc))
|
||||
(setq fmt-string (concat fmt-string "\n%s")
|
||||
arguments (append arguments (list (buffer-string))))))
|
||||
(ignore-errors
|
||||
(with-current-buffer
|
||||
(if (processp vec-or-proc)
|
||||
(process-buffer vec-or-proc)
|
||||
(tramp-get-connection-buffer vec-or-proc 'dont-create))
|
||||
(setq fmt-string (concat fmt-string "\n%s")
|
||||
arguments (append arguments (list (buffer-string)))))))
|
||||
;; Translate proc to vec.
|
||||
(when (processp vec-or-proc)
|
||||
(setq vec-or-proc (process-get vec-or-proc 'vector))))
|
||||
|
|
@ -2517,16 +2520,22 @@ Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'."
|
|||
;; This variable has been obsoleted in Emacs 26.
|
||||
tramp-completion-mode))
|
||||
|
||||
(defun tramp-connectable-p (filename)
|
||||
(defun tramp-connectable-p (vec-or-filename)
|
||||
"Check, whether it is possible to connect the remote host w/o side-effects.
|
||||
This is true, if either the remote host is already connected, or if we are
|
||||
not in completion mode."
|
||||
(let (tramp-verbose)
|
||||
(and (tramp-tramp-file-p filename)
|
||||
(or (not (tramp-completion-mode-p))
|
||||
(process-live-p
|
||||
(tramp-get-connection-process
|
||||
(tramp-dissect-file-name filename)))))))
|
||||
(let (tramp-verbose
|
||||
(vec
|
||||
(cond
|
||||
((tramp-file-name-p vec-or-filename) vec-or-filename)
|
||||
((tramp-tramp-file-p vec-or-filename)
|
||||
(tramp-dissect-file-name vec-or-filename)))))
|
||||
(when vec
|
||||
(or ;; We check this for the process related to
|
||||
;; `tramp-buffer-name'; otherwise `start-file-process'
|
||||
;; wouldn't run ever when `non-essential' is non-nil.
|
||||
(process-live-p (get-process (tramp-buffer-name vec)))
|
||||
(not (tramp-completion-mode-p))))))
|
||||
|
||||
;; Method, host name and user name completion.
|
||||
;; `tramp-completion-dissect-file-name' returns a list of
|
||||
|
|
@ -2606,8 +2615,7 @@ not in completion mode."
|
|||
(try-completion
|
||||
filename
|
||||
(mapcar #'list (file-name-all-completions filename directory))
|
||||
(when (and predicate
|
||||
(tramp-connectable-p (expand-file-name filename directory)))
|
||||
(when (and predicate (tramp-connectable-p directory))
|
||||
(lambda (x) (funcall predicate (expand-file-name (car x) directory))))))
|
||||
|
||||
;; I misuse a little bit the `tramp-file-name' structure in order to
|
||||
|
|
@ -3096,7 +3104,11 @@ User is always nil."
|
|||
|
||||
(defun tramp-handle-file-exists-p (filename)
|
||||
"Like `file-exists-p' for Tramp files."
|
||||
(not (null (file-attributes filename))))
|
||||
;; `file-exists-p' is used as predicate in file name completion.
|
||||
;; We don't want to run it when `non-essential' is t, or there is
|
||||
;; no connection process yet.
|
||||
(when (tramp-connectable-p filename)
|
||||
(not (null (file-attributes filename)))))
|
||||
|
||||
(defun tramp-handle-file-in-directory-p (filename directory)
|
||||
"Like `file-in-directory-p' for Tramp files."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue