ace-pinyin 20160611.1755(in MELPA)
Jump to Chinese characters using avy or ace-jump-mode

概要

ace-jump-mode.el(レビュー) は、画面内の任意の位置に
少なくとも3ストロークで到達できるようにする
画面内に特化した 高速カーソル移動 パッケージです。

M-x ace-jump-char-mode は入力された文字をすべて
ハイライトし、その場所に即移動できるようにします。

しかし、日本人としては日本語に対応してほしいものです。

そこで ace-pinyin.el の出番です。

これは元々 ace-jump-char-modeを中国語文字に対応 させるものですが、
僕の目測通り、ひとつの変数を変更するだけでそのまま日本語文字に
対応できることがわかりました。

pinyin (ピンイン)とは、中国語のローマ字と思ってください。

設定はa〜zに対応する多くの日本語文字の正規表現を定義しているため、
とてつもなく長くなっています。

20150418063553.png
Fig1: この状態でM-x ace-jump-char-modeの後にkを押すと…

20150418063601.png
Fig2: か行に対応する日本語文字が移動対象になる

インストール

パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。

(package-initialize)
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "http://melpa.org/packages/")
        ("org" . "http://orgmode.org/elpa/")))

初めてace-pinyinを使う方は
以下のコマンドを実行します。

M-x package-install ace-pinyin

アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。

M-x package-install package-utils (初めてアップグレードする場合のみ)
M-x package-utils-upgrade-by-name ace-pinyin

設定 150418062221.ace-pinyin.el(ダウンロードしてください)

あまりに長いのでダウンロードしてください。

(require 'ace-pinyin)
;;; echo a | cmigemo -q --emacs -d /usr/share/cmigemo/utf-8/migemo-dict
;;; をa〜zで繰り返し、最初の[]の文字を取得することで生成
(setq ace-pinyin--char-table
  '(
    "[母餅渉恤閔憐遽慌鰒蚫鮑]"
    略))
(global-set-key (kbd "C-:") 'ace-jump-char-mode)
(ace-pinyin-global-mode 1)

実行方法

$ wget http://rubikitch.com/f/150418062221.ace-pinyin.el
$ emacs -Q -f package-initialize -l 150418062221.ace-pinyin.el

メカニズム

ace-jump-char-modeace-pinyin-jump-char にすり替え、
その中で ace-pinyin--jump-impl 関数を呼んでいます。

元々ace-jump-mode.elは正規表現検索に対応しているので、
アルファベットから中国語文字に対応する正規表現を作成すれば
中国語文字に対応できることになります。

その変換テーブルこそが ace-pinyin--char-table です。

(defun ace-pinyin--build-regexp (query-char &optional prefix)
  (let ((diff (- query-char ?a)))
    (if (and (< diff 26) (>= diff 0))
        (let ((regexp (nth diff ace-pinyin--char-table)))
          (if prefix regexp (concat (format "[%c]\\|" query-char) regexp)))
      (regexp-quote (make-string 1 query-char)))))

(defun ace-pinyin--jump-impl (query-char &optional prefix)
  "Basically copy the implementation of `ace-jump-char-mode'"
  (if ace-jump-current-mode (ace-jump-done))

  (if (eq (ace-jump-char-category query-char) 'other)
    (error "[AceJump] Non-printable character"))

  ;; others : digit , alpha, punc
  (setq ace-jump-query-char query-char)
  (setq ace-jump-current-mode 'ace-jump-char-mode)
  (ace-jump-do (ace-pinyin--build-regexp query-char prefix)))

変換テーブルはこのようになっています。

;;; 本当はめちゃくちゃ長いから縮めている
(defconst ace-pinyin--char-table
  '("[阿啊呵腌嗄锕吖爱哀]" ; a に対応
    "[把八吧巴爸罢拔叭芭]" ; b に対応
    ...
                           ; z に対応
))

日本語化するにいたって

ならば、 ace-pinyin--char-table を日本語文字に
対応させればいいことになります。

では、そのためにはどうやって日本語文字を集めるか…

cmigemo を使います。

$ echo a | cmigemo -q --emacs -d /usr/share/cmigemo/utf-8/migemo-dict
を実行すればaに対応する正規表現がMigemoから得られます。

結果は以下のようになります。

\([母餅渉恤閔憐遽慌鰒蚫鮑袷]\|廈\s-*門\|厦\s-  (略) \\)

そのうち、最初の [〜] に相当する部分を抜き出せば目的は達成できます。

これらをa〜zで繰り返し、 ace-pinyin--char-table を定義すればいいです。

そのためにRubyスクリプトを作りました。

# -*- coding: utf-8 -*-
def char2migemo(char)
  `echo #{char} | cmigemo -q --emacs -d /usr/share/cmigemo/utf-8/migemo-dict`
end

def ascii2jchar(char)
  char2migemo(char)[/^\\\(\[(.+?)\]/, 1]
end
def output
  tables = (?a..?z).map{|ch| format(%Q!    "[%s]"\n!, ascii2jchar(ch)) }.join
  <<XXXX
(setq ace-pinyin--char-table
  '(
#{tables}
  ))
XXXX
end

puts output

やはり僕の読みは正しかった…

本サイト内の関連パッケージ


本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。