Subject: bug#13594: Planning Emacs-24.4

From: Leo Liu <[email-masked]>
Date: Mon, 18 Nov 2013 23:48:07 +0800

On 2013-11-18 23:20 +0800, martin rudalics wrote:
> I thought you intially wanted to fix the problem that a caller cannot
> handle a nil return value from `display-buffer'.  But Stefan says that
> it's not necessary to do that and I agree with him.  So your fix is OK
> but I'd just make the last line of `display-buffer' something like
>
> (when (windowp window) window)
>
> and you don't have to talk about a return value of t.  Returning t sounds
> not very intuitive when a function fails to accomplish something.

OK, thank you for the quick response. I have re-worked the patch based
on Stefan's and your comments. Please review it. Thanks.

Leo

=== modified file 'lisp/progmodes/compile.el'
--- lisp/progmodes/compile.el	2013-10-23 16:25:56 +0000
+++ lisp/progmodes/compile.el	2013-11-18 15:43:29 +0000
@@ -1632,7 +1632,7 @@
       (set-buffer-modified-p nil))
     ;; Pop up the compilation buffer.
     ;; http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01638.html
-    (setq outwin (display-buffer outbuf))
+    (setq outwin (display-buffer outbuf '(nil (non-window-ok . t))))
     (with-current-buffer outbuf
       (let ((process-environment
 	     (append
@@ -1654,7 +1654,7 @@
 	     (list command mode name-function highlight-regexp))
 	(set (make-local-variable 'revert-buffer-function)
 	     'compilation-revert-buffer)
-	(set-window-start outwin (point-min))
+	(and outwin (set-window-start outwin (point-min)))
 
 	;; Position point as the user will see it.
 	(let ((desired-visible-point
@@ -1663,15 +1663,15 @@
 		   (point-max)
 		 ;; Normally put it at the top.
 		 (point-min))))
-	  (if (eq outwin (selected-window))
-	      (goto-char desired-visible-point)
+	  (goto-char desired-visible-point)
+	  (when (and outwin (not (eq outwin (selected-window))))
 	    (set-window-point outwin desired-visible-point)))
 
 	;; The setup function is called before compilation-set-window-height
 	;; so it can set the compilation-window-height buffer locally.
 	(if compilation-process-setup-function
 	    (funcall compilation-process-setup-function))
-	(compilation-set-window-height outwin)
+	(and outwin (compilation-set-window-height outwin))
 	;; Start the compilation.
 	(if (fboundp 'start-process)
 	    (let ((proc
@@ -2513,14 +2513,16 @@
                 ;; the error location if the two buffers are in two
                 ;; different frames.  So don't do it if it's not necessary.
                 pre-existing
-	      (display-buffer (marker-buffer msg))))
+	      (display-buffer (marker-buffer msg) '(nil (non-window-ok . t)))))
 	 (highlight-regexp (with-current-buffer (marker-buffer msg)
 			     ;; also do this while we change buffer
-			     (compilation-set-window w msg)
+			     (goto-char (marker-position msg))
+			     (and w (compilation-set-window w msg))
 			     compilation-highlight-regexp)))
     ;; Ideally, the window-size should be passed to `display-buffer'
     ;; so it's only used when creating a new window.
-    (unless pre-existing (compilation-set-window-height w))
+    (when (and (not pre-existing) w)
+      (compilation-set-window-height w))
 
     (if from-compilation-buffer
         ;; If the compilation buffer window was selected,
@@ -2631,9 +2633,12 @@
     (while (null buffer)    ;Repeat until the user selects an existing file.
       ;; The file doesn't exist.  Ask the user where to find it.
       (save-excursion            ;This save-excursion is probably not right.
-        (let ((pop-up-windows t))
-          (compilation-set-window (display-buffer (marker-buffer marker))
-                                  marker)
+        (let ((w (let ((pop-up-windows t))
+		   (display-buffer (marker-buffer marker)
+				   '(nil (non-window-ok . t))))))
+          (with-current-buffer (marker-buffer marker)
+	    (goto-char marker)
+	    (and w (compilation-set-window w marker)))
           (let* ((name (read-file-name
                         (format "Find this %s in (default %s): "
                                 compilation-error filename)

=== modified file 'lisp/window.el'
--- lisp/window.el	2013-11-12 07:25:14 +0000
+++ lisp/window.el	2013-11-18 15:43:29 +0000
@@ -5355,7 +5355,10 @@
  ACTION is a cons cell (FUNCTION . ALIST), where FUNCTION is a
   function or a list of functions.  Each such function should
   accept two arguments: a buffer to display and an alist of the
-  same form as ALIST.  See `display-buffer' for details.
+  same form as ALIST.  If (non-window-ok . t) is in ALIST, the
+  caller is prepared to handle non-window value and FUNCTION can
+  safely return non-window value to suppress displaying the
+  window.  See `display-buffer' for details.
 
 `display-buffer' scans this alist until it either finds a
 matching regular expression or the function specified by a
@@ -5439,9 +5442,12 @@
 ALIST is an arbitrary association list (alist).
 
 Each such FUNCTION should accept two arguments: the buffer to
-display and an alist.  Based on those arguments, it should either
-display the buffer and return the window, or return nil if unable
-to display the buffer.
+display and an alist.  Based on those arguments, it should
+display the buffer and return the window.  It may return nil if
+unable to display the buffer (which is rare and most callers
+don't check this value).  If the caller is prepared to handle
+non-window value it should pass (non-window-ok . t) as an element
+of the ALIST.
 
 The `display-buffer' function builds a function list and an alist
 by combining the functions and alists specified in
@@ -5542,7 +5548,7 @@
 	(while (and functions (not window))
 	  (setq window (funcall (car functions) buffer alist)
 	  	functions (cdr functions)))
-	window))))
+	(and (windowp window) window)))))
 
 (defun display-buffer-other-frame (buffer)
   "Display buffer BUFFER preferably in another frame.