Emacs find file utility

最近在移植代码过程中,需要在三个不同的gcc(FSF, Marvell和Android)源代码目录下,查看、比较文件。在另外的目录下打开同一个文件的操作比较繁琐,于是写了点Emacs Lisp代码,自动完成带开文件的操作。

方法很简单,有一个根目录列表,

(defvar wl-find-file-gcc-root-list
  (mapcar 'expand-file-name
          '("~/project/git/marvell-toolchain/src/gcc-src/"
            "~/project/git/fsf-gcc/"
            "~/project/android/toolchain/gcc/gcc-4.4.3/")))

然后通过比较根目录字符串,得到当前buffer对应文件的相对路径,在提示用户选择其它根目录,并打开该目录下的对应文件。

(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-in-other-root (filename dir root-list)
  (let* ((root (wl-find-file-root filename root-list))
         (relative-path (substring filename (length root))))
    (find-file-existing (expand-file-name relative-path dir))))

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

(defvar wl-find-file-completing-read-function
  'wl-iswitchb-completing-read)

(defun wl-gcc-find-buffer-file-in-other-root (dir)
  (interactive
   (list
    (let ((completion-ignore-case t)
          (root (wl-find-file-root (buffer-file-name)
                                   wl-find-file-gcc-root-list)))
      (funcall wl-find-file-completing-read-function
               "Open file in: " (remove-if (lambda (elem)
                                             (string-equal elem root))
                                           wl-find-file-gcc-root-list)))))
  (wl-find-file-in-other-root (buffer-file-name)
                              dir
                              wl-find-file-gcc-root-list))

模仿Land of Lisp里面的程序风格,把代码分成functional和非functional两部分,其中wl-find-file-in-other-root是functional的,实现核心功能,而接口则是非functional,使用全局变量。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据