【问题标题】:Emacs ediff marked files in different dired buffersEmacs ediff 在不同的 dired 缓冲区中标记了文件
【发布时间】:2013-08-08 08:55:14
【问题描述】:
我有以下函数在我在 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)))))
它只适用于同一目录中的文件,我怎样才能使它适用于我在不同目录中标记的文件?
【问题讨论】:
标签:
emacs
dired
emacs-ediff
【解决方案1】:
这是我的解决方案,它适用于标记在同一个 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")))))
【解决方案2】:
稍微扩充 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")))))
【解决方案3】:
这里有一个解决方案:
(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)))