Monday, December 13, 2010

こっちで単語登録したら、あっちでも使いたい

これは SKK Advent Calendar 2010 の六日目 2010/12/13 の記事です。

五日目は tomoya さんによる、

です。 (setq skk-kakutei-when-unique-candidate t) は便利そうですね。実は単語登録したいとき困るのじゃないかと思っていたら、続けて skk-undo-kakutei すれば辞書登録モードになるという新発見もありました。

さて、SKK の特徴的な機能の一つには再帰的な辞書登録モードがあり、たとえ世界中のどの辞書にも載っていない単語だとしても、超簡単に単語を登録してあっというまに個人辞書を充実させていくことができます。

これは再帰していない

ぼくは普段 Windows のデスクトップで生活していて、Emacs では Daredevil SKK (ddskk) を使い、他のアプリケーションでは skkime を使って日本語を入力しています。ところが ddskk と skkime はそれぞれ別の個人辞書を使うので、どちらかで単語を登録してももう一方ではすぐにその単語が出てきません。これはちょっと悲しい。そこで今日は個人辞書育成を少しだけ楽しくする TIPS を紹介したいと思います。

skkime から ddskk の個人辞書を参照する

まずは skkime から ddskk の個人辞書を参照できるように設定します。

SKKIME1.5(build:20100719) Properties

skkime のプロパティを表示して、辞書設定のタブから、ファイル辞書として ddskk で使っている個人辞書のファイルを指定します。辞書ファイルのパスはお使いの環境に合わせてください。

ddskk の個人辞書はソートされていませんので、「この辞書はソートされている」のチェックは入れないようにしてください。

これで skkime の個人辞書にない単語を変換したときに、ddskk の個人辞書を参照して変換できるようになりました。

しかし、これだけでは、ddskk で単語登録した直後にはその単語を skkime で使うことができません。単語登録をしても、ディスク上の個人辞書ファイルがすぐに更新されるわけではないためです。

ですから、ddskk の設定にも少し手を入れます。以下のように .skk ファイルへ追記します。

(defvar my-skk-jisyo-updated
  nil
  "個人辞書の更新直後に保存するかどうかを示すフラグ")

(defadvice skk-henkan-in-minibuff (after my-skk-raise-jisyo-update-flag last
                                         activate compile)
  "単語登録された場合 my-skk-jisyo-updated をセットする"
  (if ad-return-value
      (setq my-skk-jisyo-updated t)))

