sdic の内容をツールチップにしてみた.

以前より, id:tomoya さんのこちらの記事 を見て, 「ええなーこれー, でも Mac のだしなー. 自分 Gentoo だもんなー」とか思って, (Mac を持っているはずなのに) 指をくわえて見ていました.
話は変わって, 私は Emacs 上で sdic を利用して, 英和←→和英の検索を行っています. sdic を利用されている方はご存知でしょうが, sdic の動作として, 検索結果のバッファが popup してきます. ほんのちょっとしか例がなかったりする場合でも, 大量に結果がある場合でも, これは変わりません. この部分が, 以前からちょっとだけ不満でした (別に気にしなけりゃいいんですが).

で, ちょうどよかったので, ↑の記事をフルに参考にさせていただいて, sdic の結果を popup.el を利用してツールチップで結果を出すようにしてみました. 今回はスクリーンショットもとってみました.

↓こんな感じです. ここでは "set" を検索してみた結果です. 普段利用している Emacs のサイズそのままなので, ちとでかいです.
http://d.hatena.ne.jp/derui/files/popup-sdic.png?d=.png

ソースコードは以下です. temp-cancel-read-only は, tomoya さんが書かれたものを極一部だけ変更していますが, ほぼすべてそのままです. my-sdic-describe-word-with-popup は, sdic-describe-word を一部改変した関数です.
最後の advice で, sdic-describe-word-at-point でも popup するようにしています.

(defun temp-cancel-read-only (function &optional jaspace-off)
  "eval temporarily cancel buffer-read-only
&optional t is turn of jaspace-mode"
  (let ((read-only-p nil)
        (jaspace-mode-p nil))
    (when (and jaspace-off jaspace-mode)
      (jaspace-mode)
      (setq jaspace-mode-p t))
    (when buffer-read-only
      (toggle-read-only)
      (setq read-only-p t))
    (eval function)
    (when read-only-p
      (toggle-read-only))
    (when jaspace-mode-p
      (jaspace-mode))))

(defun my-sdic-describe-word-with-popup (word &optional search-function)
  "Display the meaning of word."
  (interactive
   (let ((f (if current-prefix-arg (sdic-select-search-function)))
         (w (sdic-read-from-minibuffer)))
     (list w f)))
  (let ((old-buf (current-buffer))
        (dict-data))
    (set-buffer (get-buffer-create sdic-buffer-name))
    (or (string= mode-name sdic-mode-name) (sdic-mode))
    (erase-buffer)
    (let ((case-fold-search t)
          (sdic-buffer-start-point (point-min)))
      (if (prog1 (funcall (or search-function
                              (if (string-match "\\cj" word)
                                  'sdic-search-waei-dictionary
                                'sdic-search-eiwa-dictionary))
                          word)
            (set-buffer-modified-p nil)
            (setq dict-data (buffer-string))
            (set-buffer old-buf))
          (temp-cancel-read-only
           '(popup-tip dict-data :scroll-bar t :truncate nil))
        (message "Can't find word, \"%s\"." word))))
    )

(defadvice sdic-describe-word-at-point (around sdic-popup-advice activate)
  (letf (((symbol-function 'sdic-describe-word) (symbol-function 'my-sdic-describe-word-with-popup)))
    ad-do-it))

わりとさっくりと作ったので, どっか不具合があるかもしれません. 特に sdic のバッファが read only の場合とか無視したので, sdic のバッファが殘っている場合は一回 delete-buffer してからやってみると上手くいきます.