ivy弹出的框能不能固定在下方?

嗯,posframe确实可以,只是必须用gui版本了。

改 Emacs 源代码或许是更简单的方案,写死 echo area 的高度,这样就不用修改 ivy 了,任它关闭 minibuffer,但是空间还是留在那里。

好吧,可以尝试看看源码能不能改。

VSCode, Sublime 等现代化编辑器敲命令都是上方一个弹出窗口敲命令,敲完自动关闭。

嗯,在emacs里用类似效果的posframe也还好。

把这几行加到配置文件里试试, 我这里测试可以.

(setq resize-mini-windows nil)
(setq ivy-height 10)

(defun my-set-mini-window-height (&optional frame)
  (let ((mini-win (minibuffer-window frame)))
	(when mini-win
	  (window-resize mini-win ivy-height))))

(add-hook 'window-setup-hook 'my-set-mini-window-height)
(add-hook 'after-make-frame-functions 'my-set-mini-window-height)
1 个赞

这比改源码简单,直接用 hook 就把 echo area 钉住了。

在黑科技的路上永不回头。。。。。。

终端下也能用,太厉害了,是想要的效果,buffer也不会乱动了:grinning:,十分感谢!

不是「也」,而是 36# 楼这段代码只能终端下工作良好,GUI 下反而会有一点问题。

那两个 hook 都只在初始化过程中执行一次。但是在 GUI 启动之后,一旦窗口(桌面概念的窗口,即 Emacs 的 frame,而非 Emacs 概念的 widnow)大小改变,设定就失效了。

而终端下不存在 frame 大小改变的问题,任凭终端窗口大小怎么改变,都不会触发 frame 事件。


UPDATE:

@netjune 原代码的基础上我做了点修改,使 GUI 下不因 frame resize 而失效:

 (setq resize-mini-windows nil)
 (setq ivy-height 10)
 
 (defun my-set-mini-window-height (&optional frame)
   (let ((mini-win (minibuffer-window frame)))
-   (when mini-win
+   (when (and mini-win (< (window-size mini-win) ivy-height))
       (window-resize mini-win ivy-height))))

 (add-hook 'window-setup-hook 'my-set-mini-window-height)
 (add-hook 'after-make-frame-functions 'my-set-mini-window-height)
+(add-hook 'move-frame-functions 'my-set-mini-window-height)

UPDATE2:

终端下也是不完美的,改变终端 app 的高度,会使得 Emacs 已经设置的 echo area 高度失效。

其实终端下也会有点小问题,我用putty, superputty, mobaxterm三个试,改变高度后会失效,改变宽度反而不会失效。

试一试winum-mode?

是的,my-set-mini-window-height 这个方案是没错,主要是能找到 frame 改变之后的 hook / 函数,挂上去就可以了。

在官方文档Window-Hooks找到了窗口改变的hook,设置上后基本上稳了。@netjune

(add-hook 'window-size-change-functions 'my-set-mini-window-height)

如果用 window-size-change-functions,那么其它几个 hook 都可以去掉了。

确实是的。。

请问

一个frame可以有几个minibuffer

如果可以有多个 还是放在左侧比较省屏幕空间

没明白什么意思,一个frame好像只有一个minibuffer吧。

放左侧是什么样子?minibuffer显示为neotree那样的左侧形式?

严格来说 buffer(包括 minibuffer)是无形的,只不过把它放到 window 的矩形空间里展示。平时我们都不太注意区分 buffer 和 window,但也算不上什么大问题。

Emacs 把 frame 分割为两部分:edit area 和 echo area。

edit area 可以任意切割 window,而 echo area 只放一个 window,用来展示 minibuffer。所以我们说 minibuffer 等于 echo area 也不为过了。

由于 echo area 的特殊性,所以不可能存在多个。它的位置也是固定的,想要改只能去改 c 源码了。

1 个赞

对,这个hook效果更好