sdic-inline / ポイント下の単語の意味をミニバッファに表示する

ふと、Firefox の mouseover dictionary を使っていて似た機能が Emacs でも使いたいなと思い、作ってみました。
ポイント下にある単語の意味を辞書で引き、意味を自動でミニバッファに表示します。

インストール

ファイルは、EmacsWiki に置いておきました。ダウンロードし、load-path の通ったディレクトリに置けば OK です。

必要なものは、以下の通りです。

  1. sdic
  2. sdic 形式に変換した辞書
  3. popup.el (popup 表示を使用するならば)

1. は、sdic の関数を使用しているので、無ければ動きません。2. は、sdic を使っているならば、あると思うので問題無いと思います。
辞書については、自分は、英辞郎を購入して使っていますが、EDICT や GENE でも sdic 形式に変換すれば使えます。
# sdic で使えるので当然と言えば、当然ですが。
3. は、ポイント下の単語の詳細な意味を表示したい場合、popup ライブラリを使って表示しているので、その機能を使いたい場合、必要です。
基本的な機能については、無くても動きます。

設定

以下のような設定を .emacs に加えれば良いです。
辞書ファイルの位置については、適宜読み替えて下さい。

(require 'sdic-inline)
(sdic-inline-mode t)   ; sdic-inline モードの起動
;; 辞書ファイルの設定
(setq sdic-inline-eiwa-dictionary "/home/khiker/lib/dict/eijirou.sdic")
(setq sdic-inline-waei-dictionary "/home/khiker/lib/dict/waeijirou.sdic")

辞書ファイルのエンコーディングについては、`sdic-inline-dictionary-encoding' 変数に指定して下さい。
デフォルトの値は、euc-jp です。

動作

sdic-inline-mode がオンであると、ポイント下にある単語を辞書で自動でひき、結果をミニバッファに表示します。
0.3 以上であれば、リージョン選択がある場合、辞書でひく単語は、リージョンで選択された範囲のものとするようにしています。
# リージョン選択による表示を有効とする場合、transient-mark-mode がオンである必要があります。


現状では、以下のモード、ファイル、テキストプロパティ上で動きます。

  • メジャーモードが、text-mode outline-mode fundamental-mode のいずれかの場合。
  • カーソル下の単語のテキストプロパティが、font-lock-string-face か font-lock-comment-face のいずれかの場合。
    つまり、プログラムにおけるコメントか、文字列上の場合。
  • 閲覧しているバッファのファイルの拡張子が、.txt の場合。

それぞれ無効や動作するモードの追加等する場合は、以下の変数を編集して下さい。

;; sdic-inline を有効とするメジャーモードを収めたリスト。
sdic-inline-enable-modes
;; sdic-inline を有効とするテキストプロパティを収めたリスト。
sdic-inline-enable-faces
;; 以下に設定された正規表現とファイル名がマッチする場合、sdic-inline を有効とする。
sdic-inline-enable-filename-regex
;; この変数に指定された関数の実行結果が t を返す場合、sdic-inline を有効とする。
sdic-inline-enable-func

また、単語上で、C-cC-p を押す事で、popup ライブラリが有効ならば、単語の詳細な意味を表示する事ができます。
キーバインドは、sdic-inline-map に設定してありますので、気に入らない場合、適宜変更するなりして下さい。

;; http://github.com/m2ym/auto-complete
(require 'popup)

;; キー割り当ての変更
;; C-cC-p を無効化
(define-key sdic-inline-map "\C-c\C-p" 'nil)
;; C-cC-d にあらためて sdic-inline-display-popup を割り当て
(define-key sdic-inline-map "\C-c\C-d" 'sdic-inline-display-popup)

カスタマイズ

sdic-inline を動作させるモード等の編集は、例えば、以下のように行えます。

(setq sdic-inline-enable-modes nil)                ; major-mode を基準にオン・オフを判断しなくする。
(add-to-list 'sdic-inline-enable-modes 'w3m-mode)  ; w3m-mode でも動作するようにする。

(setq sdic-inline-enable-faces nil)                         ; テキスプロパティを基準にオン・オフを判断しなくする。
(add-to-list 'sdic-inline-enable-faces 'font-lock-doc-face) ; テキストプロパティが font-lock-doc-face である文字上でもオンとする。

また、0.3 以上では、ポイント下の単語を辞書でひく頻度も制御できるようにしました。
元々は、`sdic-inline-delay' に指定した秒数毎に、ポイント下の単語を辞書でひくようにしていたのですが、
あまりにも頻繁でうっとおしかったので頻度を減らすようにしました。
具体的には、前回辞書をひいたときと同じポイント位置であるならば、辞書はひかないという風にしました。
この機能は、以下の変数で制御できます。

(setq sdic-inline-not-search-style 'point) ; デフォルト値。ポイント位置が前回と同じである限り、再度辞書ではひかない。
(setq sdic-inline-not-search-style 'word)  ; カーソル下の単語が前回辞書で引いた単語と同じである限り、再度辞書ではひかない。
(setq sdic-inline-not-search-style 't)     ; sdic-inline-delay に定められた秒数毎にポイント下の単語を辞書でひく。

# 変数の名前がよくない(分かりづらい)気もしますが、良い名前が思い浮かばなかったので…。


単語の過去形や活用を除去したもので検索を自動的に行うようにしたいならば、以下のように変数を設定します。
# 例えば、enabled という単語がポイント下にあったならば、enable で検索する。

(setq sdic-inline-search-func 'sdic-inline-search-word-with-stem)

これは、sdic に付属する、stem.el を使って実現しています。
ただし、例えば、「enabled」という単語を stem.el に渡すと「enabl」、「enable」、「enabled」という3つの候補が返されます。
現状では、全ての候補に対して検索を行い、得られた結果を全て表示するようにしています。
そのため、もしかしたら、何かの単語では、候補が表示されすぎてしまい、ミニバッファが大きくなりすぎて見辛いという事が起こるやもしれません。
この機能は、0.4 より実装しました。
# しばらく使用してみて、問題が無いようであれば、この挙動をデフォルトへと変更するかもしれません。ただ、やるとしてもいつになるかわからないですが(^^;) (2010/03/06)


また、ポイント上の単語の一致は、「student 」のように単語の後に空白があって、その空白の上にポイント(カーソル)があった場合でもマッチします。
これは、sdic-inline が current-word でポイント下に単語があるかどうかをチェックしているためです。
# 実際辞書とマッチする語句を取得するのは、sdic-word-at-point という sdic にある関数を使っています
# current-word でポイント下に単語があるかどうかをチェックしている理由は、sdic-word-at-point だとポイントがどの場所にあっても、
# 確実に何らかの語句を返し、マッチしすぎてしまうためです。
この挙動(単語の後に空白がいくつかあってもマッチするという挙動)を、ポイント下に単語がある場合のみマッチするとしたい場合、
以下のように変数 sdic-inline-word-at-point-strict を t とします。

(setq sdic-inline-word-at-point-strict t)

スクリーンショット

以下のようにミニバッファに意味を表示します。

次のように、単語上で C-cC-p を押す事で、popup ライブラリが有効ならば、単語の詳細な意味を表示します。
# 通常、単語の意味がミニバッファ1行に収まるように、意味が長すぎる場合はカットしています。
# 1単語1行で、複数候補がある場合、その候補分ミニバッファに表示します。

また、複数の候補がある場合、これも popup ライブラリが有効ならば、popup-cascade-menu を使用してどのケースの意味を表示するかを選択し、
最終的に、popup-tip で表示します。


拡張機能

sdic-inline-pos-tip.el

URL:http://www.emacswiki.org/emacs/PosTip


Twitter の @iRi_E さんが、拡張機能を作って下さりました。ポイント下の単語の意味について、tooltip を使って表示できます。すごくかっこ良いです。

使用するには、pos-tip.el と `sdic-inline-pos-tip.el の2つが必要です。おそらく、-nw な環境では使用できないと思われます。 (追記) 0.0.2 から -nw な環境ではミニバッファに表示するように修正がされて、動くようになったぽです。
EmacsWiki よりそれらをダウンロードし、`load-path' の通ったディレクトリに置きます。

そして、.emacs に以下の設定を追記します。

(require 'sdic-inline-pos-tip)
(setq sdic-inline-search-func 'sdic-inline-search-word-with-stem)
(setq sdic-inline-display-func 'sdic-inline-pos-tip-show)
(define-key sdic-inline-map "\C-c\C-p" 'sdic-inline-pos-tip-show)
リージョン選択した場合のみ、tooltip に表示する

通常の自動表示では、ミニバッファに表示をし、リージョン選択をした場合のみ tooltip (pos-tip-show) で表示を行います。
以下の設定を追記して下さい。pos-tip.el と sdic-inline-pos-tip.el の関数を使用しているので、それら両者が必要です。

(require 'sdic-inline-pos-tip)
(defun sdic-inline-pos-tip-show-when-region-selected (entry)
  (cond
   ((and transient-mark-mode mark-active)
    (funcall 'sdic-inline-pos-tip-show entry))
   (t
    (funcall 'sdic-inline-display-minibuffer entry))))

(setq sdic-inline-search-func 'sdic-inline-search-word-with-stem)
(setq sdic-inline-display-func 'sdic-inline-pos-tip-show-when-region-selected)
(define-key sdic-inline-map "\C-c\C-p" 'sdic-inline-pos-tip-show)

その他


何か機能について要望や、バグがあったならば、教えて頂けると幸いです。
それでは。

更新履歴

0.4.5
  • 変数 sdic-inline-word-at-point-strict を追加した。
    • 単語がポイント下(ポイント直後を含む)にある場合のみ意味を表示する。
0.4.4
  • 空行等で sdic-inline がエラーを出していたのを抑制した。
  • キーマップの設定を修正した。
0.4.3
  • ミニバッファに意味を表示する場合、今までは意味しか表示していなかったが、その意味を示す単語名も表示するようにした。
0.4.2
  • `sdic-inline-word-at-point` でマッチする語句を正規表現における \\w にマッチしたもののみとした。
0.4.1
  • `sdic-inline-search-word-with-stem' で同じ候補が2つ重複して表示される事がある問題を修正した。
0.4
  • 変数 `sdic-inline-search-func' を追加した。辞書検索を行い、entry を返す関数を指定する。
  • sdic.el に付属する stem.el を用い、過去形や活用を取り除いた語句でも辞書検索し、その entry を返す関数 `sdic-inline-search-word-with-stem' を追加した。
0.3
  • 変数 `sdic-inline-not-search-style' の追加。ポイント下の単語を辞書で検索する頻度を制御できるようにした。
  • 変数 `sdic-inline-get-word-func' の追加。単語を取得する関数を指定できるようにした。
  • リージョン選択がある場合、辞書でひく単語は、リージョン選択されている範囲とするようにした。

更新時刻

  • 2010/03/03/23:50
  • 2010/03/04/00:59
  • 2010/03/04/08:30 / ちょっとちっちゃなバグをみつけたので修正。→ 0.2.1 へ。
  • 2010/03/06/01:00 / 機能更新。ブログへ追記。→ 0.3 へ。
  • 2010/03/06/02:10 / 機能更新。ブログへ追記。→ 0.4 へ。
  • 2010/03/06/02:30 / バグ修正。`sdic-inline-search-word-with-stem' で同じ候補が2つ重複して表示される事がある問題を修正。→ 0.4.1 へ。
  • 2010/03/07/19:15 / @iRi_E さん作の sdic-inline-pos-tip.el を追記。
  • 2010/03/08/18:20 / sdic-inline-pos-tip.el が -nw で動くようになった旨を追記。
  • 2010/03/23/00:45 / ちょっとした機能修正。→ 0.4.2 へ。
  • 2010/03/28/01:05 / ちょっとした機能修正。→ 0.4.3 へ。
  • 2010/05/06/23:12 / バグ修正 → 0.4.4 へ。
  • 2010/05/07/02:26 / 機能追加 → 0.4.5 へ。