Hatena::ブログ(Diary)

わからん

2012.02.18

[] 今開いているファイルの git log -p を emacs で見る

emacs で編集中のファイルの git log -p を emacs で見る elisp を書きました。

すでにありそうですが、探すより実装する方が楽しいので自分で書きました。

M-x log で実行できます。


f:id:kitokitoki:20120218185202p:image


(require 'cl)

(defmacro* with-temp-directory (dir &body body)
  `(with-temp-buffer
     (cd ,dir)
     ,@body))

(defmacro aif (test-form then-form &optional else-form)
  `(let ((it ,test-form))
     (if it ,then-form ,else-form)))

(defmacro* awhen (test-form &body body)
  `(aif ,test-form
        (progn ,@body)))

(defun find-file-upward (file-name &optional dir)
  (interactive)
  (let ((default-directory (file-name-as-directory (or dir default-directory))))
    (if (file-exists-p file-name)
        (expand-file-name file-name)
      (unless (string= "/" (directory-file-name default-directory))
        (find-file-upward file-name (expand-file-name ".." default-directory))))))

(defun git-repo-p ()
  (when (find-file-upward ".git") t))

(defun git-log-p-this-file ()
  (interactive)
  (let ((file (buffer-file-name)))
    (unless (git-repo-p) (error "git 管理下にありません"))
    (let ((dir (concat (find-file-upward ".git") "/../"))
          (buf "*git-log-p-this-file*"))
      (with-temp-directory dir
         (awhen (get-buffer buf)
                (with-current-buffer it (erase-buffer)))
         (call-process-shell-command (concat "git log -p -- " file) nil buf t))
      (switch-to-buffer buf)
      (diff-mode)
      (goto-char (point-min)))))

(defalias 'log 'git-log-p-this-file)

[] Kernel#trap の戻り値はどう使うのか?

 疑問

Ruby のリファレンスマニュアルによれば、「trap は前回の trap で設定したハンドラを返します」。この Kernel#trap の戻り値の利用例が知りたいです。


 回答例

たとえば、現在設定しなおしているシグナルハンドラで、直近のシグナルハンドラの設定の内容を呼び出すのに使えます。

#!/usr/bin/env ruby

trap(:INT) { puts 'foo' }

old_handler = trap(:INT) {
  puts 'bar'
  old_handler.call if old_handler.respond_to?(:call)
}

sleep 5

# $ ./a.rb
# ^Cbar
# foo
Google