Table of Contents
在 n 个月前, 我曾写过 helm与ivy简单对比, 并吐嘈了
ivy
细节打磨不够,以至于我切换到ivy
不到几天后, 又回到了helm
的拥抱, 但在n个月后,本着生命不止,折腾不息的精神, “狠狠地”的折腾了一把ivy
, 让ivy
也能像helm
一样“如丝般润滑”,适应我平时的操作
吐嘈一: counsel-find-file
我在dired中移动文件, 即使已经设置了
:map counsel-find-file-map ("C-h" . counsel-up-directory)但
C-h
返回上级目录还是无效
无意中从spacemacs中找到了解决办法(我电脑上常备 spacemacs 的配置,当看到 spacemacs 有什么更新都会切换过去尝试一番, 遇到适合自己的配置会"参考"一下, 哈), spacemacs 并没有遇到上述问题,在经过查找后,发现有这个一行
(define-key ivy-minibuffer-map (kbd "C-h") (kbd "DEL"))
转换成我自己的配置就是
:map ivy-minibuffer-map ("C-h" . [backspace])
吐嘈二: tab 键
tab 键我只想要complete, 而不是complete and done, 虽然
ivy
提供了另外的选项ivy-partial-or-done
,但不是我想要的效果,尤其是把aaa.py重命名为aaa.py.bak时
关于这一条,真的是“狠狠”地折腾了一把, 最终以胜利告终
(defun maple/ivy-done() (interactive) (let ((dir ivy--directory)) (ivy-partial-or-done) (when (string= dir ivy--directory) (ivy-insert-current) (when (and (eq (ivy-state-collection ivy-last) #'read-file-name-internal) (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last)))) (ivy--cd dir) (setq this-command 'ivy-cd)))))
主要思路就是插入当前选中项, 如果是=read-file-name-internal=(文件操作), 并且选中项是一个目录,则列出这个目录的文件,避免选中tab两次才能列出文件, 这样一来,第一次tab就是complete, 第二次tab才是done, 最终效果超出预期(V 字手)
吐嘈三: 记忆多个按键
ivy 有这样一个问题,它不会像 helm 一样在第一行显示用户输入的字符,在 ivy 的很多 issue 中都有人提了这个问题,如果当前目录下有名为aaa的目录,这是我想要创建一个aaa.py的文件,ivy 会列出 aaa 这个目录,那是我该怎么创建 aaa.py 文件。方法是一个新的命令
ivy-immediate-done
,而不是ivy-alt-done
现在的ivy已经支持可选择用户输入
(setq ivy-use-selectable-prompt t)
吐嘈四: 模糊搜索
在 helm 中我可以很容易的使用模糊搜索,ivy 中也一样,只要简单的设置
(setq ivy-re-builders-alist '((t . ivy--regex-fuzzy)))但 ivy 中有这样一个问题,空格键不能在模糊匹配中使用,/汗,作为从 helm 转入 ivy 的人,经常会不经意间在输入时按下空格键,然后,What? ivy 中搜索变成空了
其实我想要混合使用空格与非空格, 但最终还是没能找到解决办法, 因为我已经适应的使用空格分隔, 所以暂时使用
(setq ivy-re-builders-alist '((t . ivy--regex-ignore-order))
吐嘈五: 候选词按使用频率排序
这个。。。
吐嘈六: minibuffer
helm 从当前 buffer 中弹出 helm-buffer 是多么明智的选择,视野不会移动到当前 buffer 以外的地方,尤其是在屏幕较大的时候, 而 ivy 使用 minibuffer 总是从屏幕左下方弹出
经过多次试验, 最终也找到的解决办法
;; custom ivy display function (defvar maple/ivy-format-padding nil) (defun maple/ivy-read-around (-ivy-read &rest args) "Advice ivy-read `-IVY-READ` `ARGS`." (let ((maple/ivy-format-padding (make-string (window-left-column) ?\s))) (setcar args (concat maple/ivy-format-padding (car args))) (apply -ivy-read args))) (defun maple/ivy-format-function (cands) "Transform CANDS into a string for minibuffer." (ivy--format-function-generic (lambda (str) (concat maple/ivy-format-padding (ivy--add-face str 'ivy-current-match))) (lambda (str) (concat maple/ivy-format-padding str)) cands "\n")) (advice-add 'ivy-read :around #'maple/ivy-read-around) (setq ivy-count-format "" ivy-format-function 'maple/ivy-format-function)
主要思路就是在各个collections前添加空格, 空格宽度为 (window-left-column)
, window-left-column
按照 help 文档来说就是Return left column of window WINDOW, 与屏幕左边缘的距离; 然后自定义 ivy-format-function
,即可, 需要注意的一点, 不仅collections前需要添加空格, prompt前也需要添加空格
吐嘈七: dired 中复制或重命名文件
我之前想要复制或重命名一个文件,只要进入dired中按
C
或R
,然后选择目标就行,但不知道为什么,使用 ivy 时复制重命名总是报错,不成功
经过测试, 现在的ivy表现正常
吐嘈八: sudo edit
使用ivy时,
sudo edit
不成功
目前已正常
吐嘈九: counsel-ag 默认不会使用已选的单词
counsel-ag, 默认不会使用已选的单词, 想要查找已选单词, 需要在激活
counsel-ag
后使用M-n
, 很麻烦,不像helm默认就可以选择region里的单词, 另外counsel-ag
默认会使用含.git目录的目录作为根目录进行查找, 这与counsel-projectile-ag
功能上有些冲突了
解决办法很简单, defadvice counsel-ag
即可
(defun maple/counsel-ag(-counsel-ag &optional initial-input initial-directory extra-ag-args ag-prompt) (when (and (not initial-input) (region-active-p)) (setq initial-input (buffer-substring-no-properties (region-beginning) (region-end)))) (unless initial-directory (setq initial-directory default-directory)) (funcall -counsel-ag initial-input initial-directory extra-ag-args ag-prompt)) (advice-add 'counsel-ag :around #'maple/counsel-ag)
总结
-
说一说为什么想要折腾ivy:
-
在使用helm时, 首次打开会很慢(我在打开 emacs 后,习惯使用
helm-recentf
打开最近文件, 但不知道为什么,第一次会非常慢);另外, 打开 emacs 后, 必须先使用helm-recentf
才能激活helm, 如果使用其它helm命令, 比如helm-M-x
或者helm-projectile
只会使用默认的ido, 并不能激活helm -
helm真的为用户做出太多选择, 想要自定义非常难, 即使成功也不是从源头解决,而是用了取巧的办法
-
速度,不知道是不是我的感觉错误,最新版本的helm速度慢了很多
-
-
还得吐嘈ivy: ivy 细节上果然打磨不够, 不过经过调(折)教(腾), 大致上和我之前使用helm的习惯一样了
最终吐嘈点: ivy-occur,
ivy-occur
使用了wgrep作为多文件编辑, 但说实话, 我觉得很难用, 和helm-ag自己实现的helm-ag-edit比起来更是难受, 一会就要切换一下ivy-wgrep-change-to-wgrep-mode
, 不切用不了, 这个等有时间再折腾吧!
ok,就这样