From: Michael Albinus Date: Tue, 15 Aug 2023 13:23:20 +0000 (+0200) Subject: Some Tramp optimizations X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=5c101b1adac2b4f3cc4e08a6492b406952c529f3;p=emacs.git Some Tramp optimizations * lisp/net/tramp-sh.el (tramp-perl-file-name-all-completions): Extend. It shall return also some basic file attributes. (tramp-bundle-read-file-names): Simplify data to be transferred. (tramp-sh-handle-file-name-all-completions): Read additional attributes. (tramp-sh-handle-expand-file-name): Check also "doas". (tramp-bundle-read-file-names): Handle changed data layout. (tramp-find-file-exists-command): Set "file-exists-p" file property. --- diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index d836fb1f387..426682ddef1 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -634,16 +634,20 @@ characters need to be doubled.") (defconst tramp-perl-file-name-all-completions "%p -e ' -opendir(d, $ARGV[0]) || die(\"$ARGV[0]: $!\\nfail\\n\"); +($dir = $ARGV[0]) =~ s#/+$##; +opendir(d, $dir) || die(\"$dir: $!\\nfail\\n\"); @files = readdir(d); closedir(d); +print \"(\\n\"; foreach $f (@files) { - if (-d \"$ARGV[0]/$f\") { - print \"$f/\\n\"; - } - else { - print \"$f\\n\"; - } + ($p = $f) =~ s/\\\"/\\\\\\\"/g; + ($q = \"$dir/$f\") =~ s/\\\"/\\\\\\\"/g; + print \"(\", + ((-d \"$q\") ? \"\\\"$p/\\\" \\\"$q\\\" t\" : \"\\\"$p\\\" \\\"$q\\\" nil\"), + ((-e \"$q\") ? \" t\" : \" nil\"), + ((-r \"$q\") ? \" t\" : \" nil\"), + \")\\n\"; } +print \")\\n\"; ' \"$1\" %n" "Perl script to produce output suitable for use with `file-name-all-completions' on the remote file system. @@ -1073,21 +1077,10 @@ characters need to be doubled.") "echo \"(\" while read file; do quoted=`echo \"$file\" | sed -e \"s/\\\"/\\\\\\\\\\\\\\\\\\\"/\"` - if %s \"$file\"; then - echo \"(\\\"$quoted\\\" \\\"file-exists-p\\\" t)\" - else - echo \"(\\\"$quoted\\\" \\\"file-exists-p\\\" nil)\" - fi - if %s \"$file\"; then - echo \"(\\\"$quoted\\\" \\\"file-readable-p\\\" t)\" - else - echo \"(\\\"$quoted\\\" \\\"file-readable-p\\\" nil)\" - fi - if %s \"$file\"; then - echo \"(\\\"$quoted\\\" \\\"file-directory-p\\\" t)\" - else - echo \"(\\\"$quoted\\\" \\\"file-directory-p\\\" nil)\" - fi + echo -n \"(\\\"$quoted\\\"\" + if %s \"$file\"; then echo -n \" t\"; else echo -n \" nil\"; fi + if %s \"$file\"; then echo -n \" t\"; else echo -n \" nil\"; fi + if %s \"$file\"; then echo \" t)\"; else echo \" nil)\"; fi done echo \")\"" "Script to check file attributes of a bundle of files. @@ -1870,34 +1863,48 @@ ID-FORMAT valid values are `string' and `integer'." ;; Get a list of directories and files, including ;; reliably tagging the directories with a trailing "/". ;; Because I rock. --daniel@danann.net - (when (tramp-send-command-and-check - v - (if (tramp-get-remote-perl v) - (progn - (tramp-maybe-send-script - v tramp-perl-file-name-all-completions - "tramp_perl_file_name_all_completions") - (format "tramp_perl_file_name_all_completions %s" - (tramp-shell-quote-argument localname))) - - (format (concat - "cd %s 2>&1 && %s -a 2>%s" - " | while IFS= read f; do" - " if %s -d \"$f\" 2>%s;" - " then echo \"$f/\"; else echo \"$f\"; fi;" - " done") - (tramp-shell-quote-argument localname) - (tramp-get-ls-command v) - (tramp-get-remote-null-device v) - (tramp-get-test-command v) - (tramp-get-remote-null-device v)))) - - ;; Now grab the output. - (with-current-buffer (tramp-get-buffer v) - (goto-char (point-max)) - (while (zerop (forward-line -1)) - (push (buffer-substring (point) (line-end-position)) result))) - result))))))))) + (if (tramp-get-remote-perl v) + (progn + (tramp-maybe-send-script + v tramp-perl-file-name-all-completions + "tramp_perl_file_name_all_completions") + (setq result + (tramp-send-command-and-read + v (format "tramp_perl_file_name_all_completions %s" + (tramp-shell-quote-argument localname)) + 'noerror)) + ;; Cached values. + (dolist (elt result) + (tramp-set-file-property + v (cadr elt) "file-directory-p" (nth 2 elt)) + (tramp-set-file-property + v (cadr elt) "file-exists-p" (nth 3 elt)) + (tramp-set-file-property + v (cadr elt) "file-readable-p" (nth 4 elt))) + ;; Result. + (mapcar #'car result)) + + ;; Do it with ls. + (when (tramp-send-command-and-check + v (format (concat + "cd %s 2>&1 && %s -a 2>%s" + " | while IFS= read f; do" + " if %s -d \"$f\" 2>%s;" + " then echo \"$f/\"; else echo \"$f\"; fi;" + " done") + (tramp-shell-quote-argument localname) + (tramp-get-ls-command v) + (tramp-get-remote-null-device v) + (tramp-get-test-command v) + (tramp-get-remote-null-device v))) + + ;; Now grab the output. + (with-current-buffer (tramp-get-buffer v) + (goto-char (point-max)) + (while (zerop (forward-line -1)) + (push + (buffer-substring (point) (line-end-position)) result))) + result)))))))))) ;; cp, mv and ln @@ -2842,7 +2849,8 @@ the result will be a local, non-Tramp, file name." ;; appropriate either, because ssh and companions might ;; use a user name from the config file. (when (and (tramp-string-empty-or-nil-p uname) - (string-match-p (rx bos "su" (? "do") eos) method)) + (string-match-p + (rx bos (| "su" "sudo" "doas" "ksu") eos) method)) (setq uname user)) (when (setq hname (tramp-get-home-directory v uname)) (setq localname (concat hname fname))))) @@ -3630,17 +3638,16 @@ filled are described in `tramp-bundle-read-file-names'." (format "tramp_bundle_read_file_names <<'%s'\n%s\n%s\n" tramp-end-of-heredoc - (mapconcat #'tramp-shell-quote-argument - files - "\n") + (mapconcat #'tramp-shell-quote-argument files "\n") tramp-end-of-heredoc)) (with-current-buffer (tramp-get-connection-buffer vec) ;; Read the expression. (goto-char (point-min)) (read (current-buffer))))) - (tramp-set-file-property - vec (car elt) (cadr elt) (cadr (cdr elt)))))) + (tramp-set-file-property vec (car elt) "file-exists-p" (nth 1 elt)) + (tramp-set-file-property vec (car elt) "file-readable-p" (nth 2 elt)) + (tramp-set-file-property vec (car elt) "file-directory-p" (nth 3 elt))))) (defvar tramp-vc-registered-file-names nil "List used to collect file names, which are checked during `vc-registered'.") @@ -4256,6 +4263,7 @@ file exists and nonzero exit status otherwise." vec (format "%s %s" result nonexistent)))))) (tramp-error vec 'file-error "Couldn't find command to check if file exists")) + (tramp-set-file-property vec existing "file-exists-p" t) result)) (defun tramp-get-sh-extra-args (shell) @@ -5647,7 +5655,7 @@ Nonexistent directories are removed from spec." remote-path :test #'string-equal :from-end t)) ;; Remove non-existing directories. - (let ((remote-file-name-inhibit-cache nil)) + (let (remote-file-name-inhibit-cache) (tramp-bundle-read-file-names vec remote-path) (cl-remove-if (lambda (x) (not (tramp-get-file-property vec x "file-directory-p")))