Category Archives: 未分類

2014-03-01

gitをautocrlf=trueで使っているとel-getでWanderlustがインストールできない

el-getをインストールし、el-get-installでapelのインストールから先に進まない問題を解決したのですが、今度は次のようなエラーが出ました。

Generating autoloads for wanderlust/site-lisp/wl/wl-highlight.el...done
Generating autoloads for wanderlust/site-lisp/wl/wl-mailto.el...done
Generating autoloads for wanderlust/site-lisp/wl/wl-message.el...done
Generating autoloads for wanderlust/site-lisp/wl/wl-mime.el...done
wanderlust failed to install: (error Local variables entry is missing the suffix)
el-get-installation-failed: Local variables entry is missing the suffix

なんのこっちゃい。

原因

wl-mime.elの後くらいでエラーになっていたので、その後のファイルを見て原因が分かりました。

例えばwl-news.elの先頭は次のようになっています。

;;; wl-news.el --- Create notification from NEWS(.ja) for Wanderlust. -*-coding: iso-2022-jp-unix;-*-

;; Copyright (C) 2002 Yoichi NAKAYAMA

coding-systemがunix。つまり、改行コードがLFと指定されているのです。
でも私は普段Windows環境ではgitをcore.autocrlf=trueにして使用しています。
リポジトリにはLFで保存されるが、ワーキングコピーはCRLFになるようにしているのです。
つまり、このwl-news.elはCRLFになっているのです。
どうもヘッダーではunix(LF)と書いてあるのに、実際のファイルはdos(CRLF)なのでエラーが出るようなのです。

対策

普段 core.autocrlf=true にしているのには訳があります。なので、 git config --global core.autocrlf false にするのは却下です。

ワーキングコピーのローカルでgit configしようにも、el-getがこれからcloneしようとしているファイルに対しては意味がありません。

git cloneするときに、最初から git config core.autocrlf false の状態になるような方法を探したのですが、良い方法は見つかりませんでした。

ただ、 git -c core.autocrlf=false のようにオプションで指定してやれば、cloneして取り出したファイルはunix(LF)になりました。
残念ながらローカルなconfigにこのオプションは反映されません。
なので、毎回オプションをつけてgitを呼び出す必要があります。

つまり、el-getがgitを呼び出すときに、強制的にargsに("-c" "core.autocrlf=false")を付加してやれば良いわけです。

el-getでは、呼び出すコマンド列は全てリスト化されてまとめて el-get-start-process-list に渡されます(たぶん非同期対応のためだと思います)。

なので、 el-get-start-process-list に渡されるそのリスト(commands)の中に、:programがgitのものを見つけ出し、その:argsの先頭に("-c" "core.autocrlf=false")を付加します。

