Function: vc-jj-dir-status-files

vc-jj-dir-status-files is a natively compiled function defined in vc-jj.el.

Signature

(vc-jj-dir-status-files DIR FILES UPDATE-FUNCTION)

Documentation

Calculate a list of (FILE STATE EXTRA) entries for DIR.

Return the result of applying UPDATE-FUNCTION to that list.

For a description of the states relevant to jj, see vc-jj-state.

Source Code

;; Defined in /nix/store/j1ql1qsv99iszr5pqf5fk9yfcl5pq4nv-emacs-packages-deps/share/emacs/site-lisp/elpa/vc-jj-0.5/vc-jj.el
;;;; dir-status-file

(defun vc-jj-dir-status-files (dir _files update-function)
  "Calculate a list of (FILE STATE EXTRA) entries for DIR.
Return the result of applying UPDATE-FUNCTION to that list.

For a description of the states relevant to jj, see `vc-jj-state'."
  ;; This function is specified below the STATE-QUERYING FUNCTIONS
  ;; header in the comments at the beginning of vc.el.  The
  ;; specification says the 'dir-status-files' backend function
  ;; returns "a list of lists ... for FILES in DIR", which does not
  ;; say anything about subdirectories.  We follow the example of
  ;; 'vc-git' and return the state of files in subdirectories of DIR
  ;; as well (except for ignored files, since we don't want to cons up
  ;; a list of every file below DIR).
  ;;
  ;; Unfortunately this function needs to do a lot of work:
  ;; - There is no single jj command that gives us all the info we
  ;;   need, so we cannot run asynchronously.
  ;; - jj prints filenames relative to the repository root, while we
  ;;   need them relative to DIR.
  ;;
  ;; TODO: we should use hash tables, since we're doing a lot of set
  ;; operations, which are slow on lists.
  (with-demoted-errors "JJ error during `vc-dir-status-files': %S"
    (let* ((dir (expand-file-name dir))
           (default-directory dir)
           (project-root (vc-jj-root dir))
           (registered-files (vc-jj--process-lines "file" "list" "--" dir))
           (ignored-files (seq-difference (cl-delete-if #'file-directory-p
                                                        (directory-files dir nil nil t))
                                          registered-files))
           (changed (vc-jj--process-lines "diff" "--summary" "--" dir))
           (added-files (mapcan (lambda (entry)
                                  (and (string-prefix-p "A " entry)
                                       (list (substring entry 2))))
                                changed))
           (removed-files (mapcan (lambda (entry)
                                    (and (string-prefix-p "D " entry)
                                         (list (substring entry 2))))
                                  changed))
           (edited-files (mapcan (lambda (entry)
                                     (and (string-prefix-p "M " entry)
                                          (list (substring entry 2))))
                                   changed))
           ;; The command below only prints conflicted files in DIR, but
           ;; relative to project-root, hence the dance with
           ;; expand-file-name / file-relative-name
           (conflicted-files (mapcar (lambda (entry)
                                       (file-relative-name (expand-file-name entry project-root) dir))
                                     (vc-jj--process-lines "file" "list"
                                                           "-T" "if(conflict, path ++ \"\\n\")" "--" dir)))
           (up-to-date-files (cl-remove-if (lambda (entry) (or (member entry conflicted-files)
                                                              (member entry edited-files)
                                                              (member entry added-files)
                                                              (member entry ignored-files)))
                                          registered-files))
           (result
            (nconc (mapcar (lambda (entry) (list entry 'conflict)) conflicted-files)
                   (mapcar (lambda (entry) (list entry 'added)) added-files)
                   (mapcar (lambda (entry) (list entry 'removed)) removed-files)
                   (mapcar (lambda (entry) (list entry 'edited)) edited-files)
                   (mapcar (lambda (entry) (list entry 'ignored)) ignored-files)
                   (mapcar (lambda (entry) (list entry 'up-to-date)) up-to-date-files))))
      (funcall update-function result nil))))