From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Andrii Kolomoiets Newsgroups: gmane.emacs.devel Subject: Re: master f450798: Don't move point in vc-dir on vc-register/vc-checkin (bug#43188) Date: Sun, 13 Sep 2020 21:58:20 +0300 Message-ID: References: <20200904211737.15548.63989@vcs0.savannah.gnu.org> <20200904211738.DA94720667@vcs0.savannah.gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32926"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (darwin) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Sep 13 20:59:14 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kHXDV-0008RI-00 for ged-emacs-devel@m.gmane-mx.org; Sun, 13 Sep 2020 20:59:13 +0200 Original-Received: from localhost ([::1]:47276 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kHXDU-0002H4-0E for ged-emacs-devel@m.gmane-mx.org; Sun, 13 Sep 2020 14:59:12 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:55838) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kHXCm-0001Rz-Fa for emacs-devel@gnu.org; Sun, 13 Sep 2020 14:58:28 -0400 Original-Received: from mail-lj1-x22a.google.com ([2a00:1450:4864:20::22a]:32801) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kHXCk-0004f2-Ne for emacs-devel@gnu.org; Sun, 13 Sep 2020 14:58:28 -0400 Original-Received: by mail-lj1-x22a.google.com with SMTP id k25so16740886ljk.0 for ; Sun, 13 Sep 2020 11:58:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=BHh0go1MJzwYJ7ZFUDyrX/JZ+v+oL0tzHV/MYuGtFu0=; b=ONMJxLkCO01rDDoEPyme8lEXaXe2N7B6SLuROXPzcKHCHBMSYcQ6gedubj2RL4omIP f47Z3iIR9egqwfuZQsvjUEmwWXh0vTFjxBq9t+u4esmatzTZt4a5CayTtmB7JUg9ibO2 uKGLdZyy2Q8WGmw5tGkp8evLhDHmRP3e4dNdEsrEjNVfgNIKVGX+UcE0GORtuLQfrSfm DG3ekqiOMuccShRacobJXaIe2sz2c5URgn6pQUc1qCGRbfBuYeQH8TJ8DaSBDfAmxgjg 7TTnrqraBApBmFIYy714gp29wWqXHDp9DizxgzEdTVIqIWj1VABjMyJ8/0VqZ1YnvSMc sdJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=BHh0go1MJzwYJ7ZFUDyrX/JZ+v+oL0tzHV/MYuGtFu0=; b=l7CX5wLiluVZjfFf3fLmYojdoDa1dTntE0qO5wRypdltIJO4BFhY2jJiLQ/aLRtnbE 0UqjSzN5E4g5lDk0Zn5UFOlUIMfvavndX+lW5Xoc+I+QqAEA9M75kwsNLnR1Q+fb/FMg pfv8ufrSgBIOFYygOG4wcVTqM/hpNTgzh3T+5nhCe9Cm3NEY89q2hb2B5x9216874Mmj nqGbOGJ6I1r/KPyqMtsp/HmIt6oxFXOgPieBuuBF4RMkhgW3XnR+d0998pVNGVYY5MOL T5c+WAoUCJfloKSQiPm1httEUFD/qbF06Cks1rmiP3vDLaGF0Sf7fYB5QQjU1U0iY7D4 l3IA== X-Gm-Message-State: AOAM531TK80L2TEiwepvAYi8IkdaA3oWnR0KDXRVSYp26gLaWYB+W4Y6 Ao8gmfL522ma9dvU1vEBqXjhqtyirfE= X-Google-Smtp-Source: ABdhPJwf/UQR/zjHD0MvGU6dH1sQ/L+RDXS0wk1yygCs6pizMqjRXKnYJDTXLRxV/n7DUjPUcBsqlw== X-Received: by 2002:a2e:b522:: with SMTP id z2mr4264008ljm.141.1600023503897; Sun, 13 Sep 2020 11:58:23 -0700 (PDT) Original-Received: from muffinmac ([91.206.110.141]) by smtp.gmail.com with ESMTPSA id u17sm3008317lfi.2.2020.09.13.11.58.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2020 11:58:22 -0700 (PDT) In-Reply-To: (Stefan Monnier's message of "Sat, 05 Sep 2020 15:41:52 -0400") Received-SPF: pass client-ip=2a00:1450:4864:20::22a; envelope-from=andreyk.mad@gmail.com; helo=mail-lj1-x22a.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:255559 Archived-At: --=-=-= Content-Type: text/plain Stefan Monnier writes: >> - (save-excursion >> + (let ((p (point))) >> (dolist (node nodes) >> - (ewoc--refresh-node pp node dll))))) >> + (ewoc--refresh-node pp node dll)) >> + (goto-char p)))) > > Hmm... I think this is an improvement when point is within the refreshed > node, but a regression when it's further down in the buffer. You are right. Take a look at the new patch. ewoc-invalidate now save and restore point line and column offset in the current node. testewoc.el is the code I used to test the patch: 1. emacs -Q 2. M-x load-file testewoc.el 3. M-x testewoc 4. move point somewhere and M-x testewoc-invalidate Point must remain in the same line and column within the node. The nodes is represented with characters "0", "1" and "2". --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=testewoc.el Content-Transfer-Encoding: quoted-printable ;; -*- lexical-binding: t; -*- (require 'ewoc) (defvar testewoc-ewoc nil) (defun testewoc-pp (data) (let ((c (string-to-char (number-to-string data)))) (insert (make-string (random 30) c)) (dotimes (_i (random 5)) (insert (format "\n%s" (make-string (random 30) c)))))) (defun testewoc () (interactive) (switch-to-buffer (get-buffer-create "*testewoc buffer*")) (kill-all-local-variables) (setq major-mode 'testewoc-mode mode-name "Test Ewoc") (erase-buffer) (buffer-disable-undo) (let ((ewoc (ewoc-create 'testewoc-pp "-header-" "-footer-" t))) (set (make-local-variable 'testewoc-ewoc) ewoc) (ewoc-enter-last ewoc 0) (ewoc-enter-last ewoc 1) (ewoc-enter-last ewoc 2))) (defun testewoc-invalidate () (interactive) (ewoc-invalidate testewoc-ewoc (ewoc-nth testewoc-ewoc 0) (ewoc-nth testewoc-ewoc 1) (ewoc-nth testewoc-ewoc 2))) --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Save-and-restore-point-in-ewoc-invalidate.patch >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 --=-=-=--