2019年8月3日土曜日

yaskkservがgeneral protection faultで死ぬのでlocal dictionaryに移行した

yaskkserv (1.1.0-2+b1)が以下のような感じで死んで使いものにならないので、Emacsのddskk側にlocal dictionaryを持たせてそこから変換することにした。

% dmesg
...
[ 6720.501847] yaskkserv_hairy[24540]: segfault at ffffffff65c2a470 ip 0000557bd2ec4550 sp 00007ffc5c73ac38 error 5 in yaskkserv_hairy[557bd2ec3000+11000]
[ 6720.501852] Code: 41 8b 7c 24 10 49 8b 5c 24 08 99 f7 ff 48 63 d2 4c 8b 34 d3 4d 85 f6 0f 84 7c 02 00 00 85 ff 0f 84 74 02 00 00 45 85 c0 74 46 <41> 0f b6 06 45 8d 68 fe 41 bb 01 00 00 00 49 83 c5 02 84 c0 0f 84
[ 6731.709864] traps: yaskkserv_hairy[24640] general protection fault ip:560bc7400550  sp:7ffc61b6d098 error:0 in yaskkserv_hairy[560bc73ff000+11000]
[ 6742.007321] traps: yaskkserv_hairy[24729] general protection fault ip:5633f951d550 sp:7ffd18e31568 error:0 in yaskkserv_hairy[5633f951c000+11000]
[ 6780.822601] traps: yaskkserv_hairy[24917] general protection fault ip:55eed261a550 sp:7fffa84c1108 error:0 in yaskkserv_hairy[55eed2619000+11000]
[ 6784.167264] traps: yaskkserv_hairy[25045] general protection fault ip:561fa6e21550 sp:7ffd698daa68 error:0 in yaskkserv_hairy[561fa6e20000+11000]
[ 6787.968865] traps: yaskkserv_hairy[25093] general protection fault ip:557eda003550 sp:7ffe8633b038 error:0 in yaskkserv_hairy[557eda002000+11000]
...


移行先の候補


* yaskkserv以外のskkserver → 未だにuim-skkを使っているので利点もあるが今回はパス
* EmacsのDDSKKにdictionaryを持たせる → 今回採用

yaskkservを使っていた一番の理由が複数の辞書を指定できることだった。SKKの辞書には一般的な使用に適するL辞書 (SKK-JISYO.L)の他にも、複数の専門的な辞書が存在していて、それを一括して指定できるのが便利だった。

ただし、他の辞書を1つしか指定できないskkserverであっても、複数に分割されている辞書を統合して1つの辞書にしてしまえば機能的に何ら変わらない。辞書を操作するためのツールであるskkdic-expr2を用いて作業する。

skkdic-exprとskkdic-expr2の違いは:

* 動作が高速 (expr2)
* skkdic-sortが必要ない (expr2)
* annotationに対応している (expr2)

など。


作業例


統合辞書の作製


必要なdictionaries (eg. /usr/share/skk/以下にあるものとか)を'+' operatorで結合する。個人的に旧仮名の北極三號も結合している。

% skkdic-expr2 dic1 + dic2 + ... + dicn

このあたりは一度適当なscriptに記述しておくと後は一発で同じ作業できるようになって面倒事が減る。bashとかzshの機能とかをうまく使って柔軟性の高いscriptを書けるのだろうが怠いのでabsolute pathを決め打ちした。

/etc/default/yaskkservの記述を参考にして取り込む辞書を決めてabsolute pathでリスト (というか空白で要素を区切った文字列)に記述し、bashの機能で空白' 'を' + 'に変換するという雑な方法でskkdic-expr2に与えている。

dic_list="\
/path/to/skk/dic1 \
/path/to/skk/dic2 \
...
/path/to/skk/dicn"

↓ ${dic_list// / + } # 文字列内のすべての' 'を' + 'にreplace

/path/to/skk/dic1 + /path/to/skk/dic2 + ... + /path/to/skk/dicn

なお、SKKの辞書はDebianならskkdicやskkdic-extraあたりに収録されていて、/usr/share/skk/以下に展開される。他にもCVS repositoryから引っ張って来ることもできるが、その場合はcvs update -dPしてmake allしないと辞書が生成されない (或いは最新版にupdateされない)ので注意。

使っているRuby scriptが想定しているversionが古いため、nitemsというobsoleteなmethod (Ruby 1.9で廃止)が使われていたりした。これはcount {|item| !item.nil?| }というRuby 1.9移行の等価な(?)記述に変更すれば動くようになる。

cf. [nitems (Array) - Rubyリファレンス](https://ref.xaio.jp/ruby/classes/array/nitems)

作製した辞書を使うための設定


Emacsの設定ではSKKのdictioaryのcharacter encodingをUTF-8にしている (defaultではEUC-JP)ので、nkfを使って結合済みのdictionary (SKK-JISYO.my)をUTF-8に変換する。

% nkf -w -Lu SKK-JISYO.my > SKK-JISYO.my.utf8

~/.skkの記述を変更してskkserverではなくlocal dictionaryを直接読み込む設定に変更。Dictionaryのcharacter encodingをUTF-8に指定するのも忘れずに。

(setq skk-large-jisyo "/path/to/SKK-JISYO.my.utf8")
(setq skk-jisyo-code 'utf-8)

M-x skk-restartを実行して設定を最新の状態に更新する。

*scratch* bufferあたりで適当に変換して期待する動作が行われることを確認して終了。

UIMなどimput methodにSKKを用いている場合は、それぞれのtoolbarとかから設定できるはず。UIMの場合はuim-pref-gtk3とかがあるのでそこから辞書サーバではなくてlocalの辞書fileを指定する。

これで設定が反映されれば良いが、されない場合は既存のprocess(es)を皆殺しにするか、Xのsessionをrestartすれば多分反映される。


0 件のコメント:

コメントを投稿