el-getをWindows環境で利用するにあたってハマった点

最近巷では、el-get というパケージ管理ツールが流行っているようなので流行に乗らなければ!と思い導入してみました。
Windowsでel-getを動かせるようになるのに結構ハマったので、自分と同じ境遇にいる人は少しは参考になるかも。
てかWindowsemacsを利用するのは地雷原が多すぎる。マインスイーパやってるみたいでした。

導入環境は、Windowsで以下のとおり。

基本的にはGitHub - dimitri/el-get: Manage the external elisp bits and pieces upon which you depend!に記載がある通り以下を評価してあげればインストールまで勝手に進むのですが

;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working developper edition of el-get.
(url-retrieve
 "https://raw.github.com/dimitri/el-get/master/el-get-install.el"
 (lambda (s)
   (let (el-get-master-branch)
     (goto-char (point-max))
     (eval-print-last-sexp))))

Windowsでは以下の問題が発生してそのままではインストールができませんでした。

Windowsで発生した問題
  1. install-infoでコケる
  2. el-getのbyte-compileが始まらない
  3. error setting certificate verify locations が発生してgit cloneできない
  4. M-x emacswiki-refresh すると何時まで経っても終わらない

回避方法

install-infoでコケる

Readme.mdに対処方法が書いてあります。

When using the windows operating system, take into account that the way Emacs calls external programs is not the same for native builds and cygwin, so make sure you don't mix and match them at least for install-info (e.g. cygwin version of install-info will error out when called by el-get from a windows-nt Emacs, see system-type). When using a native build of Emacs for windows, consider using the GNU Win 32 distribution of TexInfo for windows, which contains the proper install-info version when you're not using the cygwin Emacs binary.

意訳すると cygwin の install-info は利用できないので GNU Win 32 のバイナリ使ってね。ということらしい。

早速、cygwinのinstall-infoを利用しないように

$ mv /usr/bin/install-info.exe{,_}

してリネームします。

TexInfo for Windows の「Download」から

  • Binaries
  • Dependencies

のzipアーカイブを落としてきて解凍しPATHを通します。
~/bin下に展開したと場合、
~/bin/GnuWin32/bin
のパスを通せばOK.
これで、GNUWin32のinstall-infoが利用されるようになります。

el-getのbyte-compileが始まらない

これは自分の環境だけの問題かもしれませんが、一応書いておきます。

結論からいうと
http://dev.ariel-networks.com/articles/emacs/part1/
lgrepの設定を書いてあると問題が発生します。以下のコードを書いている人は要注意。

Windows環境の場合,上記のままではうまく動きません.以下のように設定する事でこの問題を回避できます.
======================
;; shell-quote-argumentの問題回避
(defvar quote-argument-for-windows-p t "enables `shell-quote-argument' workaround for windows.")
(defadvice shell-quote-argument (around shell-quote-argument-for-win activate)
  "workaround for windows."
  (if quote-argument-for-windows-p
      (let ((argument (ad-get-arg 0)))
        (setq argument (replace-regexp-in-string "\\\\" "\\\\" argument nil t))
        (setq argument (replace-regexp-in-string "'" "'\\''" argument nil t))
        (setq ad-return-value (concat "'" argument "'")))
      ad-do-it))

;; lgrep で Shift_JIS を使うように設定
(setq grep-host-defaults-alist nil) ;; これはおまじないだと思ってください
(setq grep-template "lgrep -Ks -Os <C> -n <R> <F> <N>")
(setq grep-find-template "find . <X> -type f <F> -print0 | xargs -0 -e lgrep -Ks -Os <C> -n <R> <N>")
====================== 

理由は、shell-quote-argument の挙動を変更してしまっているからです。
el-getは、call-process-shell-command でemacsを起動してbyte-compileしますが
引数はshell-quote-argument でQuote化された結果が渡されるため、emacsが引数を
ファイル名と捉え間違えてしまいbyte-compileが実行されません。

shell-quote-argument の挙動を元に戻して、かつ(setq w32-quote-process-args t)をしてあげるか、
以下のようにel-getの場合だけ元の挙動をするように変更してあれば問題ありません。

(setq w32-quote-process-args t)

;; shell-quote-argumentの問題回避
(defvar quote-argument-for-windows-p t "enables `shell-quote-argument' workaround for windows.")
(defadvice shell-quote-argument (around shell-quote-argument-for-win activate)
  "workaround for windows."
  (if (and quote-argument-for-windows-p
           (not (w32-shell-dos-semantics))) ;;el-get利用時の場合は無効にするための判定
      (let ((argument (ad-get-arg 0)))
        (setq argument (replace-regexp-in-string "\\\\" "\\\\" argument nil t))
        (setq argument (replace-regexp-in-string "'" "'\\''" argument nil t))
        (setq ad-return-value (concat "'" argument "'")))
      ad-do-it))

el-getは、Windowsの場合shell-file-nameを"cmdproxy"に変更してcall-process-shell-commandを叩くようなので
(w32-shell-dos-semantics)の挙動を利用して通る経路を変えています。

error setting certificate verify locations が発生してgit cloneできない

「error setting certificate verify locations」とかいうエラーが出た場合は
以下のようにパッケージをインストールすれば問題が解決します。

$ cyg-pm install -require ca-certificates
M-x emacswiki-refresh すると何時まで経っても終わらない

el-get インストール完了後に M-x emacswiki-refresh するとCPUがぶんまわりはじめて延々終わらない現象になります。
どうも既知の問題だそうです。

Cannot refresh emacswiki recipes (Windows) · Issue #569 · dimitri/el-get · GitHub

対処方法は
Support in-process emacswiki-refresh with prefix arg by DarwinAwardWinner · Pull Request #570 · dimitri/el-get · GitHub
に書いてあるとおり、emacswiki-refresh を引数ありで呼べということのようです。

C-u M-x emacswiki-refresh

別プロセスで動かす場合に問題になるようで、引数ありで呼び出す場合は同プロセス(in-process)上で動作する挙動になるため問題が回避できるようです。

まとめ

el-getで問題が起きた場合の着眼点を書いておきます。

  • readmeは読んだか?
  • issueに似た現象が起票されていないか?
  • shell-quote-argument の挙動を変えていたりしないか
  • WindowsLinuxでの挙動の違う点で問題が起きていないか?
    • shellの挙動や外部プログラム実行時に渡す引数に問題ないか