Function: projectile-project-root

projectile-project-root is a byte-compiled function defined in projectile.el.

Signature

(projectile-project-root &optional DIR)

Documentation

Retrieves the root directory of a project if available.

If DIR is not supplied it's set to the current directory by default.

Source Code

;; Defined in ~/.emacs.d/elpa/projectile-20260310.858/projectile.el
(defun projectile-project-root (&optional dir)
  "Retrieves the root directory of a project if available.
If DIR is not supplied it's set to the current directory by default."
  (let ((dir (or dir default-directory)))
    ;; Back out of any archives, the project will live on the outside and
    ;; searching them is slow.
    (when (and (fboundp 'tramp-archive-file-name-p)
               (tramp-archive-file-name-p dir))
      (setq dir (file-name-directory (tramp-archive-file-name-archive dir))))
    ;; the cached value will be 'none in the case of no project root (this is to
    ;; ensure it is not reevaluated each time when not inside a project) so
    ;; replace this 'none value with nil so a nil value is used instead
    (let ((result (or
       ;; if we've already failed to find a project dir for this
       ;; dir, and cached that failure, don't recompute
       (let* ((cache-key (format "projectilerootless-%s" dir))
              (cache-value (gethash cache-key projectile-project-root-cache)))
         cache-value)
       ;; if the file isn't local, and we're not connected, don't try to
       ;; find a root now, but don't cache failure, as we might
       ;; re-connect.  The `is-local' and `is-connected' variables are
       ;; used to fix the behavior where Emacs hangs because of
       ;; Projectile when you open a file over TRAMP. It basically
       ;; prevents Projectile from trying to find information about
       ;; files for which it's not possible to get that information
       ;; right now.
       (let ((is-local (not (file-remote-p dir)))      ;; `true' if the file is local
             (is-connected (file-remote-p dir nil t))) ;; `true' if the file is remote AND we are connected to the remote
         (unless (or is-local is-connected)
           'none))
       ;; if the file is local or we're connected to it via TRAMP, run
       ;; through the project root functions until we find a project dir
       (seq-some
        (lambda (func)
          (let* ((cache-key (format "%s-%s" func dir))
                 (cache-value (gethash cache-key projectile-project-root-cache)))
            (if (and cache-value (file-exists-p cache-value))
                cache-value
              (let ((value (funcall func (file-truename dir))))
                (puthash cache-key value projectile-project-root-cache)
                value))))
        projectile-project-root-functions)
       ;; if we get here, we have failed to find a root by all
       ;; conventional means, and we assume the failure isn't transient
       ;; / network related, so cache the failure
       (let ((cache-key (format "projectilerootless-%s" dir)))
         (puthash cache-key 'none projectile-project-root-cache)
         'none))))
      (unless (eq result 'none) result))))