非常有趣的一个效果

实现代码:
(defvar endless/popup-frame-parameters
'((name . "MINIBUFFER")
(minibuffer . only)
(height . 10)
(left . 400)
;; Ajust this one to your preference.
(top . 300))
"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))
"")
(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)
来自于 How to display the content of minibuffer in the middle of the emacs frame? - Emacs Stack Exchange
目前实用价值还有限,因为没办法让 helm 从中间弹出来。不知道有没有 helm-ag 的替代品
4 个赞
我对你的 gif 的开头的 “amazing graphics goes on…” 比较感兴趣,怎么弄的?
C-x o 不是切换 Window 么,,工作正常
好像是比较经典的一个梗。Bing
/Google
搜emacs butterfly
第一条就是出处。(当然你多半已经搜过了。。)
GVim
上的 fzf
也是弹出第二个frame不过是借用 XTerm
之类的终端
如果把这个butterfly函数改一下,然后在一条单独的线程中运行,或许可以作为不错的开机动画
Kinney
#9
可以直接用ivy-posframe或helm-posframe,很方便调整minibuffer显示位置
1 个赞
做了下修改,能做到:
- 手动关闭弹窗后不出现“Debugger entered–Lisp error: (wrong-type-argument frame-live-p #<dead frame MINIBUFFER 1c80e7e8>)”问题
- 支持“recursive-edit”
- 根据当前窗口来适当居中所弹出的窗口
(when (display-graphic-p)
(eval
`(defun earned::read-from-minibuffer (oldfun &rest rest)
"让 minibuffer 显示在屏幕中间 - Emacs-general - Emacs China: https://emacs-china.org/t/topic/890"
(let ((select (selected-frame))
(frame
(make-frame
`((name . "*Minibuffer*")
(minibuffer . only)
,(when (boundp (quote ivy-height))
(cons (quote height) ivy-height))
(width . ,(max (/ (- (frame-inner-width)
(* 20 (frame-char-width)))
(frame-char-width))
40))
(left . ,(+ (eval (alist-get (quote left)
(frame-parameters)))
(* (frame-char-width)
10)))
(top . ,(+ (eval
(alist-get (quote top)
(frame-parameters)))
(/ (frame-inner-height)
3)))))))
(make-frame-visible frame)
(select-frame-set-input-focus frame (quote norecord))
(unwind-protect
(apply oldfun rest)
(select-frame-set-input-focus select)
(delete-frame frame))))))
(dolist (symbol
(quote
(read-from-minibuffer
read-string)))
(when (functionp (function earned::read-from-minibuffer))
(advice-add symbol :around (function earned::read-from-minibuffer))))
现在也在用 ivy-posframe,效果完全满足期望
ivy-posframe
肯定满足需求了,而且比单独的 frame 要快速和好看些。不过用起来都有所卡顿,不如原生 minibuffer 流畅,用了一段时间还是放弃了。懒猫最新的 snails 也是放在中间,只是功能比较单一,只能搜索,很多功能是没有的。
xiyang
#14
我之前重新整理了一下,写了一个类似的完整的package
让minibuffer显示位置可选屏幕或window中间,上下左右角,有兴趣的同道可以试试
有点意思,有效果图之类的参考下吗?感觉实现跟 snails 一样,都是用 frame 的?老兄考虑过上 mepla 吗?
有使用说明吗?可以单独一个完整的package发出来呀
xiyang
#17

确实是用frame实现的,之前写这个的目的好像是因为ivy-posframe
无法隐藏当前minibuffer和光标无法跟随,不过不会上mepla,我用过几次,感觉还是有些不太习惯,又换回去了
xiyang
#18
我创建了一个单独的仓库,使用上很简单,load-file
然后激活maple-minibuffer-mode
即可
用起来确实还不如原生的 minibuffer,感觉卡卡的、怪怪的。
感谢大神!赞叹大神!试了下感觉比ivy-posframe可靠。速度也很快。不过我遇到了个小问题是遇到recursive edit的时候frame的位置会跑掉。不知道有没有办法修复?GIF 如下:

具体重现步骤:
- C-x C-f (counsel-find-file)
- 直接在minibuffer存在的时候按下M-x (counsel-M-x)
结果原本被我设置在中间的minibuffer就突然跑到左上角了,不知道有没有办法修复?感谢。