all-the-icons-ivy-setup为啥第一次调用,对counsel-find-file不生效呢?

突然发现了一个奇怪的现象。我使用all-the-icons-ivy来给ivy增加图标,按说明在init.el中调用all-the-icons-ivy-setup,switch-buffer,recentf等都很正常,今天偶然用counsel-find-file发现图标没有加上。重新执行一遍all-the-icons-ivy-setup,在counsel-find-file中图标就可以正常显示了; 为啥第一遍调用all-the-icons-ivy-setup对counsel-find-file不生效呢,但是这个函数对其他counsel命令都正常。而且第二遍调用,对counsel-find-file就生效了。这是为啥呢? 我查了一下all-the-icons-ivy的源码,里面设置counsel-find-file和counsel-recentf啥的是并列的,用dolist来循环处理,也没啥特别;

很奇特的现象。

又试了几次,发现在counsel-find-file的第一次调用前,调用(all-the-icons-ivy-setup),对counsel-find-file就不生效,对其他的命令没问题;调用过counsel-find-file后,只要再调用一次(all-the-icons-ivy-setup),counsel-find-file就可以有图标了。真的很诡异; 怎么判断counsel-find-file被第一次调用啊?有没有这样的hook?

(with-eval-after-load “counsel” (all-the-icons-ivy-setup)) 我猜的

这个我试了好像不行,应该是counsel的调用不一定是find-file。咋判断调用的是counsel-find-file呢?

我的配置没有调用all-the-icons-ivy-setup。相关部分配置很简单

(use-package ivy
  :ensure t
  :demand t
  :diminish
  :config
  (ivy-mode 1)
  (ivy-add-actions
   'ivy-switch-buffer
   '(("k" (lambda (x)
            (kill-buffer x)
            (ivy--reset-state ivy-last)) "kill"))))

(use-package counsel
  :ensure t
  :diminish
  :after ivy
  :bind (("C-x C-r" . counsel-recentf)
         ("C-c C-i" . counsel-imenu))
  :config
  (counsel-mode)

  (ivy-add-actions
   'counsel-recentf
   '(("r" (lambda (x)
            (recentf-remove-filename x)
            (ivy--reset-state ivy-last)) "remove"))))

(use-package ivy-rich
  :ensure t
  :after ivy
  :config
  (ivy-rich-mode 1))

(use-package all-the-icons
  :ensure t
  :if window-system
  :defer t
  :config
  (cond
   ((equal system-type 'darwin)
    (unless (member "all-the-icons" (font-family-list))
      (message "Download all-the-icons fonts...")
      (all-the-icons-install-fonts t)
      (message "Download all-the-icons fonts...done")))))

(use-package all-the-icons-ivy-rich
  :ensure t
  :if window-system
  :after ivy-rich
  :config
  (all-the-icons-ivy-rich-mode 1))

为什么不试试 all-the-icon-ivy-rich?

感觉有点慢啊。我最常用的命令就是ivy-switch-buffer。开启rich mode后总是一卡一卡的。

今天试了这个可以。我之前好像是过eval-after-load不行,为啥with-eval-after-load就可以呢?搞不懂了。

我看了下all-the-icons-ivy-rich的代码,感觉如果能把ivy-swith-buffer的显示部分减少一些,应该速度就会快一些了?应该是要修改all-the-icons-ivy-rich-display-transformers-list这个参数。可是我怎么能只修改ivy-switch-buffer的部分,而不动其他的配置呢?难道我要把all-the-icons-ivy-rich-display-transformers-list的所有内容都拷贝到init.el里才行?有什么办法只修改里面的一部分吗? 对elisp的语法还不太熟,只会做简单的修改,实在不好意思。。。。

谢谢

ivy-rich肯定会慢一些,但是并不明显,macOS/Linux/Windows都测试过。没有任何上下文无法判断根本原因在哪儿,我只能猜测了。

  • 如果是Windows,显示icon必须启用 (setq inhibit-compacting-font-caches t).
  • 如果你有远程文件访问,(setq ivy-rich-parse-remote-buffer nil) 可以提高性能。
  • all-the-icons-ivy-rich-display-transformers-list可以配置你想显示的任何命令和元素。
1 个赞

all-the-icons-ivy-rich-display-transformers-list这个参数如果要修改,怎么才能只修改其中一部分参数啊?难道要把整个参数拷贝出来然后修改,其他的都保留不动?我是想有没有什么语法可以指定只修改ivy-switch-buffer这部分参数?elisp不熟,不知道怎么写了。 我先把这个参数的定义部分全部拷贝出来改一下试试。 另外这个参数的set,是不是必须在启用(all-the-icons-ivy-rich-mode 1)之前才有效?