2019年8月31日土曜日

yascrollがemacsの仕様変更で動かなくなったので修正してみた

yascrollが動かなくなっていることに今頃気付いた。

試しに M-x yascroll:show-scroll-bar を実行してみると:
Wrong number of arguments: (left-width right-width outside-margins), 4
なるerror messageが返って来る。どうやらEmacs側の仕様変更があった模様。

git logで調べてみるとこれだった:
commit 8e0ebb9a3cb9beef2f5ff50436fef1c54a3e3c92
Author: Martin Rudalics <rudalics@gmx.at>
Date:   Mon Jul 22 09:19:18 2019 +0200
    Handle persistence of windows' scroll bar and fringes settings (Bug#36193)
src/window.cに含まれるwindow-fringesというCで書かれたfunctionは、これまで指定された (Emacsにおける) windowのleft-widgh, right-width, outside-marginsの3つのparametersを返していた。

このcommitで加えられた変更により、新たに4つ目のpersistentというparameterが追加された。これがyascrollの側でparametersの数が合わないというerrorの原因となっていた。

なお、window-fringesの詳細はEmacsからF1 helpで参照できる:
window-fringes is a built-in function in ‘C source code’.
(window-fringes &optional WINDOW)
  Probably introduced at or before Emacs version 22.1.
  This function does not change global state, including the match data.
Return fringe settings for specified WINDOW.
WINDOW must be a live window and defaults to the selected one.
Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS
PERSISTENT), see ‘set-window-fringes’.
さて、実際にerrorを起こしていたのはyascroll.el内に定義されたyascroll:choose-scroll-barである:
(defun yascroll:choose-scroll-bar ()
  (when (memq window-system yascroll:enabled-window-systems)
    (cl-destructuring-bind (left-width right-width outside-margins)
        (window-fringes)
      (cl-loop for scroll-bar in (yascroll:listify yascroll:scroll-bar)
               if (or (eq scroll-bar 'text-area)
                      (and (eq scroll-bar 'left-fringe)
                           (> left-width 0))
                      (and (eq scroll-bar 'right-fringe)
                           (> right-width 0)))
               return scroll-bar))))
left-width, right-width, outside-marginesの3つがcl-destructuring-bindに指定されているため、新たに4つ目のpersistentを返すようになったwindow-fringesと不整合を起こした。

解決方法は簡単で、
(cl-destructuring-bind (left-width right-width outside-margins persistent)
のように適当な名前のvariableを追加すれば良い (なお、このvariableは使われない)。

fileを修正したら、M-x byte-recompile-fileなどでyascroll.elcを再生成し、el-get-reload (他お好みのpackage management systemの作法)でyascrollをreloadする。

2019年8月3日土曜日

Debian sidのchromium (76.0.3809.87-1)でextensionが使えない

*** 2019-08-04更新 ***

* chromium 76.0.3809.87-2で修正されたことを確認した。

*** 更新ここまで ***


Debian BTSに同様の報告が既に上がっている。

何れ修正されたversionがuploadされるだろうが、workaroundとしてはdowngradeすれば直るとのこと。

cf. [#933598 - Most extensions now crash upon browser start - Debian Bug report logs](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=933598)


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すれば多分反映される。