all-the-icons-ibuffer 和 all-the-icons-ivy-rich 已经发布

这套还不是非常成熟和完善,所以目前我还用ivy+counsel 这个组合。all-the-icons-ivy-rich 是给ivy/counsel 专门定制的。

最近在doom上跑这个icon以及ivy-bibtex,发现了一个很奇怪的bug :joy:

我的ivy-bibtex-completion一直用的是默认的界面,如下图

这个界面我就很喜欢。但我发现只要我运行一下all-the-icons-ivy-rich-mode-reload,马上就会变成下面这个样子

我就觉得很神奇,为什么这个icons reload还能把ivy-bibtex的界面改了?难道是doom的ivy-bibtex配置跟这个icon插件冲突了?

我个人什么配置都没做,就按all-the-icons-ivy-rich的官方说明加载了一下,然后设置了ivy-bibtex的bib file路径。所有个性化配置全部默认。 :joy: 没有冒犯的意思,不知道是这个包的问题还是doom的问题? :joy:

补充一下刚才debug的一些结果: 在运行all-the-icons-ivy-rich-mode-reload之后,运行ivy-bibtex发现界面改变。但bibtex-completion-display-formats并未改变。运行org-ref-insert-cite-link(这个函数原定是会调出跟ivy-bibtex相同的界面的),界面也和原来一样。

所以问题出在ivy-bibtex本身的设定。org-ref显然用了什么函数来确保ivy的display transformer不受影响。

于是我查看org-ref的源码,发现他在常用函数org-ref-insert-cite-link那里写了一句

(ivy-configure 'org-ref-cite-insert-ivy :display-transformer-fn 'org-ref-ivy-bibtex-display-transformer)

这里的org-ref-cite-insert-ivyorg-ref-insert-cite-link实际调用的函数。

那么就是这一句保护了显示界面。于是我在运行all-the-icons-reload打乱界面之后,手动运行一句 (ivy-configure 'ivy-bibtex :display-transformer-fn 'org-ref-ivy-bibtex-display-transformer) 界面就变回去了。再次运行reload的话界面重新被打乱。

所以结论很明显:all-the-icons-ivy-rich-mode里面应该是某个步骤改掉了整个ivy的transformer, 导致ivy-bibtex设置好的transformer崩溃。

这下我就不知道我的个人配置该怎么写了 :joy: 我要保证运行counsel-projectile之后reload all-the-icons,还要保证reload之后立即重新配置ivy-bibtex的transformer。运行这个需要调用org-ref。。。已经被调用顺序搞得一头雾水。

做点贡献吧。问题解决了。原因如上所说,all-the-icons-ivy-rich-reload改变了某个transformer,使得ivy-bibtex的显示形式发生变化。而org-ref没有变化的原因是他在定义本身的interactive函数的时候在内部把display formats重新整理了一下。所以解决办法是自己定义一个ivy-bibtex函数把原来的覆盖掉,记得要在ivy-bibtex加载之后才行。

我猜all-the-icons-ivy-reload如此定义一定是楼主精心考虑过,因此我就不妄加提议尝试改变插件结构了。但既然跟ivy-bibtex的形式冲突,这里就提一个比较简单的配置方法。 代码如下(注意看注释)

