你没有理解这个包的工作方式,你一直在minibuffer中输入,posframe只是把minibuffer中的内容显示出来,它不做输入处理
你看到的minibuffer中的光标其实是一个带颜色的空格,假的
我的也有这个问题,激活 vertico-posframe
之后,minibuffer 左下角还有个小光标,如果能去掉这个小光标应该就能解决这个问题了。
这个posframe是不支持的,想实现需要mini-frame之类的包。对于两个地方显示不一致的问题,我会想想怎么处理,应该有办法
二呆大佬,posframe设置min-width为0使其自适应内容宽度,但配合marginalia使用时,会出现这个问题:首次激活vertico-posframe,宽度为图一,C-n 到最后一个candidate时宽度为图二。第二次之后激活vertico-posframe宽度都默认保持为图二了(即保持为最大的宽度),不能再缩小为图一。
解决办法,用(posframe-delete-all):
(defun vertico-posframe--hide ()
"Hide vertico buffer."
(when (posframe-workable-p)
(posframe-delete-all)))
您看看要不要改一下?另外,激活vertico-posframe后minibuffer还有个光标一闪一闪的,这个可以隐藏的吗?
试试新的代码吧,minibuffer 遮挡的相当严实
这个不建议这么设置,因为如果输入错误,导致没有选项,posframe 宽度会急剧缩小,闪瞎眼
竟然用了一块白板遮住了minibuffer 但是会遮盖到部分mode-line。非全屏化的情况下,移动emacs之后,这块白板还停留在原地……可不可以把minibuffer的光标、promopt、输入内容的前景色设置为emacs背景色?在vertico-posframe里再设置回原来的颜色。这样也能起到隐藏的作用,但是不知道会不会影响awesome-tray这样的mode-line。ivy-posframe就很稳啊,它是这么处理这类问题的?
确实,我设置为比较小的非零值,表现挺好的了。谢谢大佬!
另外,与meow-mode(normal模式,光标样式为box)共用时,会导致vertico-posframe残留光标(c那里),需要输入3个以上字符才能消失:(下图的vertico-posframe是昨天下午新commit前的版本)
好像在 selectrum + mini-frame + posframe 方案里,可以做到mini-frame作为输入框,posframe作为candidates显示框,两者是分离的。我试试能不能实现这个效果:(感觉vertico-posframe不够ivy-posframe稳,试试曲线救国~)
我这边没有这个问题,可能是你用的 emacs child-frame 实现有问题。
ivy-posframe 说白了,也是用个白白遮挡,只不过它的白板使用 overlay 机制
我发现 vertico-posframe 的实现方式细节处理特别麻烦,不知道 mini-frame 的实现方式稳定性如何。
selectrum + mini-frame + posframe 方案,折腾一番,水平有限,只能做到下图这样的,离company-mode/ company-posframe还差一些。(注:模拟成company是最终目的。)
1、灰色为输入框,由mini-frame提供。不足之处:mini-frame的miniuffer-prompt不知道怎么去掉了,这两个函数好像是可以编辑输入框的格式的,自己瞎搞没效果;其宽度设置方式(width . 0.3)
与posframe的 :width
不同,不知道怎么弄成一样宽。
2、绿色为结果框,由posframe提供。不足之处:用 company-posframe-poshandler
作为selectrum + posframe
的poshandler,会出错:Error in post-command-hook (selectrum--update): (wrong-type-argument number-or-marker-p nil)
这个方案的配置其实就是 Additional Configuration · radian-software/selectrum Wiki · GitHub + Additional Configuration · radian-software/selectrum Wiki · GitHub 叠加起来恰好实现了“输入框和结果框分离”,后面调好两者child-frame的样式和弹出位置即可:
稳定性应该没问题。
看了看mini-frame的代码,它是通过read-frome-minibuffer
来获取minibuffer的内容,效果很彻底,连C-x r t
这样的提示都获取到。
另外再通过“make-fame”来生成child-frame,child-frame显示的过程比较流畅,像是从poshandler这里往下拉开的。而posframe会有一个对齐的过程,例如:posframe-poshandler-p0p0-to-p0p1
会看得到child-frame先在p0p0
生成,再对齐到p0p1
。这个过程虽然一闪而过,但肉眼也能看得出。可能与系统和emacs版本有关,我的是macos和emacs-plus 29。
大佬可以用下面的配置简单测试一下:
(use-package mini-frame
:hook (window-setup . mini-frame-mode))
(use-package posframe
:hook (window-setup . (lambda () (require 'posframe))))
(use-package selectrum
:hook (window-setup . selectrum-mode)
:config
(setq mini-frame-show-parameters
(lambda ()
(let* ((info (posframe-poshandler-argbuilder))
(posn (posframe-poshandler-point-bottom-left-corner info))
(left (car posn))
(top (cdr posn)))
`((left . ,left)
(top . ,top))))))
题外话插一句 use-package hook 后面如果接 lambda 的话是不会 defer 的,也即直接 require
:hook (window-setup . (lambda () (require 'posframe)))
这个展开不是 (add-hook 'window-setup-hook (lambda () (require 'posframe)))
吗?我以为可以defer的呢,才疏学浅
就是这个展开近似等价于
(add-hook 'window-setup-hook (lambda () (require 'posframe)))
(require 'posframe)
需要手动给 use-package
defer (别的非 lambda 的 hook 不需要)
(use-package posframe
:defer t
:hook (window-setup . (lambda () (require 'posframe))))
已纠正写法,谢谢 @Voleking 大佬~
楼歪了,让我扶正过来。目前已实现结果框的边缘大小与company-mode的margin大小一致,即一个字符宽度;两者与高亮行字符对齐一致:
(setq selectrum-display-action '(selectrum-posframe))
(defcustom selectrum-posframe-fringe 1
"The width of selectrum-posframe-fringe."
:type 'number)
(defun posframe-poshandler-point-bottom-left-corner-fringe (info)
"Poshandler looks like company-posframe."
(let* ((parent-window (plist-get info :parent-window))
(point (with-current-buffer (window-buffer parent-window)
(max (line-beginning-position)
(- (plist-get info :position) selectrum-posframe-fringe))))
(info (plist-put info :position-info (posn-at-point point parent-window))))
(posframe-poshandler-point-bottom-left-corner info)))
(defun selectrum-posframe (buffer _alist)
"Function used by `selectrum-display-action."
(frame-root-window
(posframe-show buffer
:min-height 10
:min-width 30
:background-color "#b4eeb4" ;; hl-line background color
:left-fringe (* (frame-char-width) selectrum-posframe-fringe)
:right-fringe (* (frame-char-width) selectrum-posframe-fringe)
:poshandler 'posframe-poshandler-point-bottom-left-corner-fringe
:lines-truncate t
)))
(set-face-attribute 'fringe nil :background 'unspecified :inherit 'hl-line)
(add-hook 'minibuffer-exit-hook 'posframe-delete-all)
TODO:
1、隐藏 “25 M-x”,即 candidates count 和 minibuffer-prompt ;
2、调整“结果框posframe”的宽高使之随candidaes长短多少而变化;
3、fringe背景色与“select-candidate”背景色不一致,可以考虑去掉finge,取而代之的是给每个candidate双侧加上一个字符宽度。
非IT专业,搞不动了……希望各位大佬出手相助
看来是minibuffer遮挡器的位置不对。