jdeeのコンパイルウィンドウでのエラーメッセージが化ける

とまぁ、そうやって動くようにしたjdeeですがコンパイルエラー時のエラーメッセージが化けます。

process-coding-system周りをいじってみてもダメでした。
ググってみると皆さんbean shellの表示localeをenにして逃げているようです。

まぁ確かに簡単な方法なんですが*1、せっかくの日本語環境なのに日本語がでないのも負けた気がするので何とかしてみます。

まずは原因追求から。
JDEEはデフォルトではbean shellをサーバとして立ち上げておいて、それに外からファイルコンパイル指示をすることでJVMの起動のオーバヘッドをなくしています。結局裏ではprocessが動いてるわけで、これがMeadowのbufferと結びついてエラーメッセージを表示してるわけです。

なのでbean shellの起動から追いかけていくと・・・

beanshell.el内のbsh-comint-buffer-execという関数までたどり着きます。

(defmethod bsh-comint-buffer-exec ((this bsh-comint-buffer) vm vm-args)
  (let ((win32-start-process-show-window t)
        (w32-start-process-show-window t)
        (w32-quote-process-args ?\") ;; Emacs
        (win32-quote-process-args ?\") ;; XEmacs
        (windowed-process-io t)
        (process-connection-type nil)
        ;; XEmacs addition
        (coding-system-for-read
         (if (or (member system-type '(cygwin32 cygwin))
                 (eq system-type 'windows-nt))
             'raw-text-dos)))
    (comint-exec (oref this buffer) "bsh"  vm  nil vm-args))
...

comint-execがprocessを起動してbufferと結びつける処理をしています。
で、その直前のletスペシャルフォームでcoding-system-for-readと言う名前の変数にwindowsだとraw-text-dosというシンボルを束縛しています。
何か怪しいですねぇ。

describe-bariableしてみると

coding-system-for-read is a variable defined in `C source code'.
Its value is nil


Documentation:
Specify the coding system for read operations.
It is useful to bind this variable with `let', but do not set it globally.
If the value is a coding system, it is used for decoding on read operation.
If not, an appropriate element is used from one of the coding system alists:
There are three such tables, `file-coding-system-alist',
`process-coding-system-alist', and `network-coding-system-alist'.

[back]

ということで他のcoding-systemの設定をこの変数上書きされているようです。
なのでこれを何とかする必要があるみたいです。


で、どうしたかというとcomint-execがプログラムを実行した後にcomint-exec-hookを呼び出してくれますのでこれで何とかしてみましょう。

で、何とかした結果こうなりました。

(defun jde-coding-reset ()
  (with-current-buffer buffer
    (set-buffer-process-coding-system 'undecided-dos 'undecided-dos)))

(defun my-jde-compile ()
  (interactive)
  (let (coding-system-for-read
	(comint-exec-hook comint-exec-hook))
    (add-hook 'comint-exec-hook #'jde-coding-reset)
    (jde-compile)))

(add-hook 'jde-mode-hook
	  #'(local-set-key "\C-c\C-v\C-c" 'my-jde-compile))

これでjde-modeでC-c C-v C-cするとmy-jde-compileが呼び出されることになり、なかでjde-compileを呼び出しますが、呼び出し前にcomint-exec-hookにjde-coding-resetをしこんで置きます。

こうすることで内部でbean shellを起動したあとにbean shellに割り付けられたbufferに対してset-buffer-process-coding-systemでencode/decodeを再設定しています。

これでエラーメッセージがちゃんとでるようになりますが、設定しているcoding-systemがundecided-dosなので自動判定の順序などによっては化けるかもしれません。その場合は適当なのにかえてやってください。

*1:bean shellの起動オプションでうまくいかないような書き込みもあってもしかしたらBean Shellのソース変更して再構築、というあまり簡単じゃない場合もあるかもしれませんが