branch: externals/tramp-hlo
commit ba9f8c41e8ebb0140c7b398410477255bc9d7070
Author: Joe Sadusk <[email protected]>
Commit: Joe Sadusk <[email protected]>

    Applied changes from [email protected]. Fixed default-directory and 
file name quoting handling in dir-locals-find-file
---
 tramp-hlo-tests.el |  65 +++++++++++++------------
 tramp-hlo.el       | 137 ++++++++++++++++++++++++-----------------------------
 2 files changed, 97 insertions(+), 105 deletions(-)

diff --git a/tramp-hlo-tests.el b/tramp-hlo-tests.el
index 49043257b2..9bb162eacd 100644
--- a/tramp-hlo-tests.el
+++ b/tramp-hlo-tests.el
@@ -35,14 +35,12 @@
 
 ;;; Code:
 
-
 ;; Add load-path for batch mode
-(if (and load-file-name noninteractive)
-    (progn
+(when load-file-name noninteractive
       (add-to-list 'load-path (file-name-directory load-file-name))
-      (add-to-list 'load-path (file-name-concat (file-name-directory 
load-file-name) ".." "tramp"))
-      )
-  )
+      (add-to-list
+       'load-path
+       (file-name-concat (file-name-directory load-file-name) ".." "tramp")))
 (require 'tramp)
 (require 'tramp-hlo)
 (require 'ert-x)
@@ -116,7 +114,7 @@ The result must be equal."
   (skip-unless (tramp-hlo--test-enabled))
 
   (ert-with-temp-directory tmpdir
-    :prefix ert-remote-temporary-file-directory
+    :prefix (file-name-as-directory ert-remote-temporary-file-directory)
     (make-empty-file (expand-file-name dir-locals-file tmpdir))
     (make-empty-file
      (expand-file-name (string-replace ".el" "-2.el" dir-locals-file) tmpdir))
@@ -126,11 +124,12 @@ The result must be equal."
 
     ;; Use relative directory.
     (let ((default-directory tmpdir))
-      (tramp-hlo--run-test 'dir-locals--all-files "./"))
+      (tramp-hlo--run-test 'dir-locals--all-files "./")))
 
-    ;; Try directory with special characters.  See tramp-tests.el for
-    ;; more examples.
-  (dolist (prefix '(" foo\tbar baz\t" "&foo&bar&baz&" "$foo$bar$$baz$"))
+  ;; Try directory with special characters.  See tramp-tests.el for
+  ;; more examples.
+  (dolist (prefix '(" foo\tbar baz\t" "&foo&bar&baz&"
+                   "$foo$bar$$baz$" "'foo\"bar'baz\""))
     (ert-with-temp-directory tmpdir
       :prefix (expand-file-name prefix ert-remote-temporary-file-directory)
       (make-empty-file (expand-file-name dir-locals-file tmpdir))
@@ -141,20 +140,20 @@ The result must be equal."
 
   ;; Use another `dir-locals-file'.
   (ert-with-temp-directory tmpdir
-    :prefix ert-remote-temporary-file-directory
+    :prefix (file-name-as-directory ert-remote-temporary-file-directory)
     (let ((dir-locals-file "foo.el"))
       (make-empty-file (expand-file-name dir-locals-file tmpdir))
       (make-empty-file
        (expand-file-name (string-replace ".el" "-2.el" dir-locals-file) 
tmpdir))
 
-      (tramp-hlo--run-test 'dir-locals--all-files tmpdir)))))
+      (tramp-hlo--run-test 'dir-locals--all-files tmpdir))))
 
 (ert-deftest tramp-hlo-test-dir-locals-find-file ()
   "Test `dir-locals-find-file'."
   (skip-unless (tramp-hlo--test-enabled))
 
   (ert-with-temp-directory tmpdir
-    :prefix ert-remote-temporary-file-directory
+    :prefix (file-name-as-directory ert-remote-temporary-file-directory)
     (make-directory (file-name-concat tmpdir "foo" "bar") 'parents)
     (make-empty-file (expand-file-name dir-locals-file tmpdir))
     (make-empty-file
@@ -166,23 +165,24 @@ The result must be equal."
 
     ;; Subdirectory that doesn't exist yet
     (tramp-hlo--run-test
-     'dir-locals-find-file (file-name-concat tmpdir "foo" "bar" "baz" "blah" 
"bloo"))
+     'dir-locals-find-file
+     (file-name-concat tmpdir "foo" "bar" "baz" "blah" "bloo"))
 
     ;; Use relative directory
     (let ((default-directory (file-name-concat tmpdir "foo" "bar" "baz")))
-      (tramp-hlo--run-test 'dir-locals-find-file "./")
-      )
+      (tramp-hlo--run-test 'dir-locals-find-file "./"))
 
     ;; With space in directory name
     (make-directory (file-name-concat tmpdir "foo" "bar bar") 'parents)
-    
+
     ;; Use absolute directory.
     (tramp-hlo--run-test
      'dir-locals-find-file (file-name-concat tmpdir "foo" "bar bar" "baz"))
 
     ;; Subdirectory that doesn't exist yet
     (tramp-hlo--run-test
-     'dir-locals-find-file (file-name-concat tmpdir "foo" "bar bar" "baz" 
"blah" "bloo"))
+     'dir-locals-find-file
+     (file-name-concat tmpdir "foo" "bar bar" "baz" "blah" "bloo"))
 
     ;; Use relative directory
     (let ((default-directory (file-name-concat tmpdir "foo" "bar bar" "baz")))
@@ -194,7 +194,7 @@ The result must be equal."
   (skip-unless (tramp-hlo--test-enabled))
 
   (ert-with-temp-directory tmpdir
-    :prefix ert-remote-temporary-file-directory
+    :prefix (file-name-as-directory ert-remote-temporary-file-directory)
     (make-directory (file-name-concat tmpdir "foo" "bar") 'parents)
     (make-empty-file (expand-file-name dir-locals-file tmpdir))
 
@@ -207,16 +207,18 @@ The result must be equal."
 
     ;; Use subdirectory that doesn't exist yet
     (tramp-hlo--run-test
-     'locate-dominating-file (file-name-concat tmpdir "foo" "bar" "baz" "blah" 
"bleh") dir-locals-file)
+     'locate-dominating-file
+     (file-name-concat tmpdir "foo" "bar" "baz" "blah" "bleh") dir-locals-file)
     (tramp-hlo--run-test
-     'locate-dominating-file (file-name-concat tmpdir "foo" "bar" "baz" "blah" 
"bleh") "foo")
+     'locate-dominating-file
+     (file-name-concat tmpdir "foo" "bar" "baz" "blah" "bleh") "foo")
     ;; Use relative directory.
     (let ((default-directory (file-name-concat tmpdir "foo" "bar" "baz")))
       (tramp-hlo--run-test 'locate-dominating-file "./" dir-locals-file)
       (tramp-hlo--run-test 'locate-dominating-file "./" "foo")
       (tramp-hlo--run-test 'locate-dominating-file "./blah/bleh" "foo")
-      (tramp-hlo--run-test 'locate-dominating-file "./blah/bleh" 
dir-locals-file)
-      )
+      (tramp-hlo--run-test
+       'locate-dominating-file "./blah/bleh" dir-locals-file))
 
     ;; Directory name with space
     (make-directory (file-name-concat tmpdir "foo" "bar bar") 'parents)
@@ -225,21 +227,24 @@ The result must be equal."
      'locate-dominating-file
      (file-name-concat tmpdir "foo" "bar bar" "baz") dir-locals-file)
     (tramp-hlo--run-test
-     'locate-dominating-file (file-name-concat tmpdir "foo" "bar bar" "baz") 
"foo")
+     'locate-dominating-file
+     (file-name-concat tmpdir "foo" "bar bar" "baz") "foo")
 
     ;; Use subdirectory that doesn't exist yet
     (tramp-hlo--run-test
-     'locate-dominating-file (file-name-concat tmpdir "foo" "bar bar" "baz" 
"blah" "bleh") dir-locals-file)
+     'locate-dominating-file
+     (file-name-concat tmpdir "foo" "bar bar" "baz" "blah" "bleh")
+     dir-locals-file)
     (tramp-hlo--run-test
-     'locate-dominating-file (file-name-concat tmpdir "foo" "bar bar" "baz" 
"blah" "bleh") "foo")
+     'locate-dominating-file
+     (file-name-concat tmpdir "foo" "bar bar" "baz" "blah" "bleh") "foo")
     ;; Use relative directory.
     (let ((default-directory (file-name-concat tmpdir "foo" "bar bar" "baz")))
       (tramp-hlo--run-test 'locate-dominating-file "./" dir-locals-file)
       (tramp-hlo--run-test 'locate-dominating-file "./" "foo")
       (tramp-hlo--run-test 'locate-dominating-file "./blah/bleh" "foo")
-      (tramp-hlo--run-test 'locate-dominating-file "./blah/bleh" 
dir-locals-file)
-      )))
-
+      (tramp-hlo--run-test
+       'locate-dominating-file "./blah/bleh" dir-locals-file))))
 
 (provide 'tramp-hlo-tests)
 
diff --git a/tramp-hlo.el b/tramp-hlo.el
index 7eff2dc03c..faa1e7e47c 100644
--- a/tramp-hlo.el
+++ b/tramp-hlo.el
@@ -24,18 +24,21 @@
 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
 
 ;;; Commentary
+
 ;; This is an attempt to optimize Tramp remote editing with slow
 ;; connection by building higher level core lisp functions as Tramp
-;; operations. The idea is to reduce round trips by doing more on the
-;; server in one request.
+;; operations.  The idea is to reduce round trips by doing more on the
+;; server in one request.  It applies only to shell-based remote
+;; connections, as declared in tramp-sh.el and tramp-container.el.
+
+;; In order to enable it, call `M-x tramp-hlo-setup'.
 
 ;;; Code
 
 (require 'tramp)
 (require 'tramp-sh)
 
-(defconst tramp-hlo-test-files-in-dir-script
-  "
+(defconst tramp-hlo-test-files-in-dir-script "\
 DIR=$1
 shift
 FILES=$@
@@ -47,17 +50,18 @@ else
     echo \\(
     for FILE in $FILES; do
         if [ -r \"$FILE\" ] && [ -f \"$FILE\" ] && [ ! -d \"$FILE\" ]; then
-            echo \"\\\"$DIR/$FILE\\\"\"
-    fi
+            %k \"$DIR/$FILE\"; printf \"\\n\"
+        fi
     done
     echo \\)
 fi
 "
-  "Script to check for `dir-locals' in a remote dir."
-  )
+  "Script to check for `dir-locals' in a remote directory.
+The arguments are `DIRECTORY FILE1 FILE2 ...', with optional FILE*.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
 
-(defconst tramp-hlo-list-parents-script
-  "
+(defconst tramp-hlo-list-parents-script "\
 FILE=$1
 TEST=\"$(dirname $FILE )\"
 echo \\(
@@ -70,13 +74,12 @@ done
 echo \\\"/\\\"
 echo \\)
 "
-  "Script to list all parents in upward order of a directory,
-with home abbreviations."
-  )
-
+  "Script to list all parents in upward order of a DIRECTORY.
+If possible, the parents use home abbreviations.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
 
-(defconst tramp-hlo-locate-dominating-file-multi-script
-  "
+(defconst tramp-hlo-locate-dominating-file-multi-script "\
 FILE=$1
 shift
 NAMES=$@
@@ -105,12 +108,13 @@ while [ ! -z \"$TEST\" ] && [ -z \"$FOUND\" ]; do
 done
 echo \\)
 "
-  "Script to find several dominating files on a remote host."
-)
+  "Script to find several dominating files on a remote host.
+Arguments are like in `locate-dominating-file', but with supporting
+several NAMEs.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
 
-
-(defconst tramp-hlo-dir-locals-find-file-cache-update-script
-  "
+(defconst tramp-hlo-dir-locals-find-file-cache-update-script "\
 FILE=$1
 shift
 NAMES=$1
@@ -147,7 +151,7 @@ if [ -z \"$STARTING\" ]; then
 else
     TEST=$(realpath \"$STARTING\")
 
-    # make sure we're looking directories
+    # Make sure we're looking directories
     if [ ! -d \"$TEST\" ]; then
         TEST=$(dirname \"$TEST\")
     fi
@@ -156,7 +160,7 @@ else
     echo \"(\"
     echo \":file \\\"$FILE\\\" \"
 
-    # walk up the directory structure looking for the search files
+    # Walk up the directory structure looking for the search files
     FOUND=\"\"
     while [ ! -z \"$TEST\" ] && [ -z \"$FOUND\" ]; do
         for NAME in $NAMES; do
@@ -190,7 +194,9 @@ else
     for CACHEDIR in $CACHEDIRS; do
         CACHEDIR_LEN=$(expr length \"$CACHEDIR\")
 
-        if [ -d \"$CACHEDIR\" ] && [ \"$CACHEDIR_LEN\" -gt 
\"$FOUND_CACHEDIR_LEN\" ] && [ \"${FILE#$CACHEDIR}\" != \"$FILE\" ]; then
+        if [ -d \"$CACHEDIR\" ] \\
+          && [ \"$CACHEDIR_LEN\" -gt \"$FOUND_CACHEDIR_LEN\" ] \\
+          && [ \"${FILE#$CACHEDIR}\" != \"$FILE\" ]; then
             FOUND_CACHEDIR=$CACHEDIR
             FOUND_CACHEDIR_LEN=$CACHEDIR_LEN
         fi
@@ -211,39 +217,33 @@ else
     echo \")\"
 fi
 "
-  "Support script for `dir-locals-find-file'."
-)
-
+  "Support script for `dir-locals-find-file'.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
 
 (defun tramp-hlo-dir-locals--all-files (directory)
   "Tramp optimized version of `dir-locals--all-files'.
-Return a list of all readable dir-locals files in the directory
-represented by VEC.
+Return a list of all readable dir-locals files in DIRECTORY.
 The returned list is sorted by increasing priority.  That is,
 values specified in the last file should take precedence over
 those in the first.
 
 The optional argument BASE-EL-ONLY will only consider the base dir locals 
file."
   (with-parsed-tramp-file-name
-      (if (file-name-absolute-p directory) directory (file-name-concat 
default-directory directory))
+      (if (file-name-absolute-p directory)
+         directory (file-name-concat default-directory directory))
       vec
     (let* ((localdir (directory-file-name (tramp-file-name-localname vec)))
            (file-1 dir-locals-file)
            (file-2 (when (string-match "\\.el\\'" file-1)
-                     (replace-match "-2.el" t nil file-1)))
-           )
+                     (replace-match "-2.el" t nil file-1))))
       (tramp-maybe-send-script vec tramp-hlo-test-files-in-dir-script
                                "test_files_in_dir")
       (mapcar (lambda (name) (tramp-make-tramp-file-name vec name))
               (tramp-send-command-and-read
                vec
                (format "test_files_in_dir %s %s %s"
-                       (tramp-shell-quote-argument localdir) file-1 file-2)
-               )
-              )
-      )
-    )
-  )
+                       (tramp-shell-quote-argument localdir) file-1 
file-2))))))
 
 (defun tramp-hlo-locate-dominating-file-pred (vec pred)
   "Implementation of `tramp-hlo-locate-dominating-file' for a name predicate.
@@ -255,18 +255,13 @@ PRED takes one argument, a directory, and returns a 
non-nil value if that
 directory is the one for which we're looking."
   (tramp-maybe-send-script vec tramp-hlo-list-parents-script "list_parents")
   (let* ((command (format "list_parents %s" (tramp-file-name-localname vec)))
-         (parents (tramp-send-command-and-read vec command))
-         )
+         (parents (tramp-send-command-and-read vec command)))
     (while (and parents
                 (not (funcall pred
                               (tramp-make-tramp-file-name vec (car parents)))))
-      (pop parents)
-      )
-    (if parents
-        (tramp-make-tramp-file-name vec (car parents))
-      nil)
-    )
-  )
+      (pop parents))
+    (when parents
+      (tramp-make-tramp-file-name vec (car parents)))))
 
 (defun tramp-hlo-locate-dominating-file-list (vec names)
   "Implementation of `tramp-hlo-locate-dominating-file' for a list of names.
@@ -285,9 +280,7 @@ if not found."
          (local-dominating (tramp-send-command-and-read vec command)))
     (mapcar (lambda (result)
               (tramp-make-tramp-file-name vec result))
-            local-dominating)
-    )
-  )
+            local-dominating)))
 
 (defun tramp-hlo-locate-dominating-file (file name)
   "Tramp version of `locate-dominating-file'.
@@ -300,21 +293,17 @@ Instead of a string, NAME can also be a predicate taking 
one argument
 \(a directory) and returning a non-nil value if that directory is the one for
 which we're looking.  The predicate will be called with every file/directory
 the function needs to examine, starting with FILE."
+  ;; FIXME: What about `locate-dominating-stop-dir-regexp'?
   (with-parsed-tramp-file-name
-      (if (file-name-absolute-p file) file (file-name-concat default-directory 
file))
+      (if (file-name-absolute-p file)
+         file (file-name-concat default-directory file))
       vec
    (if (functionp name)
        (tramp-hlo-locate-dominating-file-pred vec name)
      (let* ((names (if (listp name) name (list name)))
             (file-list (tramp-hlo-locate-dominating-file-list vec names)))
-       (if file-list
-           (file-name-directory (car file-list))
-         nil
-         )
-       )
-     )
-   )
-  )
+       (when file-list
+         (file-name-directory (car file-list)))))))
 
 (defun tramp-hlo-dir-locals-find-file-cache-update (file cache)
   "Prepare inputs and run support script for `tramp-hlo-dir-locals-find-file'.
@@ -340,14 +329,14 @@ This function returns a plist with the fields:
     dotted pair list of dir-locals file and mtime
 `:locals' and `:cache' are optional fields, and are missing if not found."
   (with-parsed-tramp-file-name
-      (if (file-name-absolute-p file) file (file-name-concat default-directory 
file))
+      (if (file-name-absolute-p file)
+         file (file-name-concat default-directory file))
       vec
     (tramp-maybe-send-script
      vec
      tramp-hlo-dir-locals-find-file-cache-update-script
      "dir_locals_find_file_cache_update")
-    (let* (
-           (file-connection (file-remote-p file))
+    (let* ((file-connection (file-remote-p file))
            (cache-dirs (mapcar #'car cache))
            (same-remote-cache-dirs (seq-filter
                                     (lambda (cache-dir)
@@ -355,15 +344,15 @@ This function returns a plist with the fields:
                                                (file-remote-p cache-dir)))
                                     cache-dirs))
            (cache-dirs-local (mapcar #'file-local-name same-remote-cache-dirs))
-           (cache-dirs-quoted (mapcar #'tramp-shell-quote-argument 
cache-dirs-local))
+           (cache-dirs-quoted
+           (mapcar #'tramp-shell-quote-argument cache-dirs-local))
            (cache-dirs-string (string-join cache-dirs-quoted " "))
            (command (format
     "dir_locals_find_file_cache_update %s \".dir-locals.el .dir-locals2.el\" 
%s"
-                     (tramp-file-local-name file) cache-dirs-string))
-           )
+    (tramp-shell-quote-argument (tramp-file-local-name file))
+    cache-dirs-string)))
       (tramp-send-command-and-read vec command))))
 
-
 (defun tramp-hlo-dir-locals-find-file (file)
   "Tramp implementation of `dir-locals-find-file'.
 Find the directory-local variables for FILE.
@@ -384,7 +373,9 @@ This function returns either:
   - or the full path to the directory (a string) containing at
     least one `dir-locals-file' in the case of no valid cache
     entry."
-  (let* (
+  (let* ((file (if (file-name-absolute-p file)
+                   file
+                 (file-name-concat default-directory file)))
          (file-connection (file-remote-p file))
          (cache-update (tramp-hlo-dir-locals-find-file-cache-update
                         file dir-locals-directory-cache))
@@ -400,8 +391,7 @@ This function returns either:
                       (seq-find
                        (lambda (elt)
                          (string= (car elt) cache-dir))
-                       dir-locals-directory-cache)))
-         )
+                       dir-locals-directory-cache))))
     (if (and dir-elt
              (or (null locals-dir)
                  (<= (length locals-dir)
@@ -436,7 +426,6 @@ This function returns either:
       ;; No cache entry.
       locals-dir)))
 
-
 (defun tramp-hlo-setup ()
   "Setup Tramp high-level functions.
 Adds Tramp external operations for the following Emacs built-in functions:
@@ -449,19 +438,17 @@ Adds Tramp external operations for the following Emacs 
built-in functions:
   (tramp-add-external-operation 'locate-dominating-file
                                 #'tramp-hlo-locate-dominating-file 'tramp-sh)
   (tramp-add-external-operation 'dir-locals-find-file
-                                #'tramp-hlo-dir-locals-find-file 'tramp-sh)
-  )
+                                #'tramp-hlo-dir-locals-find-file 'tramp-sh))
 
 (defun tramp-hlo-remove ()
   "Remove Tramp high-level functions.
-Remove Tramp external operations for the following emacs built-in functions:
+Remove Tramp external operations for the following Emacs built-in functions:
 - `dir-locals--all-files'
 - `locate-dominating-file'
 - `dir-locals-find-file'"
   (interactive)
   (tramp-remove-external-operation 'dir-locals--all-files 'tramp-sh)
   (tramp-remove-external-operation 'locate-dominating-file 'tramp-sh)
-  (tramp-remove-external-operation 'dir-locals-find-file 'tramp-sh)
-  )
+  (tramp-remove-external-operation 'dir-locals-find-file 'tramp-sh))
 
 (provide 'tramp-hlo)

Reply via email to