git mergetool
に使えるツールとして、デフォルトで"emerge"
というのが用意されており、Emacs使いはこれを使えばEmergeでマージが行えるわけだが、難点もある。ひとつは、新たなEmacsインスタンスを起動してしまうということだ。起動に無駄な時間が掛かるし、マージにあたって既存のセッションで開いているファイルをその場で参照できないのは不便だろう。もっとも、これはemacsclient
を使うようにして、Emergeの呼び出し方を少し直せば済む。もうひとつは、EmergeではなくよりモダンなEdiffを使いたいということだが、これは思ったほど簡単ではないのでわざわざこうして記事を書くことになった。
というのも、Emergeにはemerge-files-with-ancestor-command
という便利なものがあり、「マージが終わったらマージ結果を保存して即終了」ということが一発で出来てしまうのだが、Ediffの方にはそういうものがない。こいつはマージを終了してもろくに片付けもせず、全部ほったらかしという行儀の悪さだ。
そういうわけで、まずはEdiffのediff-merge-{files,buffers}
が終わったら起動前のウィンドウ設定を復元するようにしてみる。これは比較的簡単。[2013-01-23改訂:フックにappendフラグを指定]
1 2 3 4 5 6 7 8 9 10 11 |
(eval-after-load "ediff" '(progn ; save and restore window configuration (defvar my-ediff-saved-window-configuration nil "Saved window configuration for ediff") (defun my-ediff-save-window-configuration () (setq my-ediff-saved-window-configuration (current-window-configuration))) (add-hook 'ediff-before-setup-hook 'my-ediff-save-window-configuration) (defun my-ediff-restore-window-configuration () (set-window-configuration my-ediff-saved-window-configuration)) (add-hook 'ediff-suspend-hook 'my-ediff-restore-window-configuration t) (add-hook 'ediff-quit-hook 'my-ediff-restore-window-configuration t))) |
次に、Ediffが新たに開いたファイルのバッファをマージ終了時に自動的に閉じる、および、マージ終了時に自動的にセーブしつつEmacsフレームを閉じる「バッチ版ediff-merge-files-with-ancestor
」を加える。[2013-01-23改訂:ediff-filesに影響を与えるなどおかしかったので大幅修正; 続きはGitHubで]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
(eval-after-load "ediff" '(progn ; batch mode (for use from git mergetool etc.) (ediff-defvar-local my-ediff-batch-mode-p nil "True if in batch mode") (ediff-defvar-local my-ediff-close-on-quit nil "True if the buffer should be closed on quit.") (defun my-ediff-batch-mode (&optional mode) (ediff-with-current-buffer ediff-buffer-A (case mode (set (setq my-ediff-batch-mode-p t)) (unset (prog1 my-ediff-batch-mode-p (setq my-ediff-batch-mode-p nil))) (t my-ediff-batch-mode-p)))) (defadvice ediff-find-file (around mark-newly-opened-buffers (file-var buffer-name &optional last-dir hooks-var) activate) (let* ((file (symbol-value file-var)) (existing-p (and find-file-existing-other-name (find-buffer-visiting file)))) ad-do-it (or existing-p (ediff-with-current-buffer (symbol-value buffer-name) (setq my-ediff-close-on-quit t))))) (defun my-ediff-save-merge () (if (my-ediff-batch-mode) (let ((file ediff-merge-store-file)) (if file (ediff-with-current-buffer ediff-buffer-C (set-visited-file-name file t) (save-buffer)))) (ediff-maybe-save-and-delete-merge))) (remove-hook 'ediff-quit-merge-hook 'ediff-maybe-save-and-delete-merge) (add-hook 'ediff-quit-merge-hook 'my-ediff-save-merge) (defadvice ediff-cleanup-mess (around support-batch-mode () activate) (let ((batch-p (my-ediff-batch-mode 'unset)) (buffers (list ediff-buffer-A ediff-buffer-B ediff-ancestor-buffer)) (buffer-C ediff-buffer-C)) ad-do-it (dolist (buffer buffers) (ediff-with-current-buffer buffer (and my-ediff-close-on-quit (kill-buffer)))) (when batch-p (ediff-kill-buffer-carefully buffer-C) (delete-frame)))) (defun ediff-merge-files-with-ancestor-in-batch-mode (file-A file-B file-ancestor &optional startup-hooks merge-buffer-file) (ediff-merge-files-with-ancestor file-A file-B file-ancestor (cons (function (lambda () (my-ediff-batch-mode 'set))) startup-hooks) merge-buffer-file)))) (autoload 'ediff-merge-files-with-ancestor-in-batch-mode "ediff") |
これで、~/.gitconfig
にこんな風に書けばgit mergetool
で瞬時にEdiffが起動し、マージが済んだらq, yで即コマンドラインに帰ってくる。既存Emacsセッションにゴミバッファも残らない。
1 2 3 4 |
[merge] tool = ediff [mergetool "ediff"] cmd = emacsclient -a \"\" -t -e \"(ediff-merge-files-with-ancestor-in-batch-mode \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" nil \\\"$MERGED\\\")\" |
あとは、たとえばラッパースクリプトを用意して、「<<<<<<<
」などの行が残っていたらマージ失敗とするとか、好きに改良すると良い。
порно
xnxx
Your talent is equal to your own inspiration. Giustino’s artwork is tasteful, and the written content is properly arranged. Despite this, you feel uneasy about the prospect of embarking on something that might cause you discomfort. I concede that you will be able to address this problem quickly.
Real Estate I really like reading through a post that can make men and women think. Also, thank you for allowing me to comment!
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
dodb buzz I very delighted to find this internet site on bing, just what I was searching for as well saved to fav
Fran Candelera This was beautiful Admin. Thank you for your reflections.
Blue Techker I am truly thankful to the owner of this web site who has shared this fantastic piece of writing at at this place.
child porn
Newtoki You’re so awesome! I don’t believe I have read a single thing like that before. So great to find someone with some original thoughts on this topic. Really.. thank you for starting this up. This website is something that is needed on the internet, someone with a little originality!
Самый лучший сайт для подростков с порно. restaurantetrivio.com услуги специальные очень качественные порно видео. Партнер pornhub.com