ivy 显示最近文件夹

我知道论坛已经有很多朋友写过这样的代码了,但是我不想要为这一个功能再安装一个包。所以我用的是陈斌大神的一段代码:

但是代码最后的动作有些不太合我的意。他的代码是用 dired 打开,能不能按 tab 键就将选中的文件夹作为 find-file 的输入,然后可以接着再输入以查找这个文件夹内的文件呢?回车键不变,仍然是打开dired。

直接find-file不能达到你的目的吗?

(defvar vmacs-last-dir "~/")

(defun vmacs-find-file()
  (interactive)
  (ivy-exit-with-action
   (lambda(c)
     (setq vmacs-last-dir c)
     (run-at-time 0.05 nil (lambda()
                            (let ((default-directory vmacs-last-dir))
                              ;; (find-file vmacs-last-dir)
                              (counsel-find-file )
                              )
                            ))
     )))

这把绑到tab上,

(setq ivy-dired-history-map
  (let ((map (make-sparse-keymap)))
    (define-key map  (kbd "TAB") 'vmacs-find-file)
    (define-key map  [(tab)] 'vmacs-find-file)
    map))

用的时候 传keymap

      (ivy-read prompt       
                :keymap ivy-dired-history-map
                :caller 'read-file-name-internal))))

另推荐

整合了Copy/Rename/Dired等命令,方便选中最近访问的目录

2 个赞

@jixiuf 非常感谢!请教您为什么要加 run-at-time

Edit 1:

刚才试了一下,简直好用到爆炸!不能更赞!

Edit 2:

我把陈斌和 @jixiuf 两位大神的代码综合了一下,方便大家复制粘贴。另外我做了修改,如果有安装有 ranger 会优先使用 ranger:

;; http://blog.binchen.org/posts/use-ivy-to-open-recent-directories.html
;; https://emacs-china.org/t/topic/5948/3?u=et2010
(defvar counsel-recent-dir--selected "~/")

(defvar counsel-recent-dir--map (let ((map (make-sparse-keymap)))
                                  (define-key map  (kbd "TAB") 'counsel-recent-dir--find-file)
                                  (define-key map  [(tab)] 'counsel-recent-dir--find-file)
                                  map))

(defun counsel-recent-dir--find-file()
  (interactive)
  (ivy-exit-with-action
   (lambda(c)
     (setq counsel-recent-dir--selected c)
     (run-at-time 0.05 nil (lambda()
                             (let ((default-directory counsel-recent-dir--selected))
                               ;; (find-file counsel-recent-dir--selected)
                               (counsel-find-file)))))))

(defun counsel-recent-directory ()
  "Open recent directory with dired"
  (interactive)
  (unless recentf-mode (recentf-mode 1))
  (let ((collection
         (delete-dups
          (append (mapcar 'file-name-directory recentf-list)
                  ;; fasd history
                  (if (executable-find "fasd")
                      (split-string (shell-command-to-string "fasd -ld") "\n" t))))))
    (ivy-read "directories:" collection
              :keymap counsel-recent-dir--map
              :action (lambda (x) (if (fboundp 'ranger) (ranger x) (dired x))))))

1 个赞

直接 find file 不方便,还需要输入路径

确实挺好用的,建议提个pull request给abo-abo,众乐乐嘛 :clap:

这段代码还有完善空间,现在等于调用了两次 ivy (两个 ivy buffer),中间会明显地闪一下。如果能把这个问题解决了,再考虑提出 PR。

恩。还有一个问题,没办法绑在ivy的map上,比如counsel-find-file-map,也是因为多重嵌套了ivy的map。
我刚转到ivy没多久,还不太了解怎么fix;研究研究~ 你有更新了这里吼一声哪

不用管 counsel-find-file-map,这里只有一个命令需要用户使用,就是 counsel-recent-directory,其它都是内部变量,函数。调用 counsel-recent-directory 然后按 tab 就行了。

Edit:

我把内部变量/函数都加了一个连字符,这样方便大家区分。