Popup Minibuffer di Center
Inilah cara untuk melakukan persis apa yang Anda minta: tampilkan minibuffer di bagian tengah layar .
- Memiliki bingkai terpisah untuk minibuffer
- Posisikan di tengah
- Naikkan frame ini setiap kali minibuffer mendapatkan fokus.
Itu relatif mudah untuk dicapai, dan itulah yang akan Anda dapatkan dengan
oneonone.el
paket (seperti yang ditunjukkan oleh @Drew). Masalah dengan pendekatan ini, adalah bahwa minibuffer juga digunakan untuk pesan, jadi menyembunyikannya bukanlah sesuatu yang sangat nyaman. Tidak perlu khawatir! Saya datang dengan solusi lain.
- Miliki minibuffer kedua yang ditampilkan pada bingkai terpisah.
- Posisikan di tengah.
- Gunakan frame kedua untuk perintah interaktif, sedangkan minibuffer asli (pertama) digunakan untuk menggemakan pesan.
Pelaksanaan
Untuk mengimplementasikan ini, kita perlu membuat frame minibuffer di startup emacs.
(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))
"")
Kemudian kami tambalan read-from-minibuffer
untuk menggunakan minibuffer kedua ini, bukan minibuffer frame asli.
(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)
Ini mungkin tidak bekerja dengan benar-benar semuanya, tetapi bekerja pada segala sesuatu yang saya mencoba sejauh --- find-file
, ido-switch-buffer
,
eval-expression
. Jika Anda melakukan menemukan pengecualian apapun, Anda dapat menambal fungsi-fungsi ini atas dasar kasus per kasus dengan memanggil
use-popup-minibuffer
mereka.
Posisi Near Point
Untuk menempatkan frame minibuffer ini di dekat ketinggian titik, cukup tentukan sesuatu seperti fungsi berikut. Itu tidak sempurna (pada kenyataannya, itu mengerikan pada banyak kasus), tetapi ia melakukan pekerjaan yang layak untuk memperkirakan ketinggian titik.
(defun point-screen-height ()
(* (/ (face-attribute 'default :height) 10) 2
(- (line-number-at-pos (point))
(line-number-at-pos (window-start)))))