使用 counsel-file-jump 可以遍历搜索文件夹下的文件,例如:
/home/scriptdevil/test/
|-- doc
| |-- boo
| |-- build-instructions.md
| `-- running-tests.md
|-- include
| |-- bar.h
| `-- foo.h
|-- README
`-- src
|-- bar.c
`-- foo.c
在 test 调用 counsel-file-jump 会遍历所有子文件夹 doc、include、src 下的文件。
为 counsel-file-jump 添加 action:dired-do-copy
(ivy-add-actions
'counsel-file-jump
'(("C" dired-do-copy "@ Copy to")))
使用需要
在遍历出来的文件候选项,调用 ivy-mark 标记多个 candidate 后,调用 ivy-action:dired-do-copy。
我的期待
希望就像在 dired-mode 下在 dired-mark 多个 candidate 后,使用 dired-do-copy ,这个函数会询问需要复制到的目的文件夹,选定目的文件夹并确认后,就会完成复制。
实际情况
ivy-action:dired-do-copy 会多次被调用,依次传入 ivy-mark candidate 为参数到 action,导致需要多次为 dired-do-copy 函数选定目的文件夹。使用起来失去了 action 的便利宗旨。
问题
如何解决 ivy-action 这样使用情景,使得使用习惯保持和 dired-mode 一致?
你直接打开 dired 标记不好吗? 为什么要在 ivy 里面选?
1 个赞
因为 dired 只能 mark 一个文件夹下的文件,如果需要整理的文件散落在多个,有深度的子文件夹,需要频繁切换到各个子文件夹进行操作,比较麻烦。
dired 可以显示子文件夹的,C-u C-x d
可以给 dired 传参数,加个 R
就好,或者在 dired
里面也可以用 C-u s
来设置参数
Subdirectories in Dired (GNU Emacs Manual).

谢谢,为命令 ls 添加参数 R 后,可以一定程度满足需求。
稍微看了一下 ivy,它的 :action
是一个一个 candidate 调用的。:multi-action
是所有 candidates 一起调用的:
(ivy-read "select: " '("a" "b" "c" "d" "e")
:action
;; 直接回车不标记
(lambda (x)
(message "==> x: %S" x))
:multi-action
;; 标记了任意项
(lambda (xs)
(message "==> xs: %S" xs)))
不知 ivy-add-actions
添加的 action 是哪一种,如果是 :action
,其实也可以通过变量 ivy-marked-candidates
取得所有标记的项:
(ivy-read "select: " '("a" "b" "c" "d" "e")
:action
(lambda (x)
(when (equal (concat ivy-mark-prefix x)
(car ivy-marked-candidates))
(message "==> marked candidates: %S" ivy-marked-candidates))
(message "==> x: %S" x)))
1 个赞
解决这个问题无非是要把目录「拉直」。
要么用 subtree 展开,要么用 fd 。楼上提供的 ls -R 也可以实现,不过 dired 会用 subdir 的形式展示,多余要素很多。
但不管怎么讲,用 minibuffer 来选无疑最慢也最累。
如果是 Git项目,目录下还有 .git
文件夹,加R
参数,会把 .git
文件夹下的子目录也展开。
这个有办法过滤掉吗?
我是用 dired-omit-mode
,需要 (require 'dired-x)
, 可以通过设置变量 dired-omit-files
来用正则过滤文件
(setq dired-omit-files "\\`[.]?#\\|\\`[.][.]?\\'\\|^.git$")
2 个赞