]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/ztree/ztree-diff-model.el
Merge commit '1054ea1bc5b07a1438a18c1b33f4266b28ff9d77'
[gnu-emacs-elpa] / packages / ztree / ztree-diff-model.el
index b68631e052eb8d06330f06521bd7b1010648a21b..e8fa4d9a236b6c7d2fc13b3176d1515ec07f58ec 100644 (file)
@@ -36,6 +36,9 @@
   "Message showing while constructing the diff tree.")
 (make-variable-buffer-local 'ztree-diff-model-wait-message)
 
+(defvar ztree-diff-model-ignore-fun nil
+  "Function which determines if the node should be excluded from comparison.")
+(make-variable-buffer-local 'ztree-diff-model-ignore-fun)
 
 (defun ztree-diff-model-update-wait-message ()
   "Update the wait mesage with one more '.' progress indication."
@@ -43,8 +46,6 @@
     (setq ztree-diff-model-wait-message (concat ztree-diff-model-wait-message "."))
     (message ztree-diff-model-wait-message)))
 
-
-
 ;; Create a record ztree-diff-node with defined fields and getters/setters
 ;; here:
 ;; parent - parent node
 ;; different = {nil, 'new, 'diff} - means comparison status
 (ztree-defrecord ztree-diff-node (parent left-path right-path short-name right-short-name children different))
 
+(defun ztree-diff-model-ignore-p (node)
+  "Determine if the NODE should be excluded from comparison results."
+  (when ztree-diff-model-ignore-fun
+    (funcall ztree-diff-model-ignore-fun node)))
+
 (defun ztree-diff-node-to-string (node)
   "Construct the string with contents of the NODE given."
   (let* ((string-or-nil #'(lambda (x) (if x
@@ -118,6 +124,7 @@ RIGHT if only on the right side."
 
 (defun ztree-diff-untrampify-filename (file)
   "Return FILE as the local file name."
+  ;; FIXME: We shouldn't use internal Tramp functions.
   (require 'tramp)
   (if (not (tramp-tramp-file-p file))
       file
@@ -130,6 +137,10 @@ RIGHT if only on the right side."
 (defun ztree-diff-model-files-equal (file1 file2)
   "Compare files FILE1 and FILE2 using external diff.
 Returns t if equal."
+  ;; FIXME: This "untrampification" only works if both file1 and file2 are on
+  ;; the same host.
+  ;; FIXME: We assume that default-directory is also on the same host as
+  ;; file(1|2).
   (let* ((file1-untrampified (ztree-diff-untrampify-filename (ztree-diff-modef-quotify-string file1)))
          (file2-untrampified (ztree-diff-untrampify-filename (ztree-diff-modef-quotify-string file2)))
          (diff-command (concat "diff -q" " " file1-untrampified " " file2-untrampified))
@@ -148,8 +159,7 @@ Filters out . and .."
   "Rescan the NODE."
   ;; assuming what parent is always exists
   ;; otherwise the UI shall force the full rescan
-  (let ((parent (ztree-diff-node-parent node))
-        (isdir (ztree-diff-node-is-directory node))
+  (let ((isdir (ztree-diff-node-is-directory node))
         (left (ztree-diff-node-left-path node))
         (right (ztree-diff-node-right-path node)))
     ;; if node is a directory - traverse
@@ -204,10 +214,11 @@ Argument SIDE either 'left or 'right side."
   (let ((children (ztree-diff-node-children node))
         (diff nil))
     (dolist (child children)
-      (setq diff
-            (ztree-diff-model-update-diff
-             diff
-             (ztree-diff-node-different child))))
+      (unless (ztree-diff-model-ignore-p child)
+        (setq diff
+              (ztree-diff-model-update-diff
+               diff
+               (ztree-diff-node-different child)))))
     (ztree-diff-node-set-different node diff)))
 
 (defun ztree-diff-node-update-all-parents-diff (node)
@@ -274,12 +285,14 @@ the rest is the combined list of nodes."
               (setq different (car traverse))
               ;; 3.2.3 set the children list from the 2 subdirectories comparison
               (setq children (cdr traverse)))))
-        ;; 2.3 update difference status for the whole comparison
-        (setq different-dir (ztree-diff-model-update-diff different-dir different))
         ;; update calculated parameters of the node
         (ztree-diff-node-set-right-path node file2)
         (ztree-diff-node-set-children node children)
         (ztree-diff-node-set-different node different)
+        ;; 2.3 update difference status for the whole comparison
+        ;; depending if the node should participate in overall result
+        (unless (ztree-diff-model-ignore-p node)
+          (setq different-dir (ztree-diff-model-update-diff different-dir different)))
         ;; push the created node to the result list
         (push node result)))
     ;; second - adding entries from the right directory which are not present
@@ -299,25 +312,31 @@ the rest is the combined list of nodes."
                                                                  simple-name)
                                                    (eq isdir (file-directory-p x)))))))
         ;; if it is not in the first directory, add it as a node
-        (when (not file1)
+        (unless file1
           ;; if it is a directory, set the whole subtree to children
           (when (file-directory-p file2)
             (setq children (ztree-diff-model-subtree node file2 'right)))
-          ;; update the different status for the whole comparison
-          (setq different-dir (ztree-diff-model-update-diff different-dir 'new))
           ;; set calculated children to the node
           (ztree-diff-node-set-children node children)
+          ;; update the different status for the whole comparison
+          ;; depending if the node should participate in overall result
+          (unless (ztree-diff-model-ignore-p node)
+            (setq different-dir (ztree-diff-model-update-diff different-dir 'new)))
           ;; push the created node to the result list
           (push node result))))
     ;; result is a pair: difference status and nodes list
     (cons different-dir result)))
 
-(defun ztree-diff-model-create (dir1 dir2)
-  "Create a node based on DIR1 and DIR2."
-  (when (not (file-directory-p dir1))
+(defun ztree-diff-model-create (dir1 dir2 &optional ignore-p)
+  "Create a node based on DIR1 and DIR2.
+IGNORE-P is the optional filtering function, taking node as
+an argument, which determines if the node should be excluded
+from comparison."
+  (unless (file-directory-p dir1)
     (error "Path %s is not a directory" dir1))
-  (when (not (file-directory-p dir2))
+  (unless (file-directory-p dir2)
     (error "Path %s is not a directory" dir2))
+  (setf ztree-diff-model-ignore-fun ignore-p)
   (setq ztree-diff-model-wait-message (concat "Comparing " dir1 " and " dir2 " ..."))
   (let* ((model
           (ztree-diff-node-create nil dir1 dir2