branch: master commit 6d7ce1ff3617930ec2ca9ce2a6303c4e94d80649 Author: Alexey Veretennikov <alexey.veretenni...@gmail.com> Commit: Alexey Veretennikov <alexey.veretenni...@gmail.com>
Fixed Delete method --- ztree-diff-model.el | 19 +++++++++++ ztree-diff.el | 91 +++++++++++++++++++++++++++------------------------ 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/ztree-diff-model.el b/ztree-diff-model.el index c088ef5..5a728a7 100644 --- a/ztree-diff-model.el +++ b/ztree-diff-model.el @@ -116,6 +116,7 @@ RIGHT if only on the right side." (if (and left right) 'both (if left 'left 'right)))) + (defun ztree-diff-node-equal (node1 node2) "Determines if NODE1 and NODE2 are equal." (and (string-equal (ztree-diff-node-short-name node1) @@ -234,6 +235,24 @@ If the OLD is 'ignore, do not change anything" ;; all other cases return old (t old))) +(defun ztree-diff-node-update-diff-from-parent (node) + "Recursively update diff status of all children of NODE. +This function will traverse through all children recursively +setting status from the NODE, unless they have an ignore status" + (let ((status (ztree-diff-node-different node)) + (children (ztree-diff-node-children node))) + ;; if the parent has ignore status, force all kids this status + ;; otherwise only update status when the child status is not ignore + (mapc (lambda (child) + (when (or (eql status 'ignore) + (not + (or (eql status 'ignore) + (eql (ztree-diff-node-different child) 'ignore)))) + (ztree-diff-node-set-different child status) + (ztree-diff-node-update-diff-from-parent child))) + children))) + + (defun ztree-diff-model-find-in-files (list shortname is-dir) "Find in LIST of files the file with name SHORTNAME. diff --git a/ztree-diff.el b/ztree-diff.el index 464584f..59e01b9 100644 --- a/ztree-diff.el +++ b/ztree-diff.el @@ -402,53 +402,58 @@ COPY-TO-RIGHT specifies which side of the NODE to update." (and (eql node-side 'both) (eql side 'left)))) (remove-path (if delete-from-left - (ztree-diff-node-left-path node) - (ztree-diff-node-right-path node)))) + (ztree-diff-node-left-path node) + (ztree-diff-node-right-path node)))) (when (and parent ; do not delete the root node (yes-or-no-p (format "Delete the file [%s]%s ?" (if delete-from-left "LEFT" "RIGHT") remove-path))) - (let* ((delete-command - (if (file-directory-p remove-path) - #'delete-directory - #'delete-file)) - (children (ztree-diff-node-children parent)) - (err - (condition-case error-trap - (progn - (funcall delete-command remove-path t) - nil) - (error error-trap)))) - (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))) - ;; if everything ok - ;; if was only on one side - ;; remove the node from children - (if (or (and (eql node-side 'left) - delete-from-left) - (and (eql node-side 'right) - (not delete-from-left))) - (ztree-diff-node-set-children parent - (ztree-filter - (lambda (x) (not (ztree-diff-node-equal x node))) - children)) - ;; otherwise update only one side - (if delete-from-left - (ztree-diff-node-set-left-path node nil) - (ztree-diff-node-set-right-path node nil)) - ;; and update diff status - ;; if was ignored keep the old status - (unless (eql (ztree-diff-node-different node) 'ignore) - (ztree-diff-node-set-different node 'new)))) - (ztree-diff-node-update-all-parents-diff node) - (ztree-refresh-buffer (line-number-at-pos)))))))) + (let* ((delete-command + (if (file-directory-p remove-path) + #'delete-directory + #'delete-file)) + (children (ztree-diff-node-children parent)) + (err + (condition-case error-trap + (progn + (funcall delete-command remove-path t) + nil) + (error error-trap)))) + (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))) + ;; if everything ok + ;; if was only on one side + ;; remove the node from children + (if (or (and (eql node-side 'left) + delete-from-left) + (and (eql node-side 'right) + (not delete-from-left))) + (ztree-diff-node-set-children parent + (ztree-filter + (lambda (x) (not (ztree-diff-node-equal x node))) + children)) + ;; otherwise update only one side + (let ((update-fun + (if delete-from-left + #'ztree-diff-node-set-left-path + #'ztree-diff-node-set-right-path))) + (mapcar (lambda (x) (funcall update-fun x nil)) + (cons node (ztree-diff-node-children node)))) + ;; and update diff status + ;; if was ignored keep the old status + (unless (eql (ztree-diff-node-different node) 'ignore) + (ztree-diff-node-set-different node 'new)) + ;; finally update all children statuses + (ztree-diff-node-update-diff-from-parent node))) + (ztree-diff-node-update-all-parents-diff node) + (ztree-refresh-buffer (line-number-at-pos))))))))