5

我有以下函数在我在 dired 缓冲区中标记的文件上运行 ediff:

(defun mkm/ediff-marked-pair ()
  "Run ediff-files on a pair of files marked in dired buffer"
  (interactive)
  (let ((marked-files (dired-get-marked-files nil)))
    (if (not (= (length marked-files) 2))
    (message "mark exactly 2 files")
      (ediff-files (nth 0 marked-files)
           (nth 1 marked-files)))))

它仅适用于同一目录中的文件,我怎样才能使其适用于我在不同目录中标记的文件?

4

3 回答 3

4

这是我的解决方案,它适用于标记在同一个 dired 缓冲区中的文件,也适用于不同缓冲区中的文件。

(defun mkm/ediff-marked-pair ()
  "Run ediff-files on a pair of files marked in dired buffer"
  (interactive)
  (let* ((marked-files (dired-get-marked-files nil nil))
         (other-win (get-window-with-predicate
                     (lambda (window)
                       (with-current-buffer (window-buffer window)
                         (and (not (eq window (selected-window)))
                              (eq major-mode 'dired-mode))))))
         (other-marked-files (and other-win
                                  (with-current-buffer (window-buffer other-win)
                                    (dired-get-marked-files nil)))))
    (cond ((= (length marked-files) 2)
           (ediff-files (nth 0 marked-files)
                        (nth 1 marked-files)))
          ((and (= (length marked-files) 1)
                (= (length other-marked-files) 1))
           (ediff-files (nth 0 marked-files)
                        (nth 0 other-marked-files)))
          (t (error "mark exactly 2 files, at least 1 locally")))))
于 2013-10-01T09:16:12.743 回答
3

稍微扩充 mkm 的答案。除了处理可能跨 dired 缓冲区的 2 个标记文件之外,它还处理存在 0 或 1 个标记文件的情况。0 标记的文件会将光标下的文件作为文件 A,并提示要比较的文件。1 标记文件将标记文件用作文件A,并提示要与之比较的文件。该点下的文件用作提示中的默认值。我将此绑定到=。

(defun mkm/ediff-marked-pair ()
   "Run ediff-files on a pair of files marked in dired buffer"
   (interactive)
   (let* ((marked-files (dired-get-marked-files nil nil))
          (other-win (get-window-with-predicate
                      (lambda (window)
                        (with-current-buffer (window-buffer window)
                          (and (not (eq window (selected-window)))
                               (eq major-mode 'dired-mode))))))
          (other-marked-files (and other-win
                                   (with-current-buffer (window-buffer other-win)
                                     (dired-get-marked-files nil)))))
     (cond ((= (length marked-files) 2)
            (ediff-files (nth 0 marked-files)
                         (nth 1 marked-files)))
           ((and (= (length marked-files) 1)
                 (= (length other-marked-files) 1))
            (ediff-files (nth 0 marked-files)
                         (nth 0 other-marked-files)))
           ((= (length marked-files) 1)
            (let ((single-file (nth 0 marked-files))) 
              (ediff-files single-file
                           (read-file-name
                            (format "Diff %s with: " single-file)
                            nil (m (if (string= single-file (dired-get-filename))
                                       nil
                                     (dired-get-filename))) t))))
           (t (error "mark no more than 2 files")))))
于 2014-09-20T02:31:07.120 回答
2

这是一个解决方案:

(defvar mkm/dired-file-1)

(defun mkm/ediff-push ()
  (interactive)
  (setq mkm/dired-file-1 (dired-get-filename)))
(defun mkm/ediff-pop ()
  (interactive)
  (ediff-files mkm/dired-file-1 (dired-get-filename)))
(add-hook 'dired-mode-hook
      (lambda()
            (define-key dired-mode-map (kbd "C-c u") 'mkm/ediff-push)
            (define-key dired-mode-map (kbd "C-c o") 'mkm/ediff-pop)))
于 2013-08-08T09:19:31.747 回答