Function: projectile-doctor--render

projectile-doctor--render is a byte-compiled function defined in projectile.el.

Signature

(projectile-doctor--render DATA)

Documentation

Render the report described by DATA into the current buffer.

Source Code

;; Defined in ~/.emacs.d/elpa/projectile-20260820.1509/projectile.el
(defun projectile-doctor--render (data)
  "Render the report described by DATA into the current buffer."
  (projectile--report-title "Projectile doctor report")
  (insert (projectile--report-face
           (format "projectile %s, Emacs %s, %s\n"
                   projectile-version emacs-version system-type)
           'projectile-report-label))
  (if (null (plist-get data :root))
      (projectile-doctor--render-no-project data)
    (projectile-doctor--section "Project")
    (projectile-doctor--field "root" (plist-get data :root)
                              'projectile-report-value)
    (projectile-doctor--field
     "detected by"
     (when-let* ((func (plist-get data :root-function)))
       (concat (symbol-name func)
               (if-let* ((marker (plist-get data :root-marker)))
                   (format " (marker: %s)" marker)
                 ""))))
    (projectile-doctor--field
     "name"
     (format "%s (%s)" (plist-get data :name)
             (if (eq (plist-get data :name-source) 'local-variable)
                 "from the `projectile-project-name' variable"
               (format "via %s" (plist-get data :name-source)))))
    (projectile-doctor--field "remote" (or (plist-get data :remote)
                                           "no (local project)"))
    (projectile-doctor--field "projectile-mode"
                              (if (plist-get data :projectile-mode) "on" "off"))

    (projectile-doctor--section "Type")
    (projectile-doctor--field
     "type"
     (format "%s (%s)" (plist-get data :type)
             (if (eq (plist-get data :type-source) 'local-variable)
                 "from the `projectile-project-type' variable"
               "auto-detected")))
    (projectile-doctor--field
     "marker"
     (when-let* ((marker (plist-get data :type-marker)))
       (if (functionp marker)
           (format "%s (predicate)" marker)
         ;; Every position is a list of alternatives once normalized, so
         ;; rendering doesn't need to know the shapes: `|' separates what
         ;; would satisfy one position, a space separates the positions.
         (mapconcat (lambda (alternatives) (string-join alternatives "|"))
                    (projectile--marker-clauses marker)
                    " "))))
    (projectile-doctor--field "vcs" (plist-get data :vcs))
    (when (eq (plist-get data :type) 'generic)
      (insert "
No registered project type matched this project's files.  That only
affects the type-specific commands (compile, test, run, related files);
file listing and search work regardless.  Set `projectile-project-type'
in .dir-locals.el to pin a type, or register one with
`projectile-register-project-type'.
"))

    (projectile-doctor--section "Indexing")
    (projectile-doctor--field "method" (plist-get data :indexing-method))
    (projectile-doctor--field "async indexing"
                              (if (plist-get data :async-indexing) "on" "off"))
    (projectile-doctor--field "command"
                              (or (plist-get data :index-command)
                                  "none (native indexing walks the tree in Lisp)"))
    (projectile-doctor--field "git" (projectile-doctor--executable-string
                                     (plist-get data :git)))
    (projectile-doctor--field
     "fd" (concat (projectile-doctor--executable-string (plist-get data :fd))
                  (unless (plist-get data :git-use-fd)
                    " (not used - projectile-git-use-fd is nil)")))
    (projectile-doctor--field "rg" (projectile-doctor--executable-string
                                    (plist-get data :rg)))

    (projectile-doctor--section "Files")
    (projectile-doctor--field "files" (projectile-doctor--files-string data))
    (projectile-doctor--field "caching" (pcase (plist-get data :caching)
                                          ('nil "disabled")
                                          ('persistent "persistent")
                                          (_ "enabled (this session)")))
    (projectile-doctor--field "cache state" (projectile-doctor--cache-string data))
    (projectile-doctor--field "cache file" (plist-get data :cache-file))

    (projectile-doctor--section "Ignores")
    (let ((cfg (plist-get data :dirconfig)))
      (projectile-doctor--field
       "dirconfig"
       (if cfg
           (format "%s (keep %d, ignore %d, ensure %d)"
                   (plist-get data :dirconfig-file)
                   (length (projectile-dirconfig-keep cfg))
                   (length (projectile-dirconfig-ignore cfg))
                   (length (projectile-dirconfig-ensure cfg)))
         (format "%s (absent)" (plist-get data :dirconfig-file))))
      (when cfg
        (projectile-doctor--list-field "keep (+)"
                                       (projectile-dirconfig-keep cfg))
        (projectile-doctor--list-field "ignore (-)"
                                       (projectile-dirconfig-ignore cfg))
        (projectile-doctor--list-field "ensure (!)"
                                       (projectile-dirconfig-ensure cfg))))
    (projectile-doctor--list-field "ignore patterns"
                                   (plist-get data :ignore-patterns))
    (projectile-doctor--list-field "ensure patterns"
                                   (plist-get data :ensure-patterns))
    (projectile-doctor--list-field "ignored in root"
                                   (if (plist-get data :remote)
                                       (list "not checked (remote)")
                                     (plist-get data :excluded-entries)))

    (projectile-doctor--section "Findings")
    ;; Anything that wants action first - a report is read top-down and a
    ;; lone warning shouldn't be buried among a dozen `ok' lines.
    (dolist (finding (projectile-doctor--sort-findings
                      (projectile-doctor--findings data)))
      (pcase-let* ((`(,label . ,face)
                    (pcase (plist-get finding :severity)
                      ('ok '("ok" . projectile-report-ok))
                      ('warn '("warn" . projectile-report-warning))
                      (_ '("info" . projectile-report-info)))))
        (insert (projectile--report-face (format "%-6s" label) face)
                (plist-get finding :message)
                "\n")
        ;; Put the fix under the diagnosis rather than describing it.  Its
        ;; own line, because findings are long and a button at the end of
        ;; one sits past the window edge where nobody will find it.
        (when-let* ((action (plist-get finding :action)))
          (insert (make-string 6 ?\s))
          (insert-text-button (format "[%s]" (plist-get finding :action-label))
                              'type 'projectile-doctor-action
                              'projectile-action action)
          (insert "\n"))))
    (projectile--report-hints '((forward-button . "next action")
                                (revert-buffer . "refresh")
                                (projectile-report-copy . "copy")
                                (outline-toggle-children . "fold")
                                (quit-window . "quit")))))