Mac OS X での Emacs (2)

以前の記事 で書いた通り、私は Emacs を使い始めてから現在まで銭谷版 Carbon Emacs パーケージ を使用している。とても安定しており、複雑なフォントの設定も carbon-font.el を使用すれば手軽に理想的な設定が可能となる。Mac OS X のインプットメソッドが利用できることをはじめ、他にも dired-mode で Space キーによって Quick Look が起動したり、Ctrl + Cmd + D でアップルの辞書がポップアップで引けたり、印刷コマンド (M-x print-buffer など) で Mac のプリントダイアログが開いたり、たくさんの Mac と連携した便利な機能が利用できる。しかし、この Carbon Emacs パッケージは残念ながら 2010-01-15 版 (ver. 22.3.1) を最終版としていて、Cocoa Emacs (ver. 23) への移行は考えられていないとのことである。

一方で、Emacs 23 は 2009/07/29 に Cocoa 化された初めてのバージョンが出て以来、もう二年以上も経つ。現在 (2011/08/7) の安定版は 23.3 であり、最新のパッケージでは Emacs 23 での使用が想定されていることも珍しくない。私は Emacs をプログラマのように酷使するわけではないが、それでも Emacs 23 を Mac OS X 上で使いたい時が出てきて、その時は X11 版 (Macports) か、ftp://ftp.math.s.chiba-u.ac.jp/emacs/ で公開されているパッチを適用したものを使用している。後者の Emacs Mac port は 64bit にも対応し、上記の Carbon Emacs の機能はデフォルトのままかあるいは簡単な設定で利用できる (導入は こちらの記事 を参照)。

辞書.app に関しては特になにも設定しなくても Ctrl + Cmd + D で、

https://skalldan.files.wordpress.com/2011/08/wpid-emacs_dict.png

というように Emacs 内で意味がポップアップ表示される。

印刷を Carbon Emacs のようにダイアログボックスを表示させて行うには MacPrintMode にあるように必要なパッケージを導入し、

