branch: master commit 865afb08c3a149d7860e12f7461cf1c24c345348 Author: Alexey Veretennikov <alexey.veretenni...@gmail.com> Commit: Alexey Veretennikov <alexey.veretenni...@gmail.com>
Implemented partial rescan/refresh feature ('r' hotkey) --- README.md | 1 + ztree-diff-model.el | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ ztree-diff.el | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 0 deletions(-) diff --git a/README.md b/README.md index 49c74a2..d0cdeb7 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ The basic hotkeys are the same as in the **ztree-dir**. Additionally: * `C` key to copy current file or directory to the left or right panel * `D` key to delete current file or directory * `v` key to quick view the current file + * `r` initiates the rescan/refresh of current file or subdirectory * `F5` forces the full rescan. Screenshots: diff --git a/ztree-diff-model.el b/ztree-diff-model.el index 810d447..8f7fc15 100644 --- a/ztree-diff-model.el +++ b/ztree-diff-model.el @@ -52,6 +52,31 @@ ;; different = {nil, 'new, 'diff} - means comparison status (defrecord ztree-diff-node (parent left-path right-path short-name right-short-name children different)) +(defun ztree-diff-node-to-string (node) + (let* ((string-or-nil #'(lambda (x) (if x + (cond ((stringp x) x) + ((eq x 'new) "new") + ((eq x 'diff) "different") + (t (ztree-diff-node-short-name x))) + "(empty)"))) + (children (ztree-diff-node-children node)) + (ch-str "")) + (dolist (x children) + (setq ch-str (concat ch-str "\n * " (ztree-diff-node-short-name x)))) + (concat "Node: " (ztree-diff-node-short-name node) + "\n" + ;; " * Parent: " (let ((parent (ztree-diff-node-parent node))) + ;; (if parent (ztree-diff-node-short-name parent) "nil")) + " * Parent: " (funcall string-or-nil (ztree-diff-node-parent node)) + "\n" + " * Left path: " (funcall string-or-nil (ztree-diff-node-left-path node)) + "\n" + " * Right path: " (funcall string-or-nil (ztree-diff-node-right-path node)) + "\n" + " * Children: " ch-str + "\n"))) + + (defun ztree-diff-node-short-name-wrapper (node &optional right-side) (if (not right-side) (ztree-diff-node-short-name node) @@ -92,6 +117,31 @@ (string-equal simple-name ".."))))) (directory-files dir 'full))) +(defun ztree-diff-model-partial-rescan (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)) + (left (ztree-diff-node-left-path node)) + (right (ztree-diff-node-right-path node))) + ;; if node is a directory - traverse + (when (and left right + (file-exists-p left) + (file-exists-p right)) + (if isdir + (let ((traverse (ztree-diff-node-traverse + node + left + right))) + (ztree-diff-node-set-different node (car traverse)) + (ztree-diff-node-set-children node (cdr traverse))) + ;; node is a file + (ztree-diff-node-set-different + node + (if (ztree-diff-model-files-equal left right) + nil + 'diff)))))) + (defun ztree-diff-model-subtree (parent path side) "Creates a subtree for the given path for either 'left or 'right sides" (let ((files (ztree-directory-files path)) diff --git a/ztree-diff.el b/ztree-diff.el index b6f7131..e441202 100644 --- a/ztree-diff.el +++ b/ztree-diff.el @@ -94,6 +94,7 @@ including . and ..") (,(kbd "D") . ztree-diff-delete-file) (,(kbd "v") . ztree-diff-view-file) (,(kbd "d") . ztree-diff-simple-diff-files) + (,(kbd "r") . ztree-diff-partial-rescan) ([f5] . ztree-diff-full-rescan))) @@ -135,6 +136,43 @@ including . and ..") (ztree-diff (car ztree-diff-dirs-pair) (cdr ztree-diff-dirs-pair)))) + +(defun ztree-diff-existing-common (node) + (let ((left (ztree-diff-node-left-path node)) + (right (ztree-diff-node-right-path node))) + (princ (ztree-diff-node-to-string node)) + (if (and left right + (file-exists-p left) + (file-exists-p right)) + node + nil))) + +(defun ztree-diff-existing-common-parent (node) + (let ((common (ztree-diff-existing-common node))) + (if common + common + (ztree-diff-existing-common-parent (ztree-diff-node-parent node))))) + +(defun ztree-diff-do-partial-rescan (node) + (let* ((common (ztree-diff-existing-common-parent node)) + (parent (ztree-diff-node-parent common))) + (if (not parent) + (when ztree-diff-dirs-pair + (ztree-diff (car ztree-diff-dirs-pair) (cdr ztree-diff-dirs-pair))) + (progn + (ztree-diff-model-partial-rescan common) + (ztree-diff-node-update-all-parents-diff node) + (ztree-refresh-buffer (line-number-at-pos)))))) + + +(defun ztree-diff-partial-rescan () + "Performs partial rescan on the current node" + (interactive) + (let ((found (ztree-find-node-at-point))) + (when found + (ztree-diff-do-partial-rescan (car found))))) + + (defun ztree-diff-simple-diff (node) "Create a simple diff buffer for files from left and right panels" (let* ((node-left (ztree-diff-node-left-path node))