(after! ivy-bibtex
  (defun ivy-bibtex (&optional arg local-bib)
  "Search BibTeX entries using ivy.

With a prefix ARG the cache is invalidated and the bibliography
reread.

If LOCAL-BIB is non-nil, display that the BibTeX entries are read
from the local bibliography.  This is set internally by
`ivy-bibtex-with-local-bibliography'."
  (interactive "P")
  (when arg
    (bibtex-completion-clear-cache))
  (bibtex-completion-init)
  (let* ((candidates (mapcar (lambda (entry)
			       (cons (bibtex-completion-format-entry entry (1- (frame-width)))
				     (cdr entry)))
			     (bibtex-completion-candidates))) ;;这一段是ivy-bibtex没有的,正是这句保护了显示形式。org-ref里定义org-ref-read-key时使用了这一段,进而让所有以这个函数为后端的interactive函数都保留了定制好的ivy表现形式。
         (key (bibtex-completion-key-at-point))
         (preselect (and key
                         (cl-position-if (lambda (cand)
                                           (member (cons "=key=" key)
                                                   (cdr cand)))
                                         candidates))))
    (ivy-read (format "BibTeX entries%s: " (if local-bib " (local)" ""))
              candidates
              :preselect preselect
              :caller 'ivy-bibtex
              :history 'ivy-bibtex-history
              :action ivy-bibtex-default-action
              :multi-action ivy-bibtex-default-multi-action
              :keymap (when ivy-bibtex-use-extra-keymap ivy-bibtex-extra-keymap))))
)

我用的doom所以这里是(after! ivy-bibtex)。不用doom的用eval-after-load就好了。

这段配置适用于全部想同时使用ivy-bibtexall-the-icons-ivy-rich的玩家。

可能直接给ivy-bibtex提交PR改掉这个比较好?

你的调试过程很详细 :+1:t2:

能否再确认下,disable all-the-icons-ivy-rich-mode,enable ivy-rich-mode,然后ivy-rich-reload,看看显示是否受影响。all-the-icons-ivy-rich 并没有修改ivy-bibtex,理论上不会影响才对。

刚试了一下。

调试前提:我把覆盖ivy-bibtex定义的那块删了。同时加载all-the-icons的方法如下:

(use-package all-the-icons-ivy-rich
  :hook (ivy-mode . all-the-icons-ivy-rich-mode)
  :config
  (all-the-icons-ivy-rich-reload))

;; More friendly display transformer for Ivy
(use-package ivy-rich
  :hook ((counsel-projectile-mode . ivy-rich-mode) ; MUST after `counsel-projectile'
         (ivy-rich-mode . ivy-rich-project-root-cache-mode)
         (ivy-rich-mode . (lambda ()
                            "Use abbreviate in `ivy-rich-mode'."
                            (setq ivy-virtual-abbreviate
                                  (or (and ivy-rich-mode 'abbreviate) 'name)))))
  :init
  ;; For better performance
  (setq ivy-rich-parse-remote-buffer nil)
  :config
  (all-the-icons-ivy-rich-mode 1))
(after! counsel-projectile
  (all-the-icons-ivy-rich-reload))

然后,在org里直接运行ivy-bibtex,是正常结果。 运行all-the-icons-ivy-rich-mode来把这个minor-mode给disable。此时运行ivy-bibtex界面就已经变了。

此时ivy-rich-mode是加载的状态。我关掉再开,界面依然是改变过的。ivy-rich-reload,界面依然是改变过的。

我觉得楼主这么好的插件,应该更大力气推广才是。我第一次见这个插件的时候就直接把doom默认的icon插件给关掉换成这个了。竞争力应该是很强的。

私以为,可以试着官方出一套在常见配置里添加这些icon的教程,把doom和spacemacs之类写进去。楼上是我把插件装doom里的办法。doom自己解决counsel-projectile和ivy-rich的加载顺序的办法也是单独一个(after counsel-projectile)再重新来一边icon配置。但我写的代码肯定没楼主好。楼主对doom的研究肯定比我透的多。

最好是给doom来个PR,把自己这个icon变成doom官方默认的icon,直接替换掉许久不更新的原版all-the-icons-ivy。这样一方面推广会很快,另一方面更多的使用者也会给出更多改进需求。最后估计能跟centaur一样火爆。

我对楼主期待好高 :joy:

你把all-the-icons-ivy-rich-mode 先删掉,只用ivy-rich-mode,看是否会改变布局。看起来是ivy-rich本身就已经改变了。不过得确认清楚。

是个好建议,本来这个插件是写给自己用的,写着写着功能就越来越多。doom-modeline已经进了doom 和spacemacs的官方配置。不过由于我本身并不使用,所以一直没给自己写的其他插件提PR合入doom或者spacemacs :joy: 我使用自己的Centaur Emacs

1 个赞

刚试了一下。我把all-the-icons-ivy-rich-mode删了,这下ivy肯定是没icon了。ivy-rich-mode默认开启。

然后直接开ivy-bibtex,界面正常。手动关掉ivy-rich-mode,此时界面改变。

看来你的猜想是对的,是ivy-rich-mode本身就改变了什么。这样的话只能去给ivy-bibtex提交pr了。听听楼主的建议吧,如果你觉得给ivy-bibtex交PR是最优解的话我就着手准备了。

我倒是可以试试写doom的PR。写好了给楼主看一下。 :joy:

1 个赞

也有可能是ivy-rich本身有问题,得仔细看看。