(defadvice skk-update-jisyo (after my-skk-sync-private-jisyo last
                                   (word &optional purge)
                                   activate compile)
  "新たに単語が登録されたか削除された時、個人辞書を保存する"
  (if (or my-skk-jisyo-updated purge)
      (progn
        (skk-save-jisyo 'quiet)
        (setq my-skk-jisyo-updated nil))))

これで便利になりました!
ddskk で単語を登録して、すぐに skkime からもその単語を変換できるようになっていることを確認してみてください。

さて、続いてこんどは逆に ddskk から skkime の個人辞書を参照できるようにしましょう。

追記@Fri Dec 17 03:00:47 2010

2010/12/17 以降の CVS 版 ddskk をお使いの場合は、上記の代わりに以下のように書くだけで良くなりました。※コメント参照

(setq skk-save-jisyo-instantly t)

ddskk 開発者の北本さんが、同等の機能を ddskk 本体に取り込んでくださいました。
ありがとうございます!

ddskk から skkime の個人辞書を参照する

実はこれから紹介する方法はあまりスマートではありません。
と言うのも、前項のように辞書を更新する適切なトリガーが無い(あるいは、ぼくが知らない)ので、手動で更新するような形になってしまうのです。

まず、いくつかのツールが必要になるので、以下からダウンロードするなどして用意してください。

それぞれの実行可能ファイルを PATH の通ったディレクトリに置いて、以下のように .skk ファイルへ追記します。

(setq skk-extra-jisyo-file-list
      (list '("c:/Users/yu-ji/home/.skkime-jisyo_euc_sort" . euc-jp)))

(defun my-skk-update-skkime-jisyo ()
  "skkime の個人辞書を保存し、文字エンコーディングを変換し、ソートする
既に読み込まれていれば辞書バッファーを削除する"
  (interactive)
  (let* ((extra-jisyo-dir "c:/Users/yu-ji/home/")
         (extra-jisyo-name ".skkime-jisyo_euc_sort")
         (skkime-jisyo-dir "c:/Users/yu-ji/home/")
         (skkime-jisyo-name ".skkime-jisyo")
         (sync-command "syncskkiserv")
         (nkf-command "nkf -W16L -e -Lu -d")
         (buf (get-buffer (concat " *" extra-jisyo-name "*")))
         (command-line (concat sync-command
                               " && " nkf-command
                               " < " skkime-jisyo-dir skkime-jisyo-name
                               " | " "skkdic-sort"
                               " > " extra-jisyo-dir extra-jisyo-name)))
    (shell-command command-line)
    (if (buffer-live-p buf)
        (kill-buffer buf))))

辞書ファイルのパスはお使いの環境に合わせてください。既定では、

  • C:/Documents and Settings/ユーザー名/Application Data/skk/skki1_5
    あるいは、
  • C:/Users/ユーザー名/AppData/Roaming/skk/skki1_5

などになっていると思います。

このとき nkf に渡すオプションでは、skkime 用の辞書の文字エンコーディングが UTF-16-LE、ddskk 用の辞書は EUC-JP を想定しています。実際のところ様々なエンコーディングを使えるのですが、skkdic-sort のフィルターを通す前に EUC-JP へ変換する必要があります。

これで M-x my-skk-update-skkime-jisyo とすると、skkime 用の個人辞書を変換して ddskk で使えるようにしたファイルが用意され、このファイルを ddskk から参照して変換できるようになります。

理想的には、skkime で単語を登録したタイミングで個人辞書を保存したり、ddskk 側で(個人辞書以外にも)ソートされていない辞書ファイルを扱えれば良いのかなぁと考えています。

(add-hook 'skk-mode-hook
          (lambda () (my-skk-update-skkime-jisyo)))

いまのところはこのように C-x C-j したタイミングで更新するようにして使っています。

ということで

後半はかなり弱気になってしまいましたが、どうでしょうか。Advent Calendar 初参加の @yunh がお送りいたしました。

もしほかの上手い方法をご存知のかたがいらしたらぜひ教えてください。
そして可能ならブログしてその記事を SKK Advent Calendar 2010 で!

七日目となる明日は tyru さん Humanity が書いてくださいます。
よろしくお願いします!

追記@Wed Jan 05 00:35:29 2011

6 comments:

  1. ddskk で単語登録直後に個人辞書を更新するなら,
    (setq skk-jisyo-save-count 1)
    とかどうでしょうか.

    ReplyDelete
  2. ymir_lin さん、
    コメントありがとうございます!
    (setq skk-jisyo-save-count 1) はお手軽で良いと思います。ただ、確定するたびに保存することになってしまうので、今回のこれは実際に単語登録・削除があったときだけを対象にしてみました。

    ReplyDelete
  3. ぜひとも本体に組み込みたいのですが、よろしいでしょうか?
    Index: skk.el
    ===================================================================
    RCS file: /circus/cvsroot/skk/main/skk.el,v
    retrieving revision 1.541
    diff -u -r1.541 skk.el
    --- skk.el 1 Dec 2010 20:22:03 -0000 1.541
    +++ skk.el 16 Dec 2010 12:53:56 -0000
    @@ -2370,6 +2370,7 @@
    ;; 入っている。skk-henkan-count をインクリメントする必要はない。
    ;; new-one が空文字列だったら nil を返す。
    (unless (string= new-one "")
    + (setq my-skk-jisyo-updated t)
    new-one))))

    (defun skk-compute-henkan-key2 ()
    @@ -4208,7 +4209,13 @@
    (setq skk-kakutei-henkan-flag (skk-search-jisyo-file file limit nomsg)))

    (defun skk-update-jisyo (word &optional purge)
    - (funcall skk-update-jisyo-function word purge))
    + (funcall skk-update-jisyo-function word purge)
    + (if (and skk-save-jisyo-instantly
    + (or my-skk-jisyo-updated
    + purge))
    + (progn
    + (skk-save-jisyo 'quiet)
    + (setq my-skk-jisyo-updated nil))))

    ReplyDelete
  4. 北本さん、
    ご提案ありがとうございます。
    大変光栄に思います。ぜひよろしくお願いいたします!

    ReplyDelete
  5. CVS に commit しました。
    CVS 上の skk-vars.el と skk.el をインストールして、defadvice を無効化してテストしていただけると助かります。

    ReplyDelete
  6. 北本さん、
    CVS HEAD にて skk-save-jisyo-instantly の動作を確認いたしました。ありがとうございます!

    ReplyDelete