用helm也可以啊,helm怎么可以固定窗口不关闭?
主要是想眼睛有个固定的焦点输入命令,并且整个buffer不会乱动。
因为一在buffer的最后一页时counsel-M-x,helm-M-x都会把整个buffer往上顶一下,体验很不好,还以为buffer内容被改了,就像这样:
所以想要固定ivy或helm不隐藏,切换窗口我想大不了就用window left, window right的方式也还好吧。
用helm也可以啊,helm怎么可以固定窗口不关闭?
主要是想眼睛有个固定的焦点输入命令,并且整个buffer不会乱动。
因为一在buffer的最后一页时counsel-M-x,helm-M-x都会把整个buffer往上顶一下,体验很不好,还以为buffer内容被改了,就像这样:
所以想要固定ivy或helm不隐藏,切换窗口我想大不了就用window left, window right的方式也还好吧。
先抛开窗口切换问题,只关注如何固定窗口。
ivy 和 helm 都需要关闭列表窗口,才能进行下一步。
对于 ivy 来说,你需要修改所有包含 (minibuffer-keyboard-quit)
和 (exit-minibuffer)
语句的函数,比如:(我只改了这一个函数,仅阻止回车关闭 minibuffer)
(define-advice ivy--done (:override (text) stop-exit-miniubffer)
"Insert TEXT and exit minibuffer."
(insert
(setf (ivy-state-current ivy-last)
(if (and ivy--directory
(not (eq (ivy-state-history ivy-last) 'grep-files-history)))
(expand-file-name text ivy--directory)
text)))
(setq ivy-exit 'done)
;;---
;;(exit-minibuffer)
)
修改之后带来的问题是,action 没有继续,这是首先必须要想办法解决的,后面还有多少问题未知。
另一个不固定窗口,但是避免编辑内容 buffer 网上的方法是,让 ivy / helm 弹出浮动窗口。但是这个方法只有当光标位置不会被挡住的情况下才有有效。
一旦光标位置会被浮动窗口挡住,必须往上顶,才能让编辑位置继续保持可见。所以在多窗口(特别是上下切割)的时候,还是会经常体验不太好。
试了下确实回车时不会关闭,功能得不到执行,而且C-g还是会关闭minibuffer。
如果用helm来弄有什么思路吗,毕竟helm是出来独立的window buffer。
可以把minibuf窗口高度设置大一点,比如10行,然后,ivy里也设置一下窗口高度,应该就可以了
说实话,我不明白这样做的意义何在。一直有一个窗口在那儿显示不碍事吗?让我想起张信哲的那首歌:是我让你自由过了火
我也很烦窗口内容变来变去,不过helm好像不会让上面窗口内容往上滚,ivy也许也可以设置不让它往上顶
VS之类的IDE下方不都是有个小窗口吗,毕竟用emacs会经常敲命令。
popup-menu*
helm也会往上顶,只要是光标在buffer的最后一页就会。
找了下,好像没有能设置minibuffer高度的变量或函数?
你这个情况直接用posframe是最好的吧
嗯,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)
这比改源码简单,直接用 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 高度失效。