;;; el-getがgitを呼び出すとき、 -c core.autocrlf=false 引数を付加する。
;;; wanderlustがLF改行でなければバイトコンパイルに失敗するので。
;;;
;;; 普段autocrlf=trueでgitを使っているので、gitのglobal configを変えたくない。
;;;
;;; 注意: cloneしたワーキングコピーのconfigにこの設定は反映されない。
;;;       el-get以外から直接 ~/.emacs.d/el-get/ にあるワーキングコピーを
;;;       gitで操作しようとすると、問題が起きる場合があるので注意すること。
;;;       そのようなことをする前に git config で明示的に設定すると良いと思う。
(defadvice el-get-start-process-list (around my-el-get-start-process-list--modify-git-args activate)
  (let* ((commands (ad-get-arg 1))
         (git-executable (el-get-executable-find "git"))
         (new-commands
          (loop for c in commands collect
                (if (string= (plist-get c :program) git-executable)
                    ;; gitならargsプロパティに -c core.autocrlf=falseをつける。
                    ;; @todo 破壊的だけどOK?
                    (plist-put c :args (append '("-c" "core.autocrlf=false") (plist-get c :args)))
                  ;; gitでないならそのまま
                  c))))
    (ad-set-arg 1 new-commands)
    ad-do-it))

これで無事にWanderlustがバイトコンパイルできるようになりました。
……これだからel-getは使いたくなかったんだ。

その他の解決策

git -c core.autocrlf=false %* という内容のgit-lf.batを作って、それをel-getに使わせる(el-get-git-executableを書き換える)という方法もあります。

その他のトラブル

gitは空白が無いパスに入れた方が無難かも?(詳しく確認してないがverboseで追っているときに、checksumのところでProgram Filesがらみの変なエラーメッセージを見たことがある)

2014-02-28

URLとタイトルのコピー

皆さんは開いているWebページのURLやタイトルをコピーする時ってどうしてます?

URLはロケーションバーからコピーすれば良いとして、問題はタイトルです。

私は普段Firefoxを使っているので、ページの上で右クリック→「ページの情報を表示」を選んで、タイトルを範囲選択してコピーしていました。
そしてテキストエディタにペーストしてから書式を整える。

面倒くさい。

今日もその作業をしていたときに、ふとブックマークレットにすれば良いんじゃね? と思いついてやってみました。

javascript:alert("%20%20[["+document.URL+"]["+document.title+"]]");

「ブックマークの追加」を選んで、名前を「URLをorg形式で表示」とし、URLのところに上を打ち込みます。
このブックマークを開こうとすると、現在開いているページのURLとタイトルをEmacs org-modeのリンク書式で表示してくれるというわけです。
ちなみに、先頭の%20%20はalertダイアログで範囲選択しやすくするために追加した空白です。

これだと範囲選択してコピー操作する面倒は残ります。
Firefoxのaddonならクリップボードへのコピーまで出来るのだろうなー、と思ったところで、
ひょっとしたらFirefox用のAddonがあるんじゃないかと思い至りました。

「copy url firefox」で検索してみると、次のものが。

Copy Urls Expert :: Add-ons for Firefox

書式設定まで出来る! 完璧です。

2014-02-28

今更ながらel-getを使い始めてみた

org-modeやらmagitやらWanderlustやら、Emacs Lispを最新版へ更新するのが億劫になってきたのでEmacsのパッケージ管理システムを検討してみました。

Emacs24からはpackage.elというのが標準で使えるようになったそうで、package-list-packagesでいきなりパッケージのリストが表示されるというお手軽さなのです。
でも、このシステムはパッケージのリポジトリへの登録にハードルがあるらしく、扱えるパッケージに限りがあるようなのです(参考:elispをpackageとel-get両方で管理する - $shibayu36->blog;)。

なので、el-getを試してみることにしました。公式サイトは dimitri/el-get です。

インストールは簡単で、scratchバッファなどから次のelispを実行するだけ。

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

のはずだったのですが、Windows上でgnupackのemacs-24.3-20130503を使っていると落ちます。強制終了です。
どうも、httpsから任意のページをurl-retrieveしようとしただけで落ちるみたいです。
Emacs内部に組み込まれたgnutls、実際にはlibgnutls-28.dll内で問題が起きるようです。
解決方法は elpa形式じゃない野良elispをpackage-installする #Emacs @robario cookieswap補助、gist.el、ちょっとtombloo - うぇぶとらばぁす にありました。

(eval-after-load
  "gnutls"
  '(setq gnutls-trustfiles (mapcar 'expand-file-name gnutls-trustfiles)))

gnutlsが読み込まれる前に上を実行しておけば(.emacsのel-getの設定等より先に書いておけば)落ちなくなりました。
どうもlibgnutls-28.dllがcygwin的なパスを認識できないことが原因のようです。expand-file-nameを通すことでWindows形式の絶対パスに展開され、落ちなくなるようです。

というわけで、無事にインストールできました。el-get-list-packageでパッケージの一覧を見ることが出来ます。iでマークしてxでインストールできます。

公式の Basic Setup のところに書いていますが、.emacsは次のようにすると良いみたいですね。

(add-to-list 'load-path "~/.emacs.d/el-get/el-get")

(unless (require 'el-get nil 'noerror)
  (with-current-buffer
      (url-retrieve-synchronously
       "https://raw.github.com/dimitri/el-get/master/el-get-install.el")
    (goto-char (point-max))
    (eval-print-last-sexp)))

(add-to-list 'el-get-recipe-path "~/.emacs.d/el-get-user/recipes")
(el-get 'sync)

こうすると、el-getがインストールされていなければ自動的にインストールされます。
.emacsをバージョン管理して他のマシンと共有している場合は便利ですね。

.emacsを共有している他のマシンにも同じパッケージを自動的にインストールしたいことがあると思います。
そういう場合は、

(el-get 'sync
  'color-moccur
  'magit
)

のように'syncの後にパッケージ名を書いておくと良いみたいです。(参考: 自分の el-get のワークフローについて整理する - そんなこと覚えてない)