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))))