(when (require 'mac-print-mode nil t)
  (mac-print-mode 1)
  ;;  (global-set-key (kbd "M-p") 'mac-print-buffer)
  )

と設定ファイルに書いておくことで可能となる。

Dired Mode で Quick Look を使用するには幾つか方法があるが、私は こちら の記事の通りに、

(defun my-dired-do-quicklook ()
  "In dired, preview with Quick Look."
  (interactive)
  (let ((file (dired-get-filename))
        (process (get-process "qlmanage_ps")))
    (if process
        (kill-process process)
      (start-process "qlmanage_ps" nil "qlmanage" "-p" file))))

(add-hook 'dired-mode-hook
          '(lambda ()
             (define-key dired-mode-map (kbd "SPC") 'my-dired-do-quicklook)
             ))

と設定している。

また、ピクセル単位のスムーズなスクロールに対応していることに加え、Mac のトラックパッドジェスチャーを認識してくれる。すなわち、他のアプリケーションでのように二本指でのピンチオープン/クローズなどの操作を受け付けてくれるようになる。これによってキーバインドの設定の幅も広がり、例えば、

(define-key w3m-mode-map [swipe-right] 'w3m-view-next-page)
(define-key w3m-mode-map [swipe-left] 'w3m-view-previous-page)

のようにトラックパッドでの操作を追加できるようになる (例は emacs-w3m での三本指スワイプでのページ移動)。

また、多言語フォント表示に関しても、設定ファイル (~/.emacs.d/init.el) を読みこまない状態で Emacs の Hello ファイルにある言語がすべて文字化けしていない。もちろんフォントが入っていることが前提である (インド系文字についは このあたり を参照)。

M-x view-hello-file の結果は以下のようである。

https://skalldan.files.wordpress.com/2011/08/wpid-hello_emacs_def2.png

英数フォントを変更したいだけであれば、

(set-face-attribute 'default nil
                    :family "Menlo"
                    :height 140)

と言うようにシンプルな設定で済む。フォントの確認には M-x mac-font-panel-mode を実行すると良いかも知れない。ある文字にカーソルを合わせ M-x describe-char を実行するとその文字の情報が表示される。また、

(insert (prin1-to-string (x-list-fonts "*")))

を評価することで使用できるフォント一覧が得られる。Anything を使用していれば M-x anything-select-xfont でフォントを選択できる (C-z で anything のセッションを抜けずに一時的に変更)。また、文字集合の一覧は M-x list-character-sets で、japanese-jisx0208 等のそれぞれの集合の文字一覧は M-x list-charset-chars を実行することで得られる。

私は英数フォントに加え、文字幅を調節するため次のような設定を行っている。

(setq face-font-rescale-alist
      '((".*Hiragino Kaku Gothic ProN.*" . 1.2)
        (".*LiHei Pro.*" . 1.2)
        (".*Heiti SC.*" . 1.2)
        (".*Arial Unicode MS.*" . 1.2)
        (".*Devanagari MT.*" . 1.3)
        (".*Kailasa.*" . 1.4)
        ))

この設定で、表示は次のようになっている。

https://skalldan.files.wordpress.com/2011/09/wpid-moji_haba_3.png

專門分野との関連でデーヴァナーガリー文字 (サンスクリット語) やチベット文字を入力する必要があり、それらの文字幅を見やすいように若干大きめに設定している。個人的にはこれくらいが好みだが、もう少し小さくても良いかも知れない。

ただ、デーヴァナーガリー文字のある文字に関してはうまく表示できていない。例えばデーヴァナーガリー文字「श्रि」を含むファイルを開くと以下のスクリーンショットのようにひどいことになる。

https://skalldan.files.wordpress.com/2011/08/wpid-dev_shri1.png

直接「श्रि」を入力するとフリーズする。デーヴァナーガリーのフォントを Lohit HindiSanskrit 2003Chandas などに変更してみたが、今度は正しく表示されない (以下は Chandas に設定した場合)。

https://skalldan.files.wordpress.com/2011/08/wpid-dev_shri_21.png

母音の「ि」が子音の左に来る、といったレンダリングの規則が適用されていない。慣れれば読めなくもないが、出来れば正しく表示して欲しい。おそらく Mac 特有の現象だと思うが (cf. AAT for Indic scripts)、解決のためにどこをどう見ていいか全く分からない。もしどなたか思い当たるふしがあればご教示いただければうれしいです。

【追記 2011/08/09】

Mac port 作者の山本光晴氏に上記のデーヴァナーガリーのレンダリングについてご報告したところ、すぐに以下のパッチで対処して下さった。

=== modified file 'src/macfont.c'
*** src/macfont.c   2011-08-07 00:35:10 +0000
--- src/macfont.c   2011-08-09 05:58:54 +0000
***************
*** 3103,3114 ****
    if (used <= glyph_len)
      {
        CFArrayRef ctruns = CTLineGetGlyphRuns (ctline);
!       CFIndex i, j, k, ctrun_count = CFArrayGetCount (ctruns);
        CFRange comp_range = CFRangeMake (0, 0);
!       CGFloat total_advance = 0, comp_offset;

!       comp_offset = CTLineGetOffsetForStringIndex (ctline, 0, NULL);
!       for (i = j = k = 0; k < ctrun_count; k++)
    {
      CTRunRef ctrun = CFArrayGetValueAtIndex (ctruns, k);
      CFIndex glyph_count = CTRunGetGlyphCount (ctrun);
--- 3103,3113 ----
    if (used <= glyph_len)
      {
        CFArrayRef ctruns = CTLineGetGlyphRuns (ctline);
!       CFIndex i, k, ctrun_count = CFArrayGetCount (ctruns);
        CFRange comp_range = CFRangeMake (0, 0);
!       CGFloat total_advance = 0;

!       for (i = k = 0; k < ctrun_count; k++)
    {
      CTRunRef ctrun = CFArrayGetValueAtIndex (ctruns, k);
      CFIndex glyph_count = CTRunGetGlyphCount (ctrun);
***************
*** 3118,3144 ****
           range.location++, i++)
        {
          CFIndex index;
-         CGFloat offset;
          CGPoint position;

          CTRunGetStringIndices (ctrun, range, &index);
!         offset = CTLineGetOffsetForStringIndex (ctline, index, NULL);
!         if (offset != comp_offset)
        {
!         CGPoint pos = CGPointMake (offset, 0);

!         /* Glyph indices are not always increasing in a
!            composed character (e.g., the first one of
!            "Hindi" in its native name).  */
!         comp_range.length =
!           (CTLineGetStringIndexForPosition (ctline, pos)
!            - comp_range.location);
!         for (; j < i; j++)
!           glyph_layouts[j].comp_range = comp_range;
!         comp_range.location += comp_range.length;
!         comp_offset = offset;
        }

          glyph_layouts[i].string_index = index;
          CTRunGetGlyphs (ctrun, range, &glyph_layouts[i].glyph_id);

--- 3117,3136 ----
           range.location++, i++)
        {
          CFIndex index;
          CGPoint position;

          CTRunGetStringIndices (ctrun, range, &index);
!         if (index >= comp_range.location + comp_range.length)
        {
!         CFRange new_range =
!           CFStringGetRangeOfComposedCharactersAtIndex (string, index);

!         comp_range.location = comp_range.location + comp_range.length;
!         comp_range.length = (new_range.location + new_range.length
!                      - comp_range.location);
        }

+         glyph_layouts[i].comp_range = comp_range;
          glyph_layouts[i].string_index = index;
          CTRunGetGlyphs (ctrun, range, &glyph_layouts[i].glyph_id);

***************
*** 3150,3158 ****
          total_advance += glyph_layouts[i].advance;
        }
    }
-       comp_range.length = CFStringGetLength (string) - comp_range.location;
-       for (; j < i; j++)
-   glyph_layouts[j].comp_range = comp_range;

        result = used;
      }
--- 3142,3147 ----

このパッチを適用すれば、Mac OS X (10.6) で先に言及したフォント Devanagari MT でも問題なく表示されるようになった。すばらしい。この場を借りて (といっても御覧になることはないだろうが…) 御礼申し上げます。

https://skalldan.files.wordpress.com/2011/08/wpid-dev_shri_3.png

なお、私自身はまだ移行していないが、Mac OS X 10.7 では フォント Chandas でも Mac port でデーヴァナーカリー文字の composition が正しく行われるようである。

【追記 2011/08/28】

Mac port emacs-23.3a-mac-1.9995.tar.gz (11/08/27) では上記の Devanāgarī 文字表示のための修正は取り込まれている。

関連記事

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s