>From 0b43d95581c36d43995fc27fdb965327937455ae Mon Sep 17 00:00:00 2001 From: Andrii Kolomoiets Date: Sat, 5 Sep 2020 22:18:59 +0300 Subject: [PATCH] Save and restore point in ewoc-invalidate * lisp/emacs-lisp/ewoc.el (ewoc-invalidate): Save and restore point line and column offset. * lisp/vc/vc-dir.el (vc-dir-update): Don't save/restore point on calling 'ewoc-invalidate'. --- lisp/emacs-lisp/ewoc.el | 37 ++++++++++++++++++++++++++++++++++--- lisp/vc/vc-dir.el | 6 +----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/lisp/emacs-lisp/ewoc.el b/lisp/emacs-lisp/ewoc.el index 78ada3e076..6a37309eb1 100644 --- a/lisp/emacs-lisp/ewoc.el +++ b/lisp/emacs-lisp/ewoc.el @@ -461,9 +461,40 @@ ewoc-invalidate Delete current text first, thus effecting a \"refresh\"." (ewoc--set-buffer-bind-dll-let* ewoc ((pp (ewoc--pretty-printer ewoc))) - (save-excursion - (dolist (node nodes) - (ewoc--refresh-node pp node dll))))) + (let ((point (point)) + (footer-start (ewoc-location (ewoc--footer ewoc))) + (refresh-nodes (lambda () + (dolist (node nodes) + (ewoc--refresh-node pp node dll))))) + (cond + ((= point footer-start) + (funcall refresh-nodes)) + ((or (> point footer-start) + (<= point (ewoc-location (ewoc-nth ewoc 0)))) + (save-excursion + (funcall refresh-nodes))) + (t + (let* ((node-start (ewoc-location (ewoc-locate ewoc))) + (line (- (line-number-at-pos point) + (line-number-at-pos node-start))) + (column (min (- point node-start) + (- point (line-beginning-position))))) + (funcall refresh-nodes) + (goto-char node-start) + (let* ((node-end (1- (ewoc-location + (ewoc--node-right (ewoc-locate ewoc))))) + (line-start (line-number-at-pos node-start)) + (line-end (line-number-at-pos node-end)) + (line (min line (- line-end line-start))) + (line-beginning-position (line-beginning-position)) + (line-end-position (line-end-position))) + (when (> line 0) + (forward-line line)) + (forward-char (min column + (- node-end node-start) + (- node-end line-beginning-position) + (- line-end-position line-beginning-position) + (- line-end-position node-start)))))))))) (defun ewoc-goto-prev (ewoc arg) "Move point to the ARGth previous element in EWOC. diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 6c219005ce..cdf8ab984e 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -451,11 +451,7 @@ vc-dir-update (setf (vc-dir-fileinfo->state (ewoc-data node)) (nth 1 entry)) (setf (vc-dir-fileinfo->extra (ewoc-data node)) (nth 2 entry)) (setf (vc-dir-fileinfo->needs-update (ewoc-data node)) nil) - ;; `ewoc-invalidate' will kill line and insert new text, - ;; let's keep point column. - (let ((p (point))) - (ewoc-invalidate vc-ewoc node) - (goto-char p))) + (ewoc-invalidate vc-ewoc node)) ;; If the state is nil, the file does not exist ;; anymore, so remember the entry so we can remove ;; it after we are done inserting all ENTRIES. -- 2.15.1