指定したディレクトリを再帰的に検索してマッチしたファイルのリストを返す。
defun search-file (path match &optional ignore)
("Searches files of a directory recursively. Returns the list of matched files. "
let ((result nil)
(if ignore
(regexp ("/[.]\\{1,2\\}$" "\\|" ignore)
(concat "/[.]\\{1,2\\}$")))
(cl-labels ((rec (path)dolist (f (directory-files path t))
(cond
(push f result))
((string-match match f) (and (file-accessible-directory-p f)
((not (string-match regexp f)))
(
(rec f))t nil)))))
(
(rec path))nreverse result))) (
何もelispで実装しなくてもシェルコマンドで
(split-string
(shell-command-to-stringformat "find \"%s\" -name \"%s\"" (expand-file-name "~/LaTeX/") "*.pdf"))
("\n")
こんな感じで書いても良いと思う。それでもelispで書いたほうが若干融通が効くので。
"~/LaTeX") "\\.pdf$" "\\.git$") (search-file (expand-file-name
引数match,ignore
は"\\.git$\\|\\.svn$"
のように複数つなげても良い。この例では~/LaTeX
のpdfファイルを.git
ディレクトリを除外して検索している。
これを書いたのはあちこちに散らばっているpdfを絞り込み検索してviewerで見たいというのがあった。helm
のソースに使いたいというのが動機です。
defvar *pdf-search-path* '("~/LaTeX" "~/Downloads"))
(
defvar helm-open-pdf-program
(
(cl-case system-type"open")
('darwin "gnome-open")
('gnu-linux otherwise nil)))
(
defvar helm-source-pdf
("Open PDF")
'((name . lambda ()
(candidates . (
(cl-loop for dir in *pdf-search-path*nconc (search-file dir "\\.pdf$" "\\.git$"))))
(action . helm-open-pdf)))
defun helm-open-pdf (f)
(
(start-process-shell-command"helm-pdf"
nil
" " f)))
(concat helm-open-pdf-program
defun helm-pdf ()
(
(interactive)list helm-source-pdf))) (helm :sources (
M-x helm-pdf
でpdfを絞り込みして開く。viewerは上のhelm-open-pdf-program
に設定する。自分はMacとLinuxについてしか設定していない。
もう一例として旧ブログで書いたemacsでmp3を聞く(シンプルなmpg123-mode)のプレイリストの絞り込みにも使える。旧ブログでは自分のディレクトリ構造しか想定していなかったので気になっていたのです。たまにアクセスもあるのでGitHubのREADME.mdも修正しておきました。mpg123-simple - GitHub
defvar helm-mpg123-playlists
("Play List")
'((name . lambda () (search-file *mpg123-dir* "\\.m3u$")))
(candidates . (
(action . helm-mpg123-open-playlist)))
defun helm-mpg123-open-playlist (f) (interactive) (mpg123-mode f))
(
defun helm-mpg123 () (interactive) (helm :sources (list helm-mpg123-playlists))) (