]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp.el
Teach sql-mode's imenu about IF NOT EXISTS
[gnu-emacs] / lisp / net / tramp.el
index 58506ce82f7c1b5a576dcb61f6e4720b221237f6..d6f2177b03b5a56fa43381f902888ded23207abf 100644 (file)
@@ -403,6 +403,7 @@ interpreted as a regular expression which always matches."
 (defcustom tramp-save-ad-hoc-proxies nil
   "Whether to save ad-hoc proxies persistently."
   :group 'tramp
+  :version "24.3"
   :type 'boolean)
 
 (defcustom tramp-restricted-shell-hosts-alist
@@ -413,7 +414,7 @@ This is a list of regular expressions, which denote hosts running
 a registered shell like \"rbash\".  Those hosts can be used as
 proxies only, see `tramp-default-proxies-alist'.  If the local
 host runs a registered shell, it shall be added to this list, too."
-  :version "24.2"
+  :version "24.3"
   :group 'tramp
   :type '(repeat (regexp :tag "Host regexp")))
 
@@ -1352,8 +1353,7 @@ ARGS to actually emit the message (if applicable)."
                         "tramp-debug-message"
                         "tramp-error"
                         "tramp-error-with-buffer"
-                        "tramp-message"
-                        "tramp-with-progress-reporter")
+                        "tramp-message")
                       t)
                      "$")
                     fn)))
@@ -1497,7 +1497,7 @@ If VAR is nil, then we bind `v' to the structure and `method', `user',
     (when (string-match message (or (current-message) ""))
       (tramp-compat-funcall 'progress-reporter-update reporter value))))
 
-(defmacro tramp-with-progress-reporter (vec level message &rest body)
+(defmacro with-tramp-progress-reporter (vec level message &rest body)
   "Executes BODY, spinning a progress reporter with MESSAGE.
 If LEVEL does not fit for visible messages, or if this is a
 nested call of the macro, there are only traces without a visible
@@ -1526,7 +1526,42 @@ progress reporter."
        (tramp-message ,vec ,level "%s...done" ,message))))
 
 (tramp-compat-font-lock-add-keywords
- 'emacs-lisp-mode '("\\<tramp-with-progress-reporter\\>"))
+ 'emacs-lisp-mode '("\\<with-tramp-progress-reporter\\>"))
+
+(defmacro with-tramp-file-property (vec file property &rest body)
+  "Check in Tramp cache for PROPERTY, otherwise execute BODY and set cache.
+FILE must be a local file name on a connection identified via VEC."
+  `(if (file-name-absolute-p ,file)
+      (let ((value (tramp-get-file-property ,vec ,file ,property 'undef)))
+       (when (eq value 'undef)
+         ;; We cannot pass @body as parameter to
+         ;; `tramp-set-file-property' because it mangles our
+         ;; debug messages.
+         (setq value (progn ,@body))
+         (tramp-set-file-property ,vec ,file ,property value))
+       value)
+     ,@body))
+
+(put 'with-tramp-file-property 'lisp-indent-function 3)
+(put 'with-tramp-file-property 'edebug-form-spec t)
+(tramp-compat-font-lock-add-keywords
+ 'emacs-lisp-mode '("\\<with-tramp-file-property\\>"))
+
+(defmacro with-tramp-connection-property (key property &rest body)
+  "Check in Tramp for property PROPERTY, otherwise executes BODY and set."
+  `(let ((value (tramp-get-connection-property ,key ,property 'undef)))
+    (when (eq value 'undef)
+      ;; We cannot pass ,@body as parameter to
+      ;; `tramp-set-connection-property' because it mangles our debug
+      ;; messages.
+      (setq value (progn ,@body))
+      (tramp-set-connection-property ,key ,property value))
+    value))
+
+(put 'with-tramp-connection-property 'lisp-indent-function 2)
+(put 'with-tramp-connection-property 'edebug-form-spec t)
+(tramp-compat-font-lock-add-keywords
+ 'emacs-lisp-mode '("\\<with-tramp-connection-property\\>"))
 
 (defalias 'tramp-drop-volume-letter
   (if (memq system-type '(cygwin windows-nt))
@@ -1713,20 +1748,26 @@ value of `default-file-modes', without execute permissions."
   (or (file-modes filename)
       (logand (default-file-modes) (tramp-compat-octal-to-decimal "0666"))))
 
-(defun tramp-replace-environment-variables (filename)
-  "Replace environment variables in FILENAME.
+(defalias 'tramp-replace-environment-variables
+  (if (ignore-errors
+        (equal "${ tramp?}" (substitute-env-vars "${ tramp?}" 'only-defined)))
+      (lambda (filename)
+        "Like `substitute-env-vars' with `only-defined' non-nil."
+        (substitute-env-vars filename 'only-defined))
+    (lambda (filename)
+      "Replace environment variables in FILENAME.
 Return the string with the replaced variables."
-  (save-match-data
-    (let ((idx (string-match "$\\(\\w+\\)" filename)))
-      ;; `$' is coded as `$$'.
-      (when (and idx
-                (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
-                (getenv (match-string 1 filename)))
-       (setq filename
-             (replace-match
-              (substitute-in-file-name (match-string 0 filename))
-              t nil filename)))
-      filename)))
+      (save-match-data
+        (let ((idx (string-match "$\\(\\w+\\)" filename)))
+          ;; `$' is coded as `$$'.
+          (when (and idx
+                     (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
+                     (getenv (match-string 1 filename)))
+            (setq filename
+                  (replace-match
+                   (substitute-in-file-name (match-string 0 filename))
+                   t nil filename)))
+          filename)))))
 
 ;; In XEmacs, electricity is implemented via a key map for ?/ and ?~,
 ;; which calls corresponding functions (see minibuf.el).
@@ -2859,7 +2900,7 @@ User is always nil."
   (setq filename (expand-file-name filename))
   (let (result local-copy remote-copy)
     (with-parsed-tramp-file-name filename nil
-      (tramp-with-progress-reporter
+      (with-tramp-progress-reporter
          v 3 (format "Inserting `%s'" filename)
        (unwind-protect
            (if (not (file-exists-p filename))
@@ -2982,7 +3023,7 @@ User is always nil."
     (if (not (file-exists-p file))
        nil
       (let ((tramp-message-show-message (not nomessage)))
-       (tramp-with-progress-reporter v 0 (format "Loading %s" file)
+       (with-tramp-progress-reporter v 0 (format "Loading %s" file)
          (let ((local-copy (file-local-copy file)))
            ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil.
            (unwind-protect
@@ -3126,7 +3167,7 @@ beginning of local filename are not substituted."
   "Send the login name."
   (when (not (stringp tramp-current-user))
     (setq tramp-current-user
-         (with-connection-property vec "login-as"
+         (with-tramp-connection-property vec "login-as"
            (save-window-excursion
              (let ((enable-recursive-minibuffers t))
                (pop-to-buffer (tramp-get-connection-buffer vec))
@@ -3293,7 +3334,9 @@ for process communication also."
       ;; Under Windows XP, accept-process-output doesn't return
       ;; sometimes.  So we add an additional timeout.
       (with-timeout ((or timeout 1))
-       (accept-process-output proc timeout timeout-msecs)))
+       (if (featurep 'xemacs)
+           (accept-process-output proc timeout timeout-msecs)
+         (accept-process-output proc timeout timeout-msecs (and proc t)))))
     (tramp-message proc 10 "\n%s" (buffer-string))))
 
 (defun tramp-check-for-regexp (proc regexp)
@@ -3414,13 +3457,13 @@ the remote host use line-endings as defined in the variable
 (defun tramp-get-inode (vec)
   "Returns the virtual inode number.
 If it doesn't exist, generate a new one."
-  (with-file-property vec (tramp-file-name-localname vec) "inode"
+  (with-tramp-file-property vec (tramp-file-name-localname vec) "inode"
     (setq tramp-inodes (1+ tramp-inodes))))
 
 (defun tramp-get-device (vec)
   "Returns the virtual device number.
 If it doesn't exist, generate a new one."
-  (with-connection-property (tramp-get-connection-process vec) "device"
+  (with-tramp-connection-property (tramp-get-connection-process vec) "device"
     (cons -1 (setq tramp-devices (1+ tramp-devices)))))
 
 (defun tramp-equal-remote (file1 file2)
@@ -3542,7 +3585,7 @@ would yield `t'.  On the other hand, the following check results in nil:
 
 (defun tramp-get-remote-tmpdir (vec)
   "Return directory for temporary files on the remote host identified by VEC."
-  (with-connection-property vec "tmpdir"
+  (with-tramp-connection-property vec "tmpdir"
     (let ((dir (tramp-make-tramp-file-name
                (tramp-file-name-method vec)
                (tramp-file-name-user vec)
@@ -3724,6 +3767,7 @@ Invokes `password-read' if available, `read-passwd' else."
     ("oct" . 10) ("nov" . 11) ("dec" . 12))
   "Alist mapping month names to integers.")
 
+;; FIXME: Shouldn't this also look at any subseconds parts of T1 and T2?
 ;;;###tramp-autoload
 (defun tramp-time-less-p (t1 t2)
   "Say whether time value T1 is less than time value T2."
@@ -3733,6 +3777,7 @@ Invokes `password-read' if available, `read-passwd' else."
       (and (= (car t1) (car t2))
           (< (nth 1 t1) (nth 1 t2)))))
 
+;; FIXME: Shouldn't this also look at any subseconds parts of T1 and T2?
 (defun tramp-time-subtract (t1 t2)
   "Subtract two time values.
 Return the difference in the format of a time value."
@@ -3830,7 +3875,6 @@ Only works for Bourne-like shells."
 ;; * In Emacs 21, `insert-directory' shows total number of bytes used
 ;;   by the files in that directory.  Add this here.
 ;; * Avoid screen blanking when hitting `g' in dired.  (Eli Tziperman)
-;; * Make ffap.el grok Tramp filenames.  (Eli Tziperman)
 ;; * abbreviate-file-name
 ;; * Better error checking.  At least whenever we see something
 ;;   strange when doing zerop, we should kill the process and start