From: Juri Linkov Date: Tue, 8 Jul 2014 08:02:50 +0000 (+0300) Subject: * lisp/window.el (with-displayed-buffer-window): New macro. X-Git-Tag: emacs-25.0.90~2636^2~65 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f0f70ec0bc55e452ea29b5cf3f532740966b0192;p=emacs.git * lisp/window.el (with-displayed-buffer-window): New macro. (with-temp-buffer-window, with-current-buffer-window): Use `macroexp-let2' to evaluate and bind variables in the same order as macro arguments. (display-buffer--action-function-custom-type): Add `display-buffer-below-selected' and `display-buffer-at-bottom'. * lisp/minibuffer.el (minibuffer-completion-help): Replace `with-output-to-temp-buffer' with `with-displayed-buffer-window' with actions that display *Completions* at-bottom when called from the minibuffer, or below-selected in a normal buffer. Associate `window-height' with `fit-window-to-buffer'. Let-bind `pop-up-windows' to nil. * lisp/dired.el (dired-mark-pop-up): Use `with-displayed-buffer-window' instead of `with-current-buffer-window'. Fixes: debbugs:17809 --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a8b5f935d9a..cc864810c8c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,22 @@ +2014-07-08 Juri Linkov + + * window.el (with-displayed-buffer-window): New macro. + (with-temp-buffer-window, with-current-buffer-window): + Use `macroexp-let2' to evaluate and bind variables + in the same order as macro arguments. + (display-buffer--action-function-custom-type): Add + `display-buffer-below-selected' and `display-buffer-at-bottom'. + + * minibuffer.el (minibuffer-completion-help): Replace + `with-output-to-temp-buffer' with `with-displayed-buffer-window' + with actions that display *Completions* at-bottom when called + from the minibuffer, or below-selected in a normal buffer. + Associate `window-height' with `fit-window-to-buffer'. + Let-bind `pop-up-windows' to nil. + + * dired.el (dired-mark-pop-up): Use `with-displayed-buffer-window' + instead of `with-current-buffer-window'. (Bug#17809) + 2014-07-07 Luke Lee * progmodes/hideif.el (hide-ifdef-env): Change to global. diff --git a/lisp/dired.el b/lisp/dired.el index a241fb3b339..25b70219c7d 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3103,20 +3103,20 @@ argument or confirmation)." ;; 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 - buffer - (cons 'display-buffer-below-selected - '((window-height . fit-window-to-buffer))) - #'(lambda (window _value) - (with-selected-window window - (unwind-protect - (apply function args) - (when (window-live-p window) - (quit-restore-window window 'kill))))) - ;; 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-displayed-buffer-window + buffer + (cons 'display-buffer-below-selected + '((window-height . fit-window-to-buffer))) + #'(lambda (window _value) + (with-selected-window window + (unwind-protect + (apply function args) + (when (window-live-p window) + (quit-restore-window window 'kill))))) + ;; 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) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index e7e08342b47..f8b77cddbc5 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1794,8 +1794,29 @@ variables.") ;; 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)) diff --git a/lisp/window.el b/lisp/window.el index 28dd6a8ab26..e1c79659773 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -185,16 +185,19 @@ argument replaces this)." (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) - (setq ,value (progn ,@body)) - (with-current-buffer ,buffer - (setq ,window (temp-buffer-window-show ,buffer ,action))) - - (if (functionp ,quit-function) - (funcall ,quit-function ,window ,value) - ,value)))) + (macroexp-let2 nil vbuffer-or-name buffer-or-name + (macroexp-let2 nil vaction action + (macroexp-let2 nil vquit-function quit-function + `(let* ((,buffer (temp-buffer-window-setup ,vbuffer-or-name)) + (standard-output ,buffer) + ,window ,value) + (setq ,value (progn ,@body)) + (with-current-buffer ,buffer + (setq ,window (temp-buffer-window-show ,buffer ,vaction))) + + (if (functionp ,vquit-function) + (funcall ,vquit-function ,window ,value) + ,value))))))) (defmacro with-current-buffer-window (buffer-or-name action quit-function &rest body) "Evaluate BODY with a buffer BUFFER-OR-NAME current and show that buffer. @@ -205,16 +208,50 @@ BODY." (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 ,value (progn ,@body)) - (setq ,window (temp-buffer-window-show ,buffer ,action))) + (macroexp-let2 nil vbuffer-or-name buffer-or-name + (macroexp-let2 nil vaction action + (macroexp-let2 nil vquit-function quit-function + `(let* ((,buffer (temp-buffer-window-setup ,vbuffer-or-name)) + (standard-output ,buffer) + ,window ,value) + (with-current-buffer ,buffer + (setq ,value (progn ,@body)) + (setq ,window (temp-buffer-window-show ,buffer ,vaction))) + + (if (functionp ,vquit-function) + (funcall ,vquit-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"))) + (macroexp-let2 nil vbuffer-or-name buffer-or-name + (macroexp-let2 nil vaction action + (macroexp-let2 nil vquit-function quit-function + `(let* ((,buffer (temp-buffer-window-setup ,vbuffer-or-name)) + (standard-output ,buffer) + ,window ,value) + (with-current-buffer ,buffer + (setq ,window (temp-buffer-window-show ,buffer ,vaction))) + + (let ((inhibit-read-only t) + (inhibit-modification-hooks t)) + (setq ,value (progn ,@body))) + + (set-window-point ,window (point-min)) + + (when (functionp (cdr (assq 'window-height (cdr ,vaction)))) + (ignore-errors + (funcall (cdr (assq 'window-height (cdr ,vaction))) ,window))) - (if (functionp ,quit-function) - (funcall ,quit-function ,window ,value) - ,value)))) + (if (functionp ,vquit-function) + (funcall ,vquit-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 @@ -5980,6 +6017,8 @@ The actual non-nil value of this variable will be copied to the (const display-buffer-pop-up-window) (const display-buffer-same-window) (const display-buffer-pop-up-frame) + (const display-buffer-below-selected) + (const display-buffer-at-bottom) (const display-buffer-in-previous-window) (const display-buffer-use-some-window) (function :tag "Other function"))