From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#33319: Support revisions in diff-goto-source Date: Sat, 10 Nov 2018 23:12:51 +0200 Organization: LINKOV.NET Message-ID: <87in14ra6c.fsf@mail.linkov.net> References: <87lg63p9fd.fsf@mail.linkov.net> <83pnvebscp.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1541887161 15404 195.159.176.226 (10 Nov 2018 21:59:21 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 10 Nov 2018 21:59:21 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) Cc: 33319@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Nov 10 22:59:17 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gLbHf-0003q4-CJ for geb-bug-gnu-emacs@m.gmane.org; Sat, 10 Nov 2018 22:59:15 +0100 Original-Received: from localhost ([::1]:40123 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gLbJl-00015u-TX for geb-bug-gnu-emacs@m.gmane.org; Sat, 10 Nov 2018 17:01:25 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39066) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gLbIa-0007Rp-2x for bug-gnu-emacs@gnu.org; Sat, 10 Nov 2018 17:00:13 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gLbIV-0006a7-2R for bug-gnu-emacs@gnu.org; Sat, 10 Nov 2018 17:00:12 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:40864) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gLbIU-0006Zb-Tb for bug-gnu-emacs@gnu.org; Sat, 10 Nov 2018 17:00:06 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gLbIU-0004uI-PQ for bug-gnu-emacs@gnu.org; Sat, 10 Nov 2018 17:00:06 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 10 Nov 2018 22:00:06 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 33319 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 33319-submit@debbugs.gnu.org id=B33319.154188714618652 (code B ref 33319); Sat, 10 Nov 2018 22:00:06 +0000 Original-Received: (at 33319) by debbugs.gnu.org; 10 Nov 2018 21:59:06 +0000 Original-Received: from localhost ([127.0.0.1]:45102 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gLbHV-0004ql-Mf for submit@debbugs.gnu.org; Sat, 10 Nov 2018 16:59:06 -0500 Original-Received: from indri.birch.relay.mailchannels.net ([23.83.209.92]:39677) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gLbHT-0004qT-Uj for 33319@debbugs.gnu.org; Sat, 10 Nov 2018 16:59:04 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Original-Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 79295501AD7; Sat, 10 Nov 2018 21:59:02 +0000 (UTC) Original-Received: from pdx1-sub0-mail-a77.g.dreamhost.com (unknown [100.96.30.62]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 33CC2501C29; Sat, 10 Nov 2018 21:59:02 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Original-Received: from pdx1-sub0-mail-a77.g.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.16.2); Sat, 10 Nov 2018 21:59:02 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Squirrel-Vacuous: 6e6d6e7b79a078f5_1541887142297_3299193152 X-MC-Loop-Signature: 1541887142297:3678935671 X-MC-Ingress-Time: 1541887142297 Original-Received: from pdx1-sub0-mail-a77.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a77.g.dreamhost.com (Postfix) with ESMTP id 026838091E; Sat, 10 Nov 2018 13:59:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=linkov.net; bh=UBsP1iKA+HLhdu/5+riIETP79BY=; b= Yeld2837ULQuQpgIhnuQPzAyrISUuKBmA9ejCnt266t01bxl3GebKcz/zCdlahRK Od+8zI3KznPOaSvcjwxwr5PrA1qPp09UWNTgoXO7+0P0FputnfGJva2+WHiBxo5P uqtCvOx0JXzWk/xZ8Nj2fU6BgYR4BXT5fHbHCW/qWxc= Original-Received: from mail.jurta.org (m91-129-107-244.cust.tele2.ee [91.129.107.244]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a77.g.dreamhost.com (Postfix) with ESMTPSA id A1E3E7F44E; Sat, 10 Nov 2018 13:59:00 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a77 In-Reply-To: <83pnvebscp.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 09 Nov 2018 09:52:22 +0200") X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrkeehgdduheeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuggftfghnshhusghstghrihgsvgdpffftgfetoffjqffuvfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufhofhffjgfkfgggtgesmhdtreertdertdenucfhrhhomheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqeenucfkphepledurdduvdelrddutdejrddvgeegnecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehmrghilhdrjhhurhhtrgdrohhrghdpihhnvghtpeeluddruddvledruddtjedrvdeggedprhgvthhurhhnqdhprghthheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqedpmhgrihhlfhhrohhmpehjuhhriheslhhinhhkohhvrdhnvghtpdhnrhgtphhtthhopegvlhhiiiesghhnuhdrohhrghenucevlhhushhtvghrufhiiigvpedu X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:152281 Archived-At: --=-=-= Content-Type: text/plain >> +*** In the diff buffer created by a version control system, the prefix >> +arg of diff-goto-source means it jumps to the old revision of the file > ^^^^^^^^^^^^^^^^^ > "... means jump to ..." is a better wording, I think. > > Also, it is best to provide a header for the description of the > change, so that it could be meaningfully folded by Outline mode. Fixed in a new patch. > And I think we want to update the manual as well. Updated. >> +(defvar diff-vc-revisions nil >> + "The VC revisions compared in the current Diff buffer, if any.") >> + >> (defvar diff-outline-regexp >> "\\([*+][*+][*+] [^0-9]\\|@@ ...\\|\\*\\*\\* [0-9].\\|--- [0-9]..\\)") > > Which VCSes does this support? I'm not sure all of them produce such > markers. If this supports only some, we should document that and make > sure the code does something reasonable when the revision is not > found. It should work in all VCSes that support the VC interface function 'find-revision' defined in the comments of vc.el: ;; * find-revision (file rev buffer) ;; ;; Fetch revision REV of file FILE and put it into BUFFER. ;; If REV is the empty string, fetch the head of the trunk. ;; The implementation should pass the value of vc-checkout-switches ;; to the backend command. BTW, its implementation in vc-find-revision currently has a major shortcoming: it always saves the retrieved revision to the file. I spend too much time cleaning after this command all old files that it creates. Thus I propose a new option `vc-find-revision-no-save' to not save the buffer it creates to the file. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=diff-goto-source.2.patch diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 6c68075ae4..523734ec1f 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -1507,7 +1507,11 @@ Diff Mode @item C-c C-c @findex diff-goto-source Go to the source file and line corresponding to this hunk -(@code{diff-goto-source}). +(@code{diff-goto-source}). With a prefix argument of @kbd{C-u}, +go to the old source file. If the source file is under version +control (@pxref{Version Control}), with a prefix argument of +@kbd{C-u}, go to the old revision of the file (@pxref{Old Revisions}) +when point is on old line, or otherwise to the new revision. @item C-c C-e @findex diff-ediff-patch diff --git a/etc/NEWS b/etc/NEWS index 29bbde9395..cea600c430 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -334,6 +334,9 @@ still be used if it exists.) Set the variable to nil to get the previous behavior of always creating a buffer that visits a ChangeLog file. +*** New customizable variable 'vc-find-revision-no-save'. +With non-nil, 'vc-find-revision' doesn't write the created buffer to file. + *** New customizable variable 'vc-git-grep-template'. This new variable allows customizing the default arguments passed to git-grep when 'vc-git-grep' is used. @@ -358,6 +361,10 @@ To disable it, set the new defcustom 'diff-font-lock-refine' to nil. *** File headers can be shortened, mimicking Magit's diff format. To enable it, set the new defcustom 'diff-font-lock-prettify to t. +*** Prefix arg of 'diff-goto-source' means jump to the old revision +of the file under version control if point is on an old changed line, +or to the new revision of the file otherwise. + ** Browse-url *** The function 'browse-url-emacs' can now visit a URL in selected window. diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index cf52368508..aef16e2e67 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -104,6 +105,9 @@ diff-font-lock-prettify (defvar diff-vc-backend nil "The VC backend that created the current Diff buffer, if any.") +(defvar diff-vc-revisions nil + "The VC revisions compared in the current Diff buffer, if any.") + (defvar diff-outline-regexp "\\([*+][*+][*+] [^0-9]\\|@@ ...\\|\\*\\*\\* [0-9].\\|--- [0-9]..\\)") @@ -1736,7 +1740,12 @@ diff-find-source-location (match-string 1))))) (file (or (diff-find-file-name other noprompt) (error "Can't find the file"))) - (buf (find-file-noselect file))) + (revision (and other diff-vc-backend + (nth (if reverse 1 0) diff-vc-revisions))) + (buf (if revision + (let ((vc-find-revision-no-save t)) + (vc-find-revision file revision diff-vc-backend)) + (find-file-noselect file)))) ;; Update the user preference if he so wished. (when (> (prefix-numeric-value other-file) 8) (setq diff-jump-to-old-file other)) @@ -1862,7 +1871,11 @@ diff-goto-source `diff-jump-to-old-file' (or its opposite if the OTHER-FILE prefix arg is given) determines whether to jump to the old or the new file. If the prefix arg is bigger than 8 (for example with \\[universal-argument] \\[universal-argument]) -then `diff-jump-to-old-file' is also set, for the next invocations." +then `diff-jump-to-old-file' is also set, for the next invocations. + +Under version control, the OTHER-FILE prefix arg means jump to the old +revision of the file if point is on an old changed line, or to the new +revision of the file otherwise." (interactive (list current-prefix-arg last-input-event)) ;; When pointing at a removal line, we probably want to jump to ;; the old location, and else to the new (i.e. as if reverting). diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index dcfbf26e86..7c4c288b66 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -871,6 +871,12 @@ vc-comment-alist (string :tag "Comment End"))) :group 'vc) +(defcustom vc-find-revision-no-save nil + "If non-nil, `vc-find-revision' doesn't write the created buffer to file." + :type 'boolean + :group 'vc + :version "27.1") + ;; File property caching @@ -1728,6 +1735,7 @@ vc-diff-internal (set-buffer buffer) (diff-mode) (set (make-local-variable 'diff-vc-backend) (car vc-fileset)) + (set (make-local-variable 'diff-vc-revisions) (list rev1 rev2)) (set (make-local-variable 'revert-buffer-function) (lambda (_ignore-auto _noconfirm) (vc-diff-internal async vc-fileset rev1 rev2 verbose))) @@ -1951,6 +1959,8 @@ vc-revision-other-window (defun vc-find-revision (file revision &optional backend) "Read REVISION of FILE into a buffer and return the buffer. Use BACKEND as the VC backend if specified." + (if vc-find-revision-no-save + (vc-find-revision-no-save file revision backend) (let ((automatic-backup (vc-version-backup-file-name file revision)) (filebuf (or (get-file-buffer file) (current-buffer))) (filename (vc-version-backup-file-name file revision 'manual))) @@ -1981,6 +1991,38 @@ vc-find-revision ;; Set the parent buffer so that things like ;; C-x v g, C-x v l, ... etc work. (set (make-local-variable 'vc-parent-buffer) filebuf)) + result-buf)))) + +(defun vc-find-revision-no-save (file revision &optional backend) + "Read REVISION of FILE into a buffer and return the buffer. +Unlike `vc-find-revision', doesn't save the created buffer to file." + (let ((filebuf (or (get-file-buffer file) (current-buffer))) + (filename (vc-version-backup-file-name file revision 'manual))) + (unless (or (get-file-buffer filename) + (file-exists-p filename)) + (with-current-buffer filebuf + (let ((failed t)) + (unwind-protect + (let ((coding-system-for-read 'no-conversion) + (coding-system-for-write 'no-conversion)) + (with-current-buffer (create-file-buffer filename) + (setq buffer-file-name filename) + (let ((outbuf (current-buffer))) + (with-current-buffer filebuf + (if backend + (vc-call-backend backend 'find-revision file revision outbuf) + (vc-call find-revision file revision outbuf)))) + (goto-char (point-min)) + (normal-mode) + (set-buffer-modified-p nil) + (setq buffer-read-only t)) + (setq failed nil)) + (when (and failed (get-file-buffer filename)) + (kill-buffer (get-file-buffer filename))))))) + (let ((result-buf (or (get-file-buffer filename) + (find-file-noselect filename)))) + (with-current-buffer result-buf + (set (make-local-variable 'vc-parent-buffer) filebuf)) result-buf))) ;; Header-insertion code --=-=-=--