2014年3月5日水曜日

[OCaml]cursesライブラリの wide character サポートを有効にする

OCaml にも、Cursesライブラリがある(OCaml Curses)。
このライブラリは opam でインストールできるが、現バージョンのcurses-1.0.3では、wide characterサポートが有効になっておらず、日本語は文字化けして正しく表示できなかった。
opamでのインストール時に実行するconfigureに、--enable-widec を付けてビルドできれば良いのだけど、具体的にどのようにすればできるのか不明だった。
何とかできないかなーと、tweetしていたところ、
星のキャミバ様さんに、ローカルリポジトリを作る方法で、簡単に自分用パッケージを作成できることを教えていただいた。

想像していたよりも、かなり簡単にパッケージを作成することができ、wide characterサポートを有効にしたOCaml cursesライブラリをインストールすることできた。
星のキャミバ様さん、ありがとうございます!

以下、手順。

ローカルリポジトリにするディレクトリ(~/opam_myrepo とした)を作成する。
~$ mkdir ~/opam_myrepo

そのリポジトリを登録する。
~$ opam repo add myrepo ~/opam_myrepo
myrepo     Synchronizing with /home/satoshi/opam_myrepo
[WARNING] "/home/satoshi/opam_myrepo" doesn't contain a "packages" nor a "compilers" directory.
Is it really the directory of your repo ? ("opam remote remove myrepo" to revert)
Updating ~/.opam/repo/compiler-index ...
Updating ~/.opam/compilers/ ...
Updating ~/.opam/repo/package-index ...
Updating ~/.opam/packages/ ...
Updating the cache of metadata (~/.opam/state.cache) ...

登録できたか確認する。
~$ opam repo
  10 [local]     myrepo     /home/satoshi/opam_myrepo
   0 [http]     default     https://opam.ocaml.org

opam_myrepoディレクトリ配下に、packages/curses.1.0.3/を作り、その中に、descr, opam, url ファイルを作る。
curses.1.0.3をインストール済みだったので、~/.opam/packages/curses/curses.1.0.3 からコピーした。

~$ cd opam_myrepo
~/opam_myrepo$ mkdir -p packages/curses.1.0.3
~/opam_myrepo$ cd packages/curses.1.0.3
~/opam_myrepo/packages/curses.1.0.3$ cp ~/.opam/packages/curses/curses.1.0.3/* ./

この後、cursesは再インストールするので、削除する。(reinstallするなら、削除しなくても良いかも)
$ opam remove curses

コピーしたopamを編集して、
--enable-widecを追加する。
〜略〜
build: [
  ["./configure" "--enable-widec"] ←◆これ
  [make "byte"]
  [make "opt"]
  [make "install"]
]
〜略〜

リポジトリをアップデートする。
~/opam_myrepo/packages/curses.1.0.3$ opam update
myrepo     Synchronizing with /home/satoshi/opam_myrepo
default    Downloading https://opam.ocaml.org/urls.txt
default    Downloading https://opam.ocaml.org/index.tar.gz
Updating ~/.opam/repo/compiler-index ...
Updating ~/.opam/compilers/ ...
Updating ~/.opam/repo/package-index ...
Updating ~/.opam/packages/ ...
Updating the cache of metadata (~/.opam/state.cache) ...
0 to install | 11 to reinstall | 17 to upgrade | 0 to downgrade | 0 to remove
You can now run 'opam upgrade' to upgrade your system.

curses をインストールする。
~/opam_myrepo/packages/curses.1.0.3$ opam install curses
The following actions will be performed:
 - install curses.1.0.3
1 to install | 0 to reinstall | 0 to upgrade | 0 to downgrade | 0 to remove

=-=-= Installing curses.1.0.3 =-=-=
curses.1.0.3 ocaml-curses-1.0.3.ogunden1.tar.gz is in the local cache, using it.
Building curses.1.0.3:
  ./configure --enable-widec  ←◆ここ。できたー!!
  make byte
  make opt
  make install
Installing curses.1.0.3.

wide character サポートが有効になったか調べる。
$ echo -e '#require "curses";;\nlet s = if Curses.Curses_config.wide_ncurses then "wide char ok!" else "no wide char support." in print_endline s;;' | ocaml
〜略〜
/home/satoshi/.opam/system/lib/herelib/pa_herelib.cma: loaded
# /home/satoshi/.opam/system/lib/curses: added to search path
/home/satoshi/.opam/system/lib/curses/curses.cma: loaded
# wide char ok! ←◆wide characterが有効になった
- : unit = ()

サンプルプログラム

open Core.Std

let () =
  let module C = Curses in
  let main_window = C.initscr () in
  let err = C.mvwaddstr main_window 10 2 "hello, world!" in
  let err = C.mvwaddstr main_window 11 2 "こんにちは、世界!" in
  let err = C.refresh () in
  Unix.sleep 5;
  C.endwin ()

文字化けせずに、「こんにちは、世界!」を表示できた。
 

参考