Function: projectile--dir-files-alien-await

projectile--dir-files-alien-await is a byte-compiled function defined in projectile.el.

Signature

(projectile--dir-files-alien-await DIRECTORY &optional VCS SUBDIRS)

Documentation

Like projectile-dir-files-alien for DIRECTORY but without freezing Emacs.

Runs the asynchronous indexer and waits for it with accept-process-output so redisplay keeps happening and keyboard-quit (C-g (keyboard-quit)) stays live; on a quit the indexing process is killed and the quit is re-signalled. The returned list is the same one projectile-dir-files-alien would produce.

VCS and SUBDIRS are interpreted exactly as in projectile-dir-files-alien. Falls back to the synchronous function when the asynchronous process can't be started (e.g. a remote host whose handler doesn't support make-process).

Note that waiting pumps the event loop, so process filters, sentinels and timers (but not interactive commands) may run while we wait.

Source Code

;; Defined in ~/.emacs.d/elpa/projectile-20260820.1509/projectile.el
(defun projectile--dir-files-alien-await (directory &optional vcs subdirs)
  "Like `projectile-dir-files-alien' for DIRECTORY but without freezing Emacs.
Runs the asynchronous indexer and waits for it with `accept-process-output'
so redisplay keeps happening and `keyboard-quit' (\\[keyboard-quit]) stays live; on a
quit the indexing process is killed and the quit is re-signalled.  The
returned list is the same one `projectile-dir-files-alien' would produce.

VCS and SUBDIRS are interpreted exactly as in `projectile-dir-files-alien'.
Falls back to the synchronous function when the asynchronous process
can't be started (e.g. a remote host whose handler doesn't support
`make-process').

Note that waiting pumps the event loop, so process filters, sentinels
and timers (but not interactive commands) may run while we wait."
  (let* (done files err
         (proc (projectile-dir-files-alien-async
                directory
                (lambda (fs e) (setq done t files fs err e))
                vcs subdirs)))
    (cond
     ;; The async indexer didn't spawn a process.  Either the command was
     ;; empty - in which case the callback already ran synchronously and we
     ;; just return its (empty) result - or a remote handler declined
     ;; make-process, in which case we fall back to the synchronous,
     ;; TRAMP-safe path.
     ((null proc)
      (if (and done (null err))
          files
        (projectile-dir-files-alien directory vcs subdirs)))
     ;; A genuine process is running: wait for it without freezing.
     (t
      (let ((reporter (make-progress-reporter
                       (format "Projectile is indexing %s"
                               (propertize (abbreviate-file-name directory)
                                           'face 'font-lock-keyword-face)))))
        (unwind-protect
            (progn
              (while (and (not done) (process-live-p proc))
                (accept-process-output proc 0.1)
                (progress-reporter-update reporter))
              ;; The command is done, but the result reaches us from the
              ;; process sentinel, and that isn't guaranteed to have run:
              ;; `accept-process-output' on a process that has already
              ;; exited returns without running it, and the status change
              ;; may not be noticed until Emacs is back in its command
              ;; loop.  That used to leave this loop spinning forever with
              ;; the progress reporter turning (issue #2118).  Pump the
              ;; event loop briefly - `sit-for', unlike
              ;; `accept-process-output', does run pending sentinels - and
              ;; if the result still hasn't arrived, deliver it here.
              (unless done
                (let ((deadline (+ (projectile-time-seconds)
                                   projectile-async-index-sentinel-timeout)))
                  (while (and (not done) (< (projectile-time-seconds) deadline))
                    (sit-for 0.02)
                    (progress-reporter-update reporter)))
                (unless done
                  (when-let* ((finish (process-get proc 'projectile-finish)))
                    (funcall finish proc)))))
          ;; Runs on normal completion and on `keyboard-quit': make sure we
          ;; never leave the indexing process running behind us.  Mark it
          ;; aborted first so its sentinel skips the failure path (killing
          ;; it fires the sentinel with a `signal' status) and just cleans
          ;; up - a quit must stay a clean quit.
          (when (process-live-p proc)
            (process-put proc 'projectile-aborted t)
            (delete-process proc)))
        (progress-reporter-done reporter))
      (cond
       (err
        (user-error "Projectile indexing failed: %s.  \
See the *projectile-files-errors* buffer for details" err))
       (done files)
       ;; Neither the sentinel nor we could deliver a result - rather than
       ;; report an empty project, index the old (blocking) way.
       (t (projectile-dir-files-alien directory vcs subdirs)))))))