xyzzy から WinMerge を連携させる

これまで xyzzy を使っているときにファイルを比較したい場合、diff を xyzzy 内で動かしていた

しかし餅は餅屋ということで、以前紹介した WinMerge を使うことにした。

下記のコードを .xyzzy などに追記することで、開いているバッファ間の比較、2 画面ファイラでカーソル位置にあるファイル・ディレクトリを比較ができる。

;; diff として使うコマンド
; コマンドラインオプションは WinMerge のヘルプ内に書かれている
(setq *my-diff-command* "\"C:/Program Files/WinMerge/WinMergeU.exe\" /s")

;; カレントバッファでdiff
; new file: 現在のバッファがファイルに紐づいていればこのバッファ、そうでなければファイルを指定する
; old file: 別ウィンドウに開いているバッファがファイルに紐づいていればそのバッファ、そうでなければファイルを指定する
(defun diff-current-buffers ()
  (interactive)
  (let ((current-file-name (get-buffer-file-name (selected-buffer)))
        (another-file-name (and (not (eq (count-windows) 1))
                                (get-buffer-file-name (window-buffer (next-window (selected-window)))))))
    (call-process
     (format nil "~A \"~A\" \"~A\"" *my-diff-command*
          (or current-file-name (read-file-name "diff(new file): "))
             (or (and (not (eq current-file-name another-file-name)) another-file-name)
                 (read-file-name "another file(older): "))))))

; C-x d に割り当て
(define-key ctl-x-map #\d 'diff-current-buffers)

;; 左右のファイル・ディレクトリを比較
(defun filer-diff-file ()
  (let ((file1 (ed::filer-fetch-file nil nil))
	(file2 (ed::filer-fetch-file nil t)))
    (unless (and file1 file2)
      (error "比較するファイルを指定して"))
    (call-process
     (format nil "~A \"~A\" \"~A\"" *my-diff-command* file1 file2))))

; M-d に割り当て
(define-key filer-keymap #\M-d 'filer-diff-file)

ファイラでディレクトリ同士を比較する場合、サブディレクトリ内の比較は行わないようにオプションを指定してある。もしディレクトリを再帰的に比較したい場合は、開いた WinMerge 上で C-o を押してファイル選択ダイアログを開くと指定したディレクトリが入力されているので、「サブフォルダを含む」にチェックを入れて比較する。