求助ivy-posframe的设置

目标:使用ivy-posframe,ivy默认使用ivy-posframe-display-at-point,而swiper使用ivy-posframe-display-at-window-bottom-left。问题出在C-M-i触发completion-at-point用ivy补全时,非全局设置(github主页称为per-command mode),会失效。

我的配置如下:

(use-package ivy-posframe
  :ensure t
  :after (ivy)
  :config
  (setq ivy-fixed-height-minibuffer nil
        ;; ivy-display-function #'ivy-posframe-display-at-point
        ivy-posframe-parameters
        `((min-width . 90)
          (min-height .,ivy-height)
          (internal-border-width . 10)))
  (push '(t . ivy-posframe-display-at-point) ivy-display-functions-alist)
  (push '(completion-at-point . ivy-posframe-display-at-point)
        ivy-display-functions-alist)
  (push '(complete-symbol . ivy-posframe-display-at-point) ivy-display-functions-alist)
  ;; posframe doesn't work well with async sources
  (push '(swiper . ivy-posframe-display-at-window-bottom-left)
        ivy-display-functions-alist)
  (ivy-posframe-enable))

这个设备满足了默认的ivy用...-display-at-point,swiper用...-display-at-window-bottom-left,这个非常满意。 如下两图所示:

但是中间的completion-at-point或者complete-symbol并没有起作用(在ivy-posframe的github主页是给了这样的设置的),而且其实是没有调用ivy-posframe的,(注意要复现这个bug,要用 C-M-i来触发这个补全命令,不能用M-x运行,因为M-x会调用counsel-M-x,它会触发display-at-point),如下图所示:

如果使用注释掉的那行,即全局设ivy-display-funtionivy-posframe-display-at-point,则能使得 C-M-i 正确使用ivy-posframe在光标处补全,如下图(当然这种全局设置,就会使swiper也使用…at-point补全了):

然后我试了各种组合以及顺序,都搞不定哪。 求帮助08

@tumashu 求助作者,如果看到且有空,请帮忙看看 08

Temp override ivy-alist-setting, and run your command, you will find the proper function, need to setting

(defun ivy-alist-setting (alist &optional key)
  "Return the value associated with KEY in ALIST, using `assq'.
KEY defaults to the last caller of `ivy-read'; if no entry is
found, it falls back to the key t."
  (let ((s (cdr (or (let ((caller (or key (ivy-state-caller ivy-last))))
                      (and caller (assq caller alist)))
                    (assq t alist)))))
    (princ s)
    (princ "\n")
    s
    ))

这个法子没法拿到正确的ivy命令那个用于complete-symbol或者completion-at-point,输出如下:

ivy-sort-function-buffer
ivy-recompute-index-zero
ivy-display-function-overlay
nil
ivy--regex-plus
nil
ivy-recompute-index-zero

事实上,正确使用ivy-posframe的ivy命令,都是先调用的ivy-posframe-display-at-point,如下运行find-file时:

ivy-posframe-display-at-point
nil
ivy--regex-plus
ivy-sort-function-buffer
ivy-recompute-index-zero

ivy-sort-function-buffer
ivy-recompute-index-zero

估计ivy实现这个complete-symbol用的方式很特别吧

你可以不可以试试你的配置,看你运行C-M-icompletion-at-point)时,是不是正确使用-display-at-point (我相信你不会使用全局display-at-point,不然swiper根本没法用,跳到眼睛都花了)?如果没问题,可不可以分享你对ivy-posframe的配置?或者复现一下这个bug?

或者,分享下你使用ivy-posframe的正确姿势?都用一种么?还是不理completion-at-point这种老古董,反正也不会用到?

我刚才测试了以下,感觉不是补全的问题,而是 swiper 的问题

你的swiper 是绑定到快捷键的么? 还是从 M-x 调用的,如果 从 M-x 调用, 你就需要设置 M-x 的 ivy-posframe 显示方法。

求主题~~~

谢谢!

不会啊,按我上面提供的设置,除了completion-at-point,其他所有的ivy工具都正常,包括swiper应该右下显示(是使用快捷键)。你可以重新看下我一楼的问题描述。而如果想让completion-at-point也用ivy-posframe,就一定要用全局设置ivy-display-function了。

算了,估计是ivy实现complete-symbol (or completion-at-point),比较特殊,现有的ivy-posframe的per-command mode形式没法影响到它吧,即ivy-display-functions-alist的设置对它不起作用。

是doom-nord-light,注意是fuxialexander的实现,官方那个也是fuxialexander贡献的,但颜色有点不同,我喜欢fu–的实现,可能是pull request滞后吧。

答非所问。。。。 good luck

好吧,可能我的回答掺了别的让你迷惑了。

我刚才测试了以下,感觉不是补全的问题,而是 swiper 的问题

为什么提到swiper?我的swiper没问题,ivy-posframe不正常调用的是completion-at-point。还是你指的是,completion-at-point中有swiper的事儿?

提到swiper我不懂,所以我上条回复才重申了一下我的问题所在(即ivy-posframe的per-command下,哪里出问题了)

你的swiper 是绑定到快捷键的么? 还是从 M-x 调用的,如果 从 M-x 调用, 你就需要设置 M-x 的 ivy-posframe 显示方法。

我的测试都是它们的快键键触发的,我知道M-x调用时,用的是M-x的ivy-posframe设置。重新说明一下,除了complete-symbol(即completion-at-point),其他所有ivy/counsel/swiper (我所用到的)都正确使用ivy-posframe的。

我希望我说清楚了。

@tumashu

好了,解决方案找到了,通过翻找abo-abo很久前新加这个功能时的各种issues回复。

首先一个对一楼的简单回复,目标函数应该是ivy-completion-in-region

以下方案任选一:

  • 不清空ivy默认设定的ivy-display-function-alist时,设置completion-at-pointcomplete-symbol(你在ivy-posframe的readme.md里提供的)是不起作用的(C-M-i触发ivy补全时并不使用ivy-posframe), 而应该追加对ivy-completion-in-region进行ivy-posframe设置,如下:
  (push '(ivy-completion-in-region . ivy-posframe-display-at-point)
        ivy-display-functions-alist)
  • 之所以push complete-symbol 那条或全局的(push '(t . ivy-posframe-display-at-point) ivy-display-functions-alist) 不对 C-M-i作用,是因为ivy默认在ivy-display-function-alist中有对ivy-completion-in-region的设置。所以,简单处理可以清理ivy-display-function-alist,然后再添加ivy-posframe的per-command mode,这样可以避免被ivy默认设定的display形式覆盖而无法正确使用ivy-posframe:
  (setq ivy-display-functions-alist nil)
  (push '(t . ivy-posframe-display-at-point) ivy-display-functions-alist)
  (push '(swiper . ivy-posframe-display-at-window-bottom-left)
        ivy-display-functions-alist)

当然,你如果默认用的不是at-point,即(push (t . ...用的是别的display形式,但你想C-M-i用ivy-posframe的at-point,那你单独对ivy-completion-in-region设置一条at-point就好了。

这里贴出来给同样有疑惑的筒子们作参考吧。

总的来说,交流不是很顺畅,算了,不过问题算是解决啦。看来我有空了还是去了解下Ivy吧,只是抄配置用用,碰到问题就麻瓜了。

2 个赞

这里说的 command, 都是指的是绑定到快捷键的命令, 我这边 C-M-i 绑定到的是 completing-at-point :slight_smile:

可以把背景和选中的色号发出来吗

目测doom-nord-light

我在7楼给了theme链接,是doom-nord-light.

目测很准 哈哈哈

thankyou