GNU bug report logs - #17809
24.4.50; Completions display

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> jurta.org>

Date: Thu, 19 Jun 2014 07:12:03 UTC

Severity: wishlist

Tags: patch

Merged with 12618

Found in version 24.2.50

Fixed in version 24.4.50

Done: Juri Linkov <juri <at> jurta.org>

Bug is archived. No further changes may be made.

Full log


Message #49 received at 17809 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 17809 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#17809: 24.4.50; Completions display
Date: Sat, 05 Jul 2014 02:40:31 +0300
>> Maybe it would be a good thing to add a new action parameter to
>> `display-buffer' that would be like the existing `quit-function'
>> in `with-current-buffer-window', and will call its body between
>> displaying the buffer and applying final actions alists like
>> (window-height . fit-window-to-buffer)
>
> `display-buffer' has no body and hardly ever will get one.

I agree that there is no way to add body to `display-buffer'.

So the cleanest solution would be to add a new macro
`with-displayed-buffer-window' that is like
`with-current-buffer-window' and `with-temp-buffer-window',
but will run its body in the displayed window.

I've tested it with different configurations, and it produces
nice results when used in the minibuffer, at point, in
horizontally split windows, in Dired *Marked Files*,
with pop-up-frames=t, etc.

=== modified file 'lisp/window.el'
--- lisp/window.el	2014-06-18 07:57:27 +0000
+++ lisp/window.el	2014-07-04 23:30:54 +0000
@@ -216,6 +216,35 @@ (defmacro with-current-buffer-window (bu
 	   (funcall ,quit-function ,window ,value)
 	 ,value))))
 
+(defmacro with-displayed-buffer-window (buffer-or-name action quit-function &rest body)
+  "Show a buffer BUFFER-OR-NAME and evaluate BODY in that buffer.
+This construct is like `with-current-buffer-window' but unlike that
+displays the buffer specified by BUFFER-OR-NAME before running BODY."
+  (declare (debug t))
+  (let ((buffer (make-symbol "buffer"))
+	(window (make-symbol "window"))
+	(value (make-symbol "value")))
+    `(let* ((,buffer (temp-buffer-window-setup ,buffer-or-name))
+	    (standard-output ,buffer)
+	    ,window ,value)
+       (with-current-buffer ,buffer
+	 (setq ,window (temp-buffer-window-show ,buffer ,action)))
+
+       (let ((inhibit-read-only t)
+	     (inhibit-modification-hooks t))
+	 (setq ,value (progn ,@body)))
+
+       (with-selected-window ,window
+	 (goto-char (point-min)))
+
+       (when (functionp (cdr (assq 'window-height (cdr ,action))))
+	 (ignore-errors
+	   (funcall (cdr (assq 'window-height (cdr ,action))) ,window)))
+
+       (if (functionp ,quit-function)
+	   (funcall ,quit-function ,window ,value)
+	 ,value))))
+
 ;; The following two functions are like `window-next-sibling' and
 ;; `window-prev-sibling' but the WINDOW argument is _not_ optional (so
 ;; they don't substitute the selected window for nil), and they return

=== modified file 'lisp/minibuffer.el'
--- lisp/minibuffer.el	2014-06-25 10:36:51 +0000
+++ lisp/minibuffer.el	2014-07-04 23:28:38 +0000
@@ -1794,8 +1794,29 @@ (defun minibuffer-completion-help (&opti
              ;; window, mark it as softly-dedicated, so bury-buffer in
              ;; minibuffer-hide-completions will know whether to
              ;; delete the window or not.
-             (display-buffer-mark-dedicated 'soft))
-        (with-output-to-temp-buffer "*Completions*"
+             (display-buffer-mark-dedicated 'soft)
+             ;; Disable `pop-up-windows' temporarily to allow
+             ;; `display-buffer--maybe-pop-up-frame-or-window'
+             ;; in the display actions below to pop up a frame
+             ;; if `pop-up-frames' is non-nil, but not to pop up a window.
+             (pop-up-windows nil))
+        (with-displayed-buffer-window
+	 "*Completions*"
+	 ;; This is a copy of `display-buffer-fallback-action'
+	 ;; where `display-buffer-use-some-window' is replaced
+	 ;; with `display-buffer-at-bottom'.
+	 `((display-buffer--maybe-same-window
+	    display-buffer-reuse-window
+	    display-buffer--maybe-pop-up-frame-or-window
+	    ;; Use `display-buffer-below-selected' for inline completions,
+	    ;; but not in the minibuffer (e.g. in `eval-expression')
+	    ;; for which `display-buffer-at-bottom' is used.
+	    ,(if (and completion-in-region-mode-predicate
+		      (not (minibuffer-selected-window)))
+		 'display-buffer-below-selected
+	       'display-buffer-at-bottom))
+	   (window-height . fit-window-to-buffer))
+	 nil
           ;; Remove the base-size tail because `sort' requires a properly
           ;; nil-terminated list.
           (when last (setcdr last nil))

=== modified file 'lisp/dired.el'
--- lisp/dired.el	2014-06-21 19:45:59 +0000
+++ lisp/dired.el	2014-07-04 23:30:52 +0000
@@ -3103,8 +3103,7 @@ (defun dired-mark-pop-up (buffer-or-name
 	  ;; Mark *Marked Files* window as softly-dedicated, to prevent
 	  ;; other buffers e.g. *Completions* from reusing it (bug#17554).
 	  (display-buffer-mark-dedicated 'soft))
-      (with-current-buffer buffer
-	(with-current-buffer-window
+      (with-displayed-buffer-window
 	 buffer
 	 (cons 'display-buffer-below-selected
 	       '((window-height . fit-window-to-buffer)))
@@ -3117,6 +3116,7 @@ (defun dired-mark-pop-up (buffer-or-name
 	 ;; Handle (t FILE) just like (FILE), here.  That value is
 	 ;; used (only in some cases), to mean just one file that was
 	 ;; marked, rather than the current line file.
+       (with-current-buffer buffer
 	 (dired-format-columns-of-files
 	  (if (eq (car files) t) (cdr files) files))
 	 (remove-text-properties (point-min) (point-max)





This bug report was last modified 10 years and 230 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.