2013-08-08 2 views
3

У меня есть следующая функция, которая работает Ediff на файлы, я помеченные в Dired буфера:Emacs Ediff отмеченных файлов в различных 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))) 
    (if (not (= (length marked-files) 2)) 
    (message "mark exactly 2 files") 
     (ediff-files (nth 0 marked-files) 
      (nth 1 marked-files))))) 

Он работает только с файлами в том же каталоге, как я мог заставить его работать с файлами, которые я отмечаю в разных устаревших каталогах?

ответ

2

Вот мое решение, оно работает для файлов, отмеченных в том же буфере 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"))))) 
1

Вот решение:

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

Дополнение mkm в ответе. В дополнение к работе над 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")))))