Function: tramp-smb-handle-insert-directory

tramp-smb-handle-insert-directory is a byte-compiled function defined in tramp-smb.el.gz.

Signature

(tramp-smb-handle-insert-directory FILENAME SWITCHES &optional WILDCARD FULL-DIRECTORY-P)

Documentation

Like insert-directory for Tramp files.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp-smb.el.gz
(defun tramp-smb-handle-insert-directory
  (filename switches &optional wildcard full-directory-p)
  "Like `insert-directory' for Tramp files."
  (setq filename (expand-file-name filename))
  (unless switches (setq switches ""))
  ;; Mark trailing "/".
  (when (and (directory-name-p filename)
	     (not full-directory-p))
    (setq switches (concat switches "F")))
  (if full-directory-p
      ;; Called from `dired-add-entry'.
      (setq filename (file-name-as-directory filename))
    (setq filename (directory-file-name filename)))
  ;; Check, whether directory is accessible.
  (unless wildcard
    (access-file filename "Reading directory"))
  (with-parsed-tramp-file-name filename nil
    (with-tramp-progress-reporter v 0 (format "Opening directory %s" filename)
      (save-match-data
	(let ((base (file-name-nondirectory filename))
	      ;; We should not destroy the cache entry.
	      (entries (copy-tree
			(tramp-smb-get-file-entries
			 (file-name-directory filename))))
	      (avail (get-free-disk-space filename))
	      ;; `get-free-disk-space' calls `file-system-info', which
	      ;; sets file property "used-bytes" as side effect.
	      (used
	       (format
		"%.0f"
		(/ (tramp-get-file-property v localname "used-bytes" 0) 1024))))

	  (when wildcard
	    (string-match (rx ".") base)
	    (setq base (replace-match "\\\\." nil nil base))
	    (string-match (rx "*") base)
	    (setq base (replace-match ".*" nil nil base))
	    (string-match (rx "?") base)
	    (setq base (replace-match ".?" nil nil base)))

	  ;; Filter entries.
	  (setq entries
		 (if (or wildcard (string-empty-p base))
		     ;; Check for matching entries.
		     (tramp-compat-seq-keep
		      (lambda (x)
			(when (string-match-p (rx bol (literal base)) (nth 0 x))
			  x))
		      entries)
		   ;; We just need the only and only entry FILENAME.
		   (list (assoc base entries))))

	  ;; Sort entries.
	  (setq entries
		(sort
		 entries
		 (lambda (x y)
		   (if (tramp-compat-string-search "t" switches)
		       ;; Sort by date.
		       (time-less-p (nth 3 y) (nth 3 x))
		     ;; Sort by name.
		     (string-lessp (nth 0 x) (nth 0 y))))))

	  ;; Handle "-F" switch.
	  (when (tramp-compat-string-search "F" switches)
	    (mapc
	     (lambda (x)
	       (unless (string-empty-p (car x))
		 (cond
		  ((char-equal ?d (string-to-char (nth 1 x)))
		   (setcar x (concat (car x) "/")))
		  ((char-equal ?x (string-to-char (nth 1 x)))
		   (setcar x (concat (car x) "*"))))))
	     entries))

	  ;; Insert size information.
	  (when full-directory-p
	    (insert
	     (if (and avail
		      ;; Emacs 29.1 or later.
		      (not (fboundp 'dired--insert-disk-space)))
		 (format "total used in directory %s available %s\n" used avail)
	       (format "total %s\n" used))))

	  ;; Print entries.
	  (mapc
	   (lambda (x)
	     (unless (string-empty-p (nth 0 x))
	       (let ((attr
		      (when (tramp-smb-get-stat-capability v)
			(ignore-errors
			  (file-attributes
			   (expand-file-name
			    (nth 0 x) (file-name-directory filename))
			   'string)))))
		 (when (tramp-compat-string-search "l" switches)
		   (insert
		    (format
		     "%10s %3d %-8s %-8s %8s %s "
		     (or (file-attribute-modes attr) (nth 1 x))
		     (or (file-attribute-link-number attr) 1)
		     (or (file-attribute-user-id attr) "nobody")
		     (or (file-attribute-group-id attr) "nogroup")
		     (or (file-attribute-size attr) (nth 2 x))
		     (format-time-string
		      (if (time-less-p
			   ;; Half a year.
			   (time-since (nth 3 x)) (days-to-time 183))
			  "%b %e %R"
			"%b %e %Y")
		      (nth 3 x))))) ; date

		 ;; We mark the file name.  The inserted name could be
		 ;; from somewhere else, so we use the relative file name
		 ;; of `default-directory'.
		 (let ((start (point)))
		   (insert
		    (file-relative-name
		     (expand-file-name
		      (nth 0 x) (file-name-directory filename))
		     (when full-directory-p (file-name-directory filename))))
		   (put-text-property start (point) 'dired-filename t))

		 ;; Insert symlink.
		 (when (and (tramp-compat-string-search "l" switches)
			    (stringp (file-attribute-type attr)))
		   (insert " -> " (file-attribute-type attr))))

	       (insert "\n")
	       (beginning-of-line)))
	   entries))))))