]> code.delx.au - gnu-emacs-elpa/commitdiff
Fixed issue #15; added hotkey 'H' to show/hide filtered files; fixed bug with removin...
authorAlexey Veretennikov <txm.fourier@gmail.com>
Wed, 17 Jun 2015 21:44:28 +0000 (23:44 +0200)
committerAlexey Veretennikov <txm.fourier@gmail.com>
Wed, 17 Jun 2015 21:44:28 +0000 (23:44 +0200)
ztree-diff-model.el
ztree-diff.el

index b68631e052eb8d06330f06521bd7b1010648a21b..7bec4619b633757b4ee998a855b23476ea1a8af9 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
@@ -204,10 +210,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 +281,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 +308,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
index 6fd3644a831e55431ef271476f7c8cd7481e54db..ff9b3235f1207de464b1bb920410dba88107c230 100644 (file)
@@ -83,6 +83,9 @@ By default paths starting with dot (like .git) are ignored")
   "Show or not equal files/directories on both sides.")
 (make-variable-buffer-local 'ztree-diff-show-equal-files)
 
+(defvar ztree-diff-show-filtered-files nil
+  "Show or not files from the filtered list.")
+
 ;;;###autoload
 (define-minor-mode ztreediff-mode
   "A minor mode for displaying the difference of the directory trees in text mode."
@@ -94,6 +97,7 @@ By default paths starting with dot (like .git) are ignored")
   `(
     (,(kbd "C") . ztree-diff-copy)
     (,(kbd "h") . ztree-diff-toggle-show-equal-files)
+    (,(kbd "H") . ztree-diff-toggle-show-filtered-files)
     (,(kbd "D") . ztree-diff-delete-file)
     (,(kbd "v") . ztree-diff-view-file)
     (,(kbd "d") . ztree-diff-simple-diff-files)
@@ -382,38 +386,61 @@ COPY-TO-RIGHT specifies which side of the NODE to update."
                                      remove-path))
             (let* ((delete-command
                     (if (file-directory-p remove-path)
-                        '(delete-directory remove-path t)
-                      '(delete-file remove-path t)))
+                        #'delete-directory
+                      #'delete-file))
                    (children (ztree-diff-node-children parent))
                    (err
                     (condition-case error-trap
                         (progn
-                          (eval delete-command)
+                          (funcall delete-command remove-path t)
                           nil)
                       (error error-trap))))
-              (if err (message (concat "Error: " (nth 2 err)))
+              (if err
+                  (progn
+                    (message (concat "Error: " (nth 2 err)))
+                    ;; when error happened while deleting the
+                    ;; directory, rescan the node
+                    ;; and update the parents with a new status
+                    ;; of this node
+                    (when (file-directory-p remove-path)
+                      (ztree-diff-model-partial-rescan node)
+                      (ztree-diff-node-update-all-parents-diff node)))
+                ;; if everything ok 
                 (progn
+                  ;; remove the node from children
                   (setq children (ztree-filter
                                   #'(lambda (x) (not (ztree-diff-node-equal x node)))
                                   children))
                   (ztree-diff-node-set-children parent children))
                 (ztree-diff-node-update-all-parents-diff node)
+                ;;(ztree-diff-model-partial-rescan node)
                 (ztree-refresh-buffer (line-number-at-pos))))))))))
 
 
 
-(defun ztree-node-is-in-filter-list (node)
+(defun ztree-diff-node-ignore-p (node)
   "Determine if the NODE is in filter list.
-If the node is in the filter list it shall not be visible"
-  (ztree-find ztree-diff-filter-list #'(lambda (rx) (string-match rx node))))
+If the node is in the filter list it shall not be visible,
+unless it is a parent node."
+  (let ((name (ztree-diff-node-short-name node)))
+    ;; ignore then
+    ;; not a root and is in filter list
+    (and (ztree-diff-node-parent node)
+         (ztree-find ztree-diff-filter-list #'(lambda (rx) (string-match rx name))))))
 
 
 (defun ztree-node-is-visible (node)
   "Determine if the NODE should be visible."
-  (and (ztree-diff-node-parent node)    ; parent is always visible
-       (not (ztree-node-is-in-filter-list (ztree-diff-node-short-name node)))
-       (or ztree-diff-show-equal-files
-           (ztree-diff-node-different node))))
+  ;; visible then
+  ;; 1) either it is a parent
+  (or (not (ztree-diff-node-parent node))    ; parent is always visible
+      (and
+       ;; 2.1) or it is not in ignore list and 
+       (or ztree-diff-show-filtered-files ; show filtered files regardless
+           (not (ztree-diff-node-ignore-p node)))
+       ;; 2.2) it has different status
+       (or ztree-diff-show-equal-files  ; show equal files regardless
+           (ztree-diff-node-different node)))))
 
 (defun ztree-diff-toggle-show-equal-files ()
   "Toggle visibility of the equal files."
@@ -421,13 +448,20 @@ If the node is in the filter list it shall not be visible"
   (setq ztree-diff-show-equal-files (not ztree-diff-show-equal-files))
   (ztree-refresh-buffer))
 
+(defun ztree-diff-toggle-show-filtered-files ()
+  "Toggle visibility of the filtered files."
+  (interactive)
+  (setq ztree-diff-show-filtered-files (not ztree-diff-show-filtered-files))
+  (ztree-refresh-buffer))
+
+
 ;;;###autoload
 (defun ztree-diff (dir1 dir2)
   "Create an interactive buffer with the directory tree of the path given.
 Argument DIR1 left directory.
 Argument DIR2 right directory."
   (interactive "DLeft directory \nDRight directory ")
-  (let* ((difference (ztree-diff-model-create dir1 dir2))
+  (let* ((difference (ztree-diff-model-create dir1 dir2 #'ztree-diff-node-ignore-p))
          (buf-name (concat "*"
                            (ztree-diff-node-short-name difference)
                            " <--> "