emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master d0e255e 20/92: Implemented difftree model


From: Alexey Veretennikov
Subject: [elpa] master d0e255e 20/92: Implemented difftree model
Date: Thu, 11 Jun 2015 19:47:55 +0000

branch: master
commit d0e255e8f46dad88a86adde6bda265ab30de36ca
Author: Alexey Veretennikov <address@hidden>
Commit: Alexey Veretennikov <address@hidden>

    Implemented difftree model
---
 ztree-diff-model.el |  161 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 123 insertions(+), 38 deletions(-)

diff --git a/ztree-diff-model.el b/ztree-diff-model.el
index 896ece6..b4360da 100644
--- a/ztree-diff-model.el
+++ b/ztree-diff-model.el
@@ -1,8 +1,6 @@
 ;; Diff model
 
-(defun ztree-diff-model-get-left-path (node)
-  (plist-get node 'path))
-
+;; different = {nil, 'new, 'diff}
 (defun ztree-diff-model-create-node (left-full-path right-full-path short-name 
children different)
   (let (node)
     (setq node (plist-put node 'left left-full-path))
@@ -11,48 +9,135 @@
     (setq node (plist-put node 'children children))
     (setq node (plist-put node 'different different))))
 
+(defun ztree-diff-model-get-left-path (node)
+  (plist-get node 'left))
+
+(defun ztree-diff-model-get-right-path (node)
+  (plist-get node 'right))
+
 
-(defun ztree-diff-model-files-are-different (file1 file2)
+(defun ztree-diff-model-files-equal (file1 file2)
+  "Compare files using external diff. Returns t if equal"
   (let ((diff-output (shell-command-to-string (concat "diff -q" " " file1 " " 
file2))))
-    (> (length diff-output) 2)))
+    (not (> (length diff-output) 2))))
+
+
+(defun ztree-directory-files (dir)
+  "Returns the list of full paths of files in a directory, filtering out . and 
.."
+  (ztree-filter #'(lambda (file) (let ((simple-name (file-short-name file)))
+                                   (not (or (string-equal simple-name ".")
+                                            (string-equal simple-name "..")))))
+                (directory-files dir 'full)))
+
+(defun ztree-diff-model-subtree (path side)
+  "Creates a subtree for the given path for either 'left or 'right sides"
+  (let ((files (ztree-directory-files path))
+        (result nil))
+    (dolist (file files)
+      (if (file-directory-p file)
+          (push (ztree-diff-model-create-node
+                 (when (eq side 'left) path)
+                 (when (eq side 'right) path)
+                 (file-short-name file)
+                 (ztree-diff-model-subtree file side)
+                 'new)
+                result)
+        (push (ztree-diff-model-create-node
+               (when (eq side 'left) path)
+               (when (eq side 'right) path)
+               (file-short-name file)
+               nil
+               'new)
+              result)))
+    result))
+
+
+(defun ztree-diff-model-update-diff (old new)
+  (if new
+      (if (or (not old)
+              (eq old 'new))
+          new
+        old)
+    old))
 
 (defun ztree-diff-model-traverse (path1 path2)
-  (let ((list1 (directory-files path1 'full))
-        (list2 (directory-files path2 'full))
+  "Function traversing 2 paths returning the list where the
+first element is the difference status (nil, 'diff, 'new') and
+the rest is the combined list of nodes"
+  (let ((list1 (ztree-directory-files path1))
+        (list2 (ztree-directory-files path2))
+        (different-dir nil)
         (result nil))
-    ;; first - adding all files from left directory
+    ;; first - adding all entries from left directory
     (dolist (file1 list1)
-      (let ((simple-name (file-short-name file1)))
-        ;; if a file is not a special
-        (if (not (or (string-equal simple-name ".")
-                     (string-equal simple-name "..")))
-            ;; find if the file is in the second directory
-            (let ((file2 (ztree-find list2
-                                     #'(lambda (x) (string-equal 
(file-short-name x)
-                                                                 
simple-name))))
-                  (children nil)
-                  (different nil))
-              (when (and file2
-                         (not (file-directory-p file1))
-                         (setq different
-                               (ztree-diff-model-files-are-different file1 
file2))))
-              (push (ztree-diff-model-create-node file1 file2 simple-name nil 
different)
-                    result)))))
-    ;; second - adding files from right directory which are missing in first 
directory
+      ;; for every entry in the first directory 
+      ;; we are creating the node
+      (let* ((simple-name (file-short-name file1))
+             (isdir (file-directory-p file1))
+             (children nil)
+             (different nil)
+             ;; 1. find if the file is in the second directory and the type
+             ;;    is the same - i.e. both are directories or both are files
+             (file2 (ztree-find list2
+                                #'(lambda (x) (and (string-equal 
(file-short-name x)
+                                                                 simple-name)
+                                                   (eq isdir (file-directory-p 
x)))))))
+        ;; 2. if it is not in the second directory, add it as a node
+        (if (not file2)
+            (progn
+              ;; 2.1 if it is a directory, add the whole subtree
+              (when (file-directory-p file1)
+                (setq children (ztree-diff-model-subtree file1 'left)))
+              ;; 2.2 update the difference status for this entry
+              (setq different 'new))
+          ;; 3. if it is found in second directory and of the same type
+          ;; 3.1 if it is a file
+          (if (not (file-directory-p file1))
+              ;; 3.1.1 set difference status to this entry
+              (setq different (if (ztree-diff-model-files-equal file1 file2) 
nil 'diff))
+            ;; 3.2 if it is the directory
+            ;; 3.2.1 get the result of the directories comparison together 
with status
+            (let ((traverse (ztree-diff-model-traverse file1 file2)))
+              ;; 3.2.2 update the difference status for whole comparison from
+              ;;       difference result from the 2 subdirectories comparison
+              (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))
+        ;; push the created node to the result list
+        (push (ztree-diff-model-create-node file1 file2 simple-name children 
different)
+                result)))
+    ;; second - adding entries from the right directory which are not present
+    ;; in the left directory
     (dolist (file2 list2)
-      (let ((simple-name (file-short-name file2)))
-        ;; if a file is not a special
-        (if (not (or (string-equal simple-name ".")
-                     (string-equal simple-name "..")))
-            ;; find if the file is in the second directory
-            (let ((file1 (ztree-find list1
-                                     #'(lambda (x) (string-equal 
(file-short-name x)
-                                                                 
simple-name))))
-                  (children nil))
-              (when (not file1)
-                (push (ztree-diff-model-create-node nil file2 simple-name 
children nil)
-                    result))))))
-    result))
+      ;; for every entry in the second directory 
+      ;; we are creating the node
+      (let* ((simple-name (file-short-name file2))
+             (isdir (file-directory-p file2))
+             (children nil)
+             ;; 1. find if the file is in the first directory and the type
+             ;;    is the same - i.e. both are directories or both are files
+             (file1 (ztree-find list1
+                                #'(lambda (x) (and (string-equal 
(file-short-name x)
+                                                                 simple-name)
+                                                   (eq isdir (file-directory-p 
x)))))))
+        ;; if it is not in the first directory, add it as a node
+        (when (not file1)
+          ;; if it is a directory, set the whole subtree to children
+          (when (file-directory-p file2)
+            (setq children (ztree-diff-model-subtree file2 'right)))
+          ;; update the different status for the whole comparison
+          (setq different-dir (ztree-diff-model-update-diff different-dir 
'new))
+          ;; push the created node to the result list
+          (push (ztree-diff-model-create-node file1 file2 simple-name children 
'new)
+                result))))
+    (cons different-dir result)))
+
+
+(ztree-diff-model-traverse "path1" "path2")
+
+
 
                               
         



reply via email to

[Prev in Thread] Current Thread [Next in Thread]