From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: next-error-find-buffer (was: kill-compilation failing when there are several compilation buffers) Date: Thu, 02 Aug 2007 12:17:44 -0400 Message-ID: References: <87r6mndorr.fsf@jurta.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: sea.gmane.org 1186071983 21809 80.91.229.12 (2 Aug 2007 16:26:23 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 2 Aug 2007 16:26:23 +0000 (UTC) Cc: emacs-devel@gnu.org To: Juri Linkov Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Aug 02 18:26:16 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1IGdV8-0002VN-0w for ged-emacs-devel@m.gmane.org; Thu, 02 Aug 2007 18:26:14 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IGdV7-000479-EO for ged-emacs-devel@m.gmane.org; Thu, 02 Aug 2007 12:26:13 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IGdV3-00045G-M5 for emacs-devel@gnu.org; Thu, 02 Aug 2007 12:26:09 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IGdV3-00044m-60 for emacs-devel@gnu.org; Thu, 02 Aug 2007 12:26:09 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IGdV3-00044j-0o for emacs-devel@gnu.org; Thu, 02 Aug 2007 12:26:09 -0400 Original-Received: from tomts20-srv.bellnexxia.net ([209.226.175.74]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IGdV2-0000BK-K0 for emacs-devel@gnu.org; Thu, 02 Aug 2007 12:26:08 -0400 Original-Received: from pastel.home ([74.12.205.233]) by tomts20-srv.bellnexxia.net (InterMail vM.5.01.06.13 201-253-122-130-113-20050324) with ESMTP id <20070802162607.OSFV8273.tomts20-srv.bellnexxia.net@pastel.home> for ; Thu, 2 Aug 2007 12:26:07 -0400 Original-Received: by pastel.home (Postfix, from userid 20848) id 0394580CD; Thu, 2 Aug 2007 12:17:44 -0400 (EDT) In-Reply-To: <87r6mndorr.fsf@jurta.org> (Juri Linkov's message of "Wed\, 01 Aug 2007 22\:43\:20 +0300") User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux) X-Detected-Kernel: Solaris 8 (1) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:75960 Archived-At: >>> ! (if (and (compilation-buffer-internal-p (current-buffer)) >>> ! (not avoid-current)) >>> ! (current-buffer) >>> ! (next-error-find-buffer avoid-current 'compilation-buffer-interna= l-p))) >>=20 >> Curiously, next-error-find-buffer only checks current-buffer as its >> 3rd choice. This function either needs to be changed to try the current >> buffer as its first choice, or it needs a clear comment explaining why. >>=20 >> It looks like this was changed by: >>=20 >> revision 1.655 >> date: 2004-09-01 13:05:59 -0400; author: jurta; state: Exp; lines: +4= 5 -45; >> * simple.el (next-error-find-buffer): Move the rule >> "if current buffer is a next-error capable buffer" after the >> rule "if next-error-last-buffer is set to a live buffer". >> Simplify to test all rules in one `or'. >> (next-error): Doc fix. >>=20 >> where it is not explained. Juri, do you remember what was the motivation >> for this change? > This change was based on the conclusion of the very long discussion start= ed > from http://lists.gnu.org/archive/html/emacs-devel/2004-05/msg00476.html > Any change in current rules may break test cases mentioned on that thread. Actually, that thread did not conclude that the current set of rules is The Right Way. It ignored my suggestion (which was to keep the `current-buffer' as the first rule, but to disable it if current-buffer was the last source buffer visited by next-error). Interestingly, I found out in the mean time that my suggestion has another advantage: not only it ignores the current-buffer less often but it also correctly ignores it in some cases where the current rules don't. To remind people of the context, C-x ` has two problems: 1 - if you have two projects, do C-x ` in the first, then do C-x ` in the second, and then come back to the first and do C-x ` again, you'd want this C-x ` to use the compilation buffer of the first project, not of the second one. So you'd want to sometimes ignore next-error-last-buffer. This is the reason why "next-error capable buffer in the current frame" currently takes precedence over next-error-last-buffer. 2 - if you do C-x ` on a compilation buffer and that jumps to a patch file, and then do C-x ` from that patch file's buffer, it should look for the next error in the compilation buffer rather than the next hunk in the patch file. Currently this is done by giving precedence to next-error-last-buffer over current-buffer (i.e. basically this always ignores current-buffer. In practice current-buffer is still often used because of the first rule "next-error capable buffer in current frame"). The way I use Emacs, I have one frame per buffer. So the first rule basically means that current-buffer is always selected, so for me problem number 2 is not corrected. My original suggestion to fix number 2 was to introduce a new variable next-error-last-source-buffer which is set to the last source buffer visited by next-error. Then C-x ` would ignore current-buffer (and obey next-error-last-buffer instead) if the current buffer is equal to next-error-last-source-buffer: in the example problem, the C-x ` that puts me in the patch file would set next-error-last-source-buffer to that patch file buffer so hitting C-x ` in that patch file buffer would correctly ignore the patch file buffer and use the compilation buffer instead. BTW, it looks like the `avoid-current' argument is *never* used. Any objection to the patch below? Stefan --- simple.el 28 jui 2007 16:22:16 -0400 1.859.2.3 +++ simple.el 02 ao=FB 2007 12:17:20 -0400=09 @@ -173,6 +173,9 @@ similar mode is started, or when it is used with \\[next-error] or \\[compile-goto-error].") =20 +(defvar next-error-last-source-buffer nil + "The most recent buffer to which `next-error' jumped.") + (defvar next-error-function nil "Function to use to find the next error in the current buffer. The function is called with 2 parameters: @@ -228,14 +231,33 @@ The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer that would normally be considered usable. If it returns nil, that buffer is rejected." + ;; FIXME: It looks like the `avoid-current' argument is never used. + (let ((minor-avoid-current + (or avoid-current + ;; When a C-x ` in an occur or compilation buffer jumps to + ;; a patch file, we want the next C-x ` to keep visiting the + ;; next errors or occurrences, rather than jump to the + ;; next hunk. + (eq (current-buffer) next-error-last-source-buffer)))) (or + ;; 0. If the current buffer is acceptable, choose it, unless it is the + ;; buffer to which the last next-error jumped. + (if (next-error-buffer-p (current-buffer) minor-avoid-current + extra-test-inclusive extra-test-exclusive) + (current-buffer)) ;; 1. If one window on the selected frame displays such buffer, return = it. + ;; This takes precedence to the next-error-last-buffer so as to + ;; try and address the situation where the user works on 2 projects + ;; within the same Emacs session, does a C-x ` on a compilation in= the + ;; first project, then C-x ` on an occur buffer in the second, then + ;; comes back to the first project and hits C-x ` expecting to jum= p to + ;; the next error of the first project's compilation. (let ((window-buffers (delete-dups (delq nil (mapcar (lambda (w) (if (next-error-buffer-p (window-buffer w) - avoid-current + minor-avoid-current extra-test-inclusive extra-test-exclus= ive) (window-buffer w))) (window-list)))))) @@ -246,7 +268,9 @@ (next-error-buffer-p next-error-last-buffer avoid-current extra-test-inclusive extra-test-exclusive= )) next-error-last-buffer) - ;; 3. If the current buffer is acceptable, choose it. + ;; 3. If the current buffer is acceptable, choose it. This is only + ;; useful if the current-buffer is the buffer to which the last + ;; next-error jumped (otherwise rule 0 applied already). (if (next-error-buffer-p (current-buffer) avoid-current extra-test-inclusive extra-test-exclusive) (current-buffer)) @@ -267,7 +291,7 @@ (message "This is the only buffer with error message locations") (current-buffer))) ;; 6. Give up. - (error "No buffers contain error message locations"))) + (error "No buffers contain error message locations")))) =20 (defun next-error (&optional arg reset) "Visit next `next-error' message and corresponding source code. @@ -301,18 +325,21 @@ \`compilation-error-regexp-alist' for customization ideas." (interactive "P") (if (consp arg) (setq reset t arg nil)) + ;; This `when' is unneeded because next-error-find-buffer never returns = nil. (when (setq next-error-last-buffer (next-error-find-buffer)) ;; we know here that next-error-function is a valid symbol we can func= all (with-current-buffer next-error-last-buffer (funcall next-error-function (prefix-numeric-value arg) reset) + (setq next-error-last-source-buffer (current-buffer)) (run-hooks 'next-error-hook)))) =20 (defun next-error-internal () "Visit the source code corresponding to the `next-error' message at poin= t." (setq next-error-last-buffer (current-buffer)) - ;; we know here that next-error-function is a valid symbol we can funcall - (with-current-buffer next-error-last-buffer + ;; We know here that next-error-function is a valid symbol we can funcal= l. + (save-current-buffer (funcall next-error-function 0 nil) + (setq next-error-last-source-buffer (current-buffer)) (run-hooks 'next-error-hook))) =20 (defalias 'goto-next-locus 'next-error)