Table of Contents
ivy默认的配置已经足够了,但还是可以通过一些技巧来提升使用体验
ivy中的tab
  ivy提供了好几个有关补全的命令,分别是ivy-done, ivy-partial-or-done, ivy-immediate-done, ivy-dispatching-done, 但不幸,想要获得高效的补全,我不得不记住这n多个命令,这常常使效率变得更低,
  所以,我自定义了一个 maple/ivy-done, 仅使用 tab 这一个按键就可以获得以上所有的体验
(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)))))
- 
预设场景一 dirs目录下有 init-a.el init-b.el init-c.el 等多个文件, 我需要把init-c.el重命名为init-c.el.bak, 默认的ivy会怎么做呢 - 
输入 init c 进行查找 
- 
使用 C-M-j(ivy-immediate-done) 插入当前选中项
- 
修改 
 而使用 maple/ivy-done 后呢 - 
输入 init c 进行查找 
- 
使用 tab插入当前选中项
- 
修改 
 
- 
- 
预设场景二 有一个n级子目录,需要切换到第n个子目录下, 默认的ivy会怎么做呢 - 
使用 tab选中
- 
再次使用 tab切换目录
 而使用 maple/ivy-done 后呢 - 
使用 tab选中并切换目录
 
- 
ivy中的C-h
  由于我是邪恶的 evil 用户, 所以我正常情况会使用 C-j, C-k来选择待选项,同样的,我希望能够使用 C-h 来进行某些操作,比如在counsel-ag中使用C-h代替backspace删除输入的字符,而在counsel-find-file中使用C-h切换到上一级目录
  ivy默认提供了 counsel-up-directory 命令可以切换到上级目录, 我希望能更进一步,当有插入的字符时, 调用C-h能够直接清除插入的字符,再次调用才切换到上一级目录
(defun maple/ivy-c-h () (interactive) (if (eq (ivy-state-collection ivy-last) #'read-file-name-internal) (if (string-equal (ivy--input) "") (counsel-up-directory) (delete-minibuffer-contents)) (ivy-backward-delete-char)))
ivy-occur批量操作
自动打开wgrep-mode
ivy默认调用ivy-occur后, 还需要调用ivy-wgrep-change-to-wgrep-mode才能进行批量修改
;; ivy-occur custom (defun maple/ivy-edit () "Edit the current search results in a buffer using wgrep." (interactive) (run-with-idle-timer 0 nil 'ivy-wgrep-change-to-wgrep-mode) (ivy-occur))
批量修改文件名
   预设场景: 当某个项目下有许多使用 aaa.py的文件,我需要把 aaa.py 全部修改为 bbb.py, 也许某个 aaa.py 需要修改成 ccc.py,我在使用 projectile-find-file 搜索完全部的 aaa.py 后,打开ivy默认的ivy-occur并不能对文件进行修改(提示Text read only), 所以我采用 find-name-dired 来批量修改文件名(目前还有些问题)
(defun maple/ivy-dired-occur() (interactive) (find-name-dired (or (projectile-project-root) default-directory) (concat (ivy--input) "*")) (ivy-exit-with-action (lambda (_) (pop-to-buffer (get-buffer "*Find*")) (dired-hide-details-mode) (wdired-change-to-wdired-mode) (when (bound-and-true-p evil-local-mode) (evil-normal-state)))))
counsel-find-file
重命名
预设场景: 有一个dirs目录, 我需要在同级目录下创建一个 dirs-aa.el 的文件, 默认的ivy会怎么做呢
- 
切换到 dirs 目录的上级目录 
- 
使用 ivy-immediate-done 插入目录名 
- 
新建文件 
但还有一种方式
- 
切换到 dirs 目录 
- 
使用 backspace键删除目录末尾的/
- 
新建文件 
   不幸的是,ivy中 backspace 的按键绑定了 ivy-backward-delete-char, 在 counsel-find-file 中使用 ivy会直接返回上级目录, 所以需要对 ivy-backward-delete-char 作简单的修改
(defun maple/ivy-backward-delete-char ()
  (interactive)
  (let ((dir ivy--directory)
        (p (and ivy--directory (= (minibuffer-prompt-end) (point)))))
    (ivy-backward-delete-char)
    (when p (insert (file-name-nondirectory (directory-file-name dir))))))
自动创建不存在的目录
不仅用于ivy, 其它文件操作命令也需要
(defun maple/ivy-make-directory-maybe () "Create parent directory if not exists while visiting file." (let ((dir (file-name-directory buffer-file-name))) (unless (file-exists-p dir) (if (y-or-n-p (format "Directory %s does not exist,do you want you create it? " dir)) (make-directory dir t) (keyboard-quit))))) (add-to-list 'find-file-not-found-functions 'maple/ivy-make-directory-maybe nil #'eq)
ivy自动使用选中的内容
  在使用 counsel-ag 或者 swiper, 我需要快速搜索选中的关键词,然而,ivy默认并不支持这么做,ivy需要打开counsel-ag后使用 M-n 插入选中的关键词,当然,也许是作者认为这样的方式很方便,但我并不认同,我为何需要重复一次操作呢,为何还需要记住 M-n 这样的按键呢?
(defun maple/region-string() "Get region string." (if (not (use-region-p)) "" (let* ((beg (region-beginning)) (end (region-end)) (eol (save-excursion (goto-char beg) (line-end-position)))) (deactivate-mark) (buffer-substring-no-properties beg (min end eol))))) ;; custom counsel-ag (defun maple/counsel-ag(-counsel-ag &optional initial-input initial-directory extra-ag-args ag-prompt) (funcall -counsel-ag (or initial-input (maple/region-string)) (or initial-directory default-directory) extra-ag-args ag-prompt)) (advice-add 'counsel-ag :around #'maple/counsel-ag)
这样,调用 counsel-ag 时,如何已经有选中的关键词,就会直接调用该关键词进行查找,避免重复操作, 同样的对于swiper 也可以使用另一种方式
(defun maple/ivy-search-at-point (func) (let ((ivy-initial-inputs-alist (list (cons func (maple/region-string))))) (funcall func))) (defun maple/swiper() (interactive) (maple/ivy-search-at-point 'swiper))
搜索某个目录
counsel-ag默认搜索当前目录,想要搜索某个目录,需要切换到该目录下调用counsel-ag,无疑的,这非常不方便,所以,我希望可以选择某个目录进行搜索
(defun maple/counsel-ag-directory() (interactive) (counsel-ag nil (read-directory-name "Search in directory: ")))
ivy的显示避免出现在视线外
详见 自定义helm式的ivy.html 中的
吐嘈六: minibuffer
counsel-ag指定文件后缀
关键词 -- -Ggo
 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
        知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
       
      