在Emacs find file utility的最后,我声称“wl-find-file-in-other-root是functional的”,惭愧啊,偌大的一个find-file-existing在里面调用着,还敢声称是functional的。
知耻后勇,于是重写了部分实现,并且重新设计了接口,无需为每个root-list新写一个调用命令。代码如下:
(defvar wl-find-file-gcc-root-list nil)
(defvar wl-find-file-binutils-root-list nil)
(defvar wl-find-file-completing-read-function
'wl-iswitchb-completing-read)
(defun wl-iswitchb-completing-read (prompt choices
&optional dummy require-match)
"Use iswitchb completion functionality."
(let ((iswitchb-make-buflist-hook
(lambda ()
(setq iswitchb-temp-buflist
(cond ((consp (car choices))
(mapcar 'car choices))
((stringp (car choices))
choices)
((symbolp (car choices))
(mapcar 'symbol-name choices))
(t
(error "Unknown type of choices.")))))))
(iswitchb-read-buffer prompt nil require-match)))
(defun wl-find-file-root (filename root-list)
(find-if (lambda (dir)
(when (> (length filename)
(length dir))
(string-equal dir (substring filename
0 (length dir)))))
root-list))
(defun wl-find-file-other-root-list (filename root-list-list)
(when root-list-list
(let ((root (wl-find-file-root filename (car root-list-list))))
(if root
(list root (car root-list-list))
(wl-find-file-other-root-list filename (cdr root-list-list))))))
(defun wl-find-other-file-1 (filename &rest root-list-list)
(let* ((root (wl-find-file-other-root-list filename root-list-list))
(relative-path (substring filename (length (car root)))))
(remove-if (lambda (file)
(not (file-exists-p file)))
(mapcar (lambda (dir)
(expand-file-name relative-path dir))
(remove-if (lambda (elem)
(string-equal elem (car root)))
(cadr root))))))
(defun wl-find-other-file-other-window (filename)
(interactive
(list
(let ((completion-ignore-case t)
(file-list (wl-find-other-file-1 (buffer-file-name)
wl-find-file-gcc-root-list
wl-find-file-binutils-root-list)))
(if file-list
(funcall wl-find-file-completing-read-function
"Open file: "
file-list)
(error "%s does not exist in other directories"
(file-name-nondirectory (buffer-file-name)))))))
(find-file-other-window filename))





