Popup Minibuffer in der Mitte
So können Sie genau das tun, was Sie gefragt haben: Zeigen Sie den Minipuffer in der Mitte des Bildschirms an .
- Einen separaten Rahmen für den Minipuffer haben
- Positionieren Sie es in der Mitte
- Erhöhen Sie diesen Frame, wenn der Minipuffer den Fokus erhält.
Das ist relativ einfach zu erreichen und wird mit dem
oneonone.el
Paket geliefert (wie @Drew hervorhebt). Das Problem bei diesem Ansatz ist, dass der Minipuffer auch für Nachrichten verwendet wird, so dass es nicht sehr praktisch ist, ihn versteckt zu halten. Keine Sorgen machen! Ich habe eine andere Lösung gefunden.
- Lassen Sie einen zweiten Minipuffer in einem separaten Frame anzeigen.
- Positionieren Sie es in der Mitte.
- Verwenden Sie den zweiten Frame für interaktive Befehle, während der ursprüngliche (erste) Minipuffer zum Echo von Nachrichten verwendet wird.
Implementierung
Um dies zu implementieren, müssen wir den Minibuffer-Frame beim Start von emacs erstellen.
(defvar endless/popup-frame-parameters
'((name . "MINIBUFFER")
(minibuffer . only)
(height . 1)
;; Ajust this one to your preference.
(top . 200))
"Parameters for the minibuffer popup frame.")
(defvar endless/minibuffer-frame
(let ((mf (make-frame endless/popup-frame-parameters)))
(iconify-frame mf) mf)
"Frame holding the extra minibuffer.")
(defvar endless/minibuffer-window
(car (window-list endless/minibuffer-frame t))
"")
Dann patchen wir read-from-minibuffer
, um diesen zweiten Minibuffer anstelle des Minibuffers des ursprünglichen Frames zu verwenden.
(defmacro with-popup-minibuffer (&rest body)
"Execute BODY using a popup minibuffer."
(let ((frame-symbol (make-symbol "selected-frame")))
`(let* ((,frame-symbol (selected-frame)))
(unwind-protect
(progn
(make-frame-visible endless/minibuffer-frame)
(when (fboundp 'point-screen-height)
(set-frame-parameter
endless/minibuffer-frame
'top (point-screen-height)))
(select-frame-set-input-focus endless/minibuffer-frame 'norecord)
,@body)
(select-frame-set-input-focus ,frame-symbol)))))
(defun use-popup-minibuffer (function)
"Rebind FUNCTION so that it uses a popup minibuffer."
(let* ((back-symb (intern (format "endless/backup-%s" function)))
(func-symb (intern (format "endless/%s-with-popup-minibuffer"
function)))
(defs `(progn
(defvar ,back-symb (symbol-function ',function))
(defun ,func-symb (&rest rest)
,(format "Call `%s' with a poupup minibuffer." function)
,@(list (interactive-form function))
(with-popup-minibuffer
(apply ,back-symb rest))))))
(message "%s" defs)
(when (and (boundp back-symb) (eval back-symb))
(error "`%s' already defined! Can't override twice" back-symb))
(eval defs)
(setf (symbol-function function) func-symb)))
;;; Try at own risk.
(use-popup-minibuffer 'read-from-minibuffer)
;;; This will revert the effect.
;; (setf (symbol-function #'read-from-minibuffer) endless/backup-read-from-minibuffer)
;; (setq endless/backup-read-from-minibuffer nil)
Dies könnte nicht mit absolut alles funktioniert, aber es funktionierte auf alles , was ich bisher versucht --- find-file
, ido-switch-buffer
,
eval-expression
. Wenn Sie tun , alle Ausnahmen finden, können Sie diese Funktionen auf einer Fall-zu-Fall - Basis Patch durch den Aufruf
use-popup-minibuffer
auf sich.
Position in der Nähe des Punktes
Um diesen Minipufferrahmen in der Nähe der Höhe des Punktes zu positionieren, definieren Sie einfach so etwas wie die folgende Funktion. Es ist nicht perfekt (in der Tat ist es in vielen Fällen schrecklich), aber es leistet gute Arbeit bei der Schätzung der Punkthöhe.
(defun point-screen-height ()
(* (/ (face-attribute 'default :height) 10) 2
(- (line-number-at-pos (point))
(line-number-at-pos (window-start)))))