Popup Minibuffer tại Trung tâm
Đây là một cách để làm chính xác những gì bạn yêu cầu: hiển thị bộ thu nhỏ ở giữa màn hình .
- Có khung riêng cho xe buýt nhỏ
- Đặt nó ở trung tâm
- Nâng khung hình này bất cứ khi nào xe buýt nhỏ đạt được trọng tâm.
Điều đó tương đối dễ dàng để đạt được và là những gì bạn sẽ nhận được với
oneonone.el
gói (như @Drew chỉ ra). Vấn đề với cách tiếp cận này, đó là xe buýt nhỏ cũng được sử dụng cho các tin nhắn, vì vậy việc giấu nó không phải là điều gì đó rất thuận tiện. Đừng lo lắng! Tôi đã đưa ra một giải pháp khác.
- Có một xe buýt nhỏ thứ hai được hiển thị trên một khung riêng biệt.
- Đặt nó ở trung tâm.
- Sử dụng khung thứ hai cho các lệnh tương tác, trong khi bộ thu nhỏ ban đầu (thứ nhất) được sử dụng để lặp lại tin nhắn.
Thực hiện
Để thực hiện điều này, chúng ta cần tạo khung mini cho bộ khởi động 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))
"")
Sau đó, chúng tôi vá read-from-minibuffer
để sử dụng bộ thu nhỏ thứ hai này, thay vì bộ thu nhỏ của khung ban đầu.
(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)
Điều này có thể không làm việc với tất cả mọi thứ hoàn toàn, nhưng nó làm việc trên tất cả mọi thứ tôi đã cố gắng cho đến nay --- find-file
, ido-switch-buffer
,
eval-expression
. Nếu bạn làm tìm thấy bất kỳ trường hợp ngoại lệ, bạn có thể vá các chức năng trên cơ sở từng trường hợp cụ thể bằng cách gọi
use-popup-minibuffer
vào chúng.
Vị trí gần điểm
Để định vị khung hình xe buýt nhỏ này gần độ cao của điểm, chỉ cần xác định một cái gì đó giống như chức năng sau đây. Nó không hoàn hảo (trên thực tế, rất tệ trong nhiều trường hợp), nhưng nó làm rất tốt việc ước tính chiều cao điểm.
(defun point-screen-height ()
(* (/ (face-attribute 'default :height) 10) 2
(- (line-number-at-pos (point))
(line-number-at-pos (window-start)))))