在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))