在最大化的Emacs框架上工作时,很难看到屏幕底部显示的minibuffer / echo区域的内容,但是当键入命令时,这也会导致失去对正在编辑的文本的关注–这相当可用性方面的问题
有没有办法在minibuffer处于活动状态时将当前minimacs缓冲区的minibuffer / echo区域移至正在编辑的文本上方,或者更好地捕获minibuffer的内容并将其显示在中心键入命令时当前缓冲区的大小?
在最大化的Emacs框架上工作时,很难看到屏幕底部显示的minibuffer / echo区域的内容,但是当键入命令时,这也会导致失去对正在编辑的文本的关注–这相当可用性方面的问题
有没有办法在minibuffer处于活动状态时将当前minimacs缓冲区的minibuffer / echo区域移至正在编辑的文本上方,或者更好地捕获minibuffer的内容并将其显示在中心键入命令时当前缓冲区的大小?
Answers:
这是一种完全按照您的要求执行的方法:在屏幕中央显示迷你缓冲区。
这是相对容易实现的,并且可以从oneonone.el
软件包中获得
(正如@Drew所指出的)。这种方法的问题在于,微型缓冲区也用于消息,因此将其隐藏起来不是很方便。不用担心!我想出了另一种解决方案。
为此,我们需要在emacs启动时创建minibuffer框架。
(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))
"")
然后,我们打补丁read-from-minibuffer
以使用第二个微型缓冲区,而不是原始帧的微型缓冲区。
(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)
这可能不是绝对的一切工作,但它的工作对我试过到目前为止一切--- find-file
,ido-switch-buffer
,
eval-expression
。如果你做发现任何异常,您可以通过调用上打补丁的情况下,逐个这些功能
use-popup-minibuffer
在他们身上。
要将这个微型缓冲区框架定位在点的高度附近,只需定义以下函数即可。它不是完美的(实际上,在很多情况下它是可怕的),但是在估计点高方面做得不错。
(defun point-screen-height ()
(* (/ (face-attribute 'default :height) 10) 2
(- (line-number-at-pos (point))
(line-number-at-pos (window-start)))))
(setf (symbol-function function) ...)
最好不要使用advice-add
(或较旧的ad-add-advice
),而不是弄乱您。
在屏幕中间显示迷你缓冲区很复杂。一个合理的选择(您可能会或可能不会觉得它更具可读性)是将其移至顶部。
您可以使用
变量中的minibuffer
frame参数
配置帧的微型缓冲区的位置(或存在)initial-frame-alist
。
将该参数设置为,nil
将配置框架没有小缓冲区,Emacs将自动为您创建一个单独的小缓冲区帧。您可以使用操作系统的窗口管理器来定位这两个框架,也可以从Emacs进行定位。
下面的代码片段说明了如何将微型缓冲区框架放置在顶部,而普通框架则位于其下方,但是您绝对必须更改数字以适应监视器的大小。
(setq initial-frame-alist
'((left . 1) (minibuffer . nil)
;; You'll need to adjust the following 3 numbers.
(top . 75) ; In pixels
(width . 127) ; In chars
(height . 31)))
(setq minibuffer-frame-alist
'((top . 1) (left . 1) (height . 2)
;; You'll need to adjust the following number.
(width . 127)))
调整此速度最快的方法是在窗口管理器中调整框架的大小,然后进行评估(frame-parameters)
以查看所拥有的参数值。
另一种可能性是将minibuffer
参数设置为窗口。不幸的是,我无法使它在同一框架的窗口中工作。
库oneonone.el
为您提供了开箱即用的功能。
只需将选项自定义1on1-minibuffer-frame-top/bottom
到独立微型缓冲区框架所需的位置即可。该值是从显示器的顶部(如果不是负数)或底部(如果是负数)起的像素数。例如,将值设置为显示高度除以2,以使其垂直居中。
如果您希望将其动态定位,例如在当前帧的垂直中心放置,则可以通过(a)保留1on1-minibuffer-frame-top/bottom
= nil
和(b)建议函数 1on1-set-minibuffer-frame-top/bottom
将该变量动态绑定到适当位置来实现。例如:
(defadvice 1on1-set-minibuffer-frame-top/bottom (around center activate)
(let ((1on1-minibuffer-frame-top/bottom (my-dynamic-position ...)))
ad-do-it))
(定义函数my-dynamic-position
以根据所需的任何条件(当前的窗口/帧大小和位置,月相...)来计算所需的位置。