2014-05-29

VirtualBoxにWindows8.1 Updateを入れた

PCを増やして配線を色々いじるのが面倒だったので、VirtualBoxにWindows8.1 Updateを入れることにした。

幸いVirtualBoxの方ではすでに8.1に対応済みで、ゲストOSの種類として8ではなく8.1を指定すれば問題なくインストールできた(間違えて8を選んだらエラーが出て進まなかった。あとBIOS設定でIntel VTを有効にしておくこと)。

初期ユーザはローカルアカウントで作った。Microsoftアカウントで初期ユーザーを作ってしまうと、ユーザ名やユーザフォルダ名が汚らしいものになってしまうので。しかし8.1では8にはあった「Microsoftアカウントを使わずにサインインする」が最初の選択肢に表示されなくなっている。しかし諦めるべからず。「新しいアカウントを作る」を選択して「Microsoftアカウントの作成」の画面に行くと、下の方に「Microsoftアカウントを使わずにサインインする」という項目があるのでそれを選ぶべし。他にもネット接続を切ってインストールしたり、サインインにわざと失敗すると、この選択肢が出てくるらしい。なぜ最初からこの選択肢を出さないのか。

インストールが終わって再起動し、サインインすると、いきなりデスクトップが現れた。スタートスクリーンではない。よく分かっているじゃないか。

Windows8といえばスタートメニューの問題が有名だ。私はスタートメニューをキーボードで操作できるランチャーとして使用していたので、無くなるとやはり不便だ。下手なショートカットキーに割り当てるとEmacs等に支障を来すのでやりたくない(デスクトップに置いたアイコンのプロパティからCtrl+Alt+?が割り当てられるが、この組み合わせはEmacsでよく使う)。スタートメニューが無くなったのなら何か代わりになるランチャーでも探そうかなと思ったのだが、スタートメニューを復活させるアプリもいくつかあると聞いていたので、それを探してみた。

Windows8 でスタートメニューを取り戻す方法 - NAVER まとめ

なんか沢山あるみたい。結局どれが良いんだろう。海外の誰が作ったか分からないようなアプリをホイホイ入れるのも少し心配な昨今(今更だけど)。

秀丸スタートメニューにした。うん、私の用途ではこれで十分だ。

2014-05-09

OpenFlを使ってみる

NMEからOpenFlになってずいぶん経ちますが、久しぶりに使ってみようと思いました。

OpenFlの使い方

インストール

OpenFlのサイト 右上にあるDownloadを選択して指示に従ってインストールすればOK。
Haxe、Lime、OpenFLの順にインストールする。

直接ダウンロードするのはhaxeのインストーラだけ。後はhaxelib経由でダウンロード&インストールできる。

プロジェクトの作成

lime.bat create openfl:project ExampleProject

ExampleProjectは適切なプロジェクト名を入れる。
生成されたExampleProject.hxprojやproject.xmlを適切に修正する。com.exampleやCompany Nameと書いてある部分を適切な物に変える。

ソースコードの修正

試しに画面を余白10px空けて赤く塗りつぶしてみる。Source/Main.hxを次のようにする。

package;

import flash.display.Sprite;

class Main extends Sprite {
    public function new () {
        super ();

        graphics.beginFill(0xff0000, 1.0);
        graphics.drawRect(10, 10, stage.stageWidth-20, stage.stageHeight-20);
        graphics.endFill();
    }
}

ビルド

lime.bat build html5 とか lime.bat build flash とか。

(Cygwinのmakeから実行したいので.batを付けている)

実行

html5なら cygstart Export/html5/bin/index.html とか。

flashなら cygstart Export/flash/bin/ExampleProject.swf とか。

(cygstartは引数で指定されたファイルをWindowsで関連づけられたアプリケーションで開くCygwinのコマンド)

リサイズ対応

Webブラウザでhtml5を表示したにせよデスクトップのFlashプレイヤーでswfを実行したにせよ、ウィンドウサイズを変更したときに右端や下端の余白が10pxで無くなってしまいます。
なので、リサイズされたらグラフィックスを変更するようにします。

package;

import flash.display.Sprite;
import flash.events.Event;

class Main extends Sprite {
    public function new () {
        super ();

        resize();

        stage.addEventListener(Event.RESIZE, function(e:Event){resize();});
    }

    function resize():Void
    {
        // stage.stageWidth, stage.stageHeight変更直後の処理を書く。
        updateBackground();
    }

    function updateBackground():Void
    {
        graphics.clear();
        graphics.beginFill(0xff0000, 1.0);
        graphics.drawRect(10, 10, stage.stageWidth-20, stage.stageHeight-20);
        graphics.endFill();
    }
}

(アニメーション)フレーム毎の処理

試しに赤いボールを画面端でバウンドさせながら移動させてみる(超適当)。

package;

import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;

class Main extends Sprite {
    public function new () {
        super ();

        // ボールを作る。
        var ballShape = new Shape();
        ballShape.graphics.beginFill(0xff0000, 1.0);
        ballShape.graphics.drawCircle(0,0,16);
        ballShape.graphics.endFill();
        addChild(ballShape);

        var ball = {
            x:100, y:100, vx:4, vy:4, shape:ballShape
        };

        // フレーム毎に移動させる。
        addEventListener(Event.ENTER_FRAME, function(e:Event){
            ball.x += ball.vx;
            ball.y += ball.vy;
            if(ball.x > stage.stageWidth){
                ball.x = stage.stageWidth;
                ball.vx = -ball.vx;
            }
            if(ball.y > stage.stageHeight){
                ball.y = stage.stageHeight;
                ball.vy = -ball.vy;
            }
            if(ball.x < 0){
                ball.x = 0;
                ball.vx = -ball.vx;
            }
            if(ball.y < 0){
                ball.y = 0;
                ball.vy = -ball.vy;
            }
            ball.shape.x = ball.x;
            ball.shape.y = ball.y;
        });
    }
}

(赤いボールはグラデーションで影を付けたかったのだけど、html5版のGraphics.beginGradientFillはまだ実装されていなかった)

2014-04-20

2014-04春の新番組

ようやく一通り見終わりました。キツイ。多すぎ。忙しすぎ。

  • × カリーノ・コニ
  • △ Blade&Soul -ブレイドアンドソウル-
  • ○ 僕らはみんな河合荘
  • ○ 蟲師 続章 (前期)
  • △ selector infected WIXOSS
  • △ 悪魔のリドル
  • × レディ ジュエルペット (第6期)
  • △ 魔法科高校の劣等生
  • △ 神々の悪戯
  • △ 金色のコルダ Blue♪Sky
  • ○+ それでも世界は美しい
  • △ ハイキュー!!
  • ○+ ベイビーステップ
  • △ 極黒のブリュンヒルデ
  • × 召ませロードス島戦記それっておいしいの?
  • × ブレイクブレイド
  • △ キャプテン・アース
  • ○ 一週間フレンズ。
  • × 星刻の竜騎士
  • ○ マンガ家さんとアシスタントさんと
  • × DIABOLIK LOVERS
  • △ ブラック・ブレット
  • △- 史上最強の弟子ケンイチ OVAシリーズ
  • △ ソウルイーターノット!
  • × 魔法少女大戦
  • △ ノーゲーム・ノーライフ
  • △ 棺姫のチャイカ
  • △ 風雲維新ダイショーグン
  • × エスカ&ロジーのアトリエ~黄昏の空の錬金術士~
  • ○ ご注文はうさぎですか?
  • ◎ ピンポン THE ANIMATION
  • × 龍ヶ嬢七々々の埋蔵金
  • ○ シドニアの騎士

一押しはピンポンですね。普通に面白い。

蟲師はそこそこですね。1話完結で話毎に善し悪しはありそうですが、今後面白い話はありそう。

ベイビーステップはテニスものですが、話の流れがスムーズですし、主人公の性格も面白いですね。

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-03-01

Windowsのel-getで非同期インストールがエラーになる

el-getをインストールしたので、Wanderlustをel-getでインストールしようとしたらエラーになりました。

次のエラーメッセージが出ました。(gnupack emacs-24.3-20130503 / el-get version 5.1.1dce781)

el-get install apel
el-get: Package apel installed.
el-get: git submodule update ok
el-get: el-get-build apel: c:/app/emacs-24.3-20130503/bin/emacs -batch -q -no-site-file -l APEL-MK -f compile-apel prefix site-lisp site-lisp ok.
el-get: el-get-build apel: c:/app/emacs-24.3-20130503/bin/emacs -batch -q -no-site-file -l APEL-MK -f install-apel prefix site-lisp site-lisp ok.
apel failed to install: (error process byte-compile no longer connected to pipe; closed it) [2 times]
el-get-installation-failed: process byte-compile no longer connected to pipe; closed it

(el-get 'sync 'wanderlust)を評価して同期でインストールしようとするとこのエラーは出ないようなので(別のエラーは出るw)、非同期の時だけの問題のようです。

原因

結論から言うと shell-file-name が "cmdproxy.exe" になっていないことが原因です。
el-getはwindows-ntで実行しているとき、shell-file-nameを強制的に "cmdproxy.exe" に変更してからプロセス呼び出しを行うようになっています。
ただ、この処理がel-get-build関数内にしかないのが問題です。

el-get-build関数は非同期の時、ビルドの完了を待たずに終了します。el-get-build関数内ででいくら

(let* (...略...
       (shell-file-name (or (and (eq system-type 'windows-nt)
                                 (executable-find "cmdproxy.exe"))
                            shell-file-name))
       ...略...)
  ...処理の本体...

のようなコードを書いても、非同期で実行される後続のプロセス呼び出しには適用されません。

shell-file-name が"cmdproxy.exe"でないと、 shell-quote-argument がWindowsのドライブレターを含むパスを正しくクォートできません。
"C:/home/hoge.el"みたいなパスを"C\:/home/hoge.el"のようにしてしまいます。
結果、サブプロセスで呼ばれるemacsは引数で渡されたファイル名を開けずに異常終了します。
そうすると、上のエラーのように、プロセスとパイプがつながらないよ!ということになります。

対策

el-getがサブプロセスを起動するときは必ず shell-file-name が"cmdproxy.exe"になるようにします。

まず、 el-get で使用する shell-file-name を次のようにして決めます。

;;; el-getが使用するshell-file-nameを決める。
;;; el-get-build内(el-get version 5.1.1dce781)で似たような判定をしているが、
;;; その関数内だけでは不十分。
(setq my-el-get-shell-file-name
   (or (and (eq system-type 'windows-nt)
            (executable-find "cmdproxy.exe"))
       shell-file-name))

そして、 el-get-start-process-list 関数を実行するときは、必ずその決めた shell-file-name を使うようにします。

;;; プロセスを呼び出す前に my-el-get-shell-file-name を適用する。
;;;
;;; el-get-build内(el-get version 5.1.1dce781)で同じような処理をしているが、
;;; それでは不十分。非同期インストールの時はel-get-build関数は処理の完了を
;;; 待たずに終わってしまうので。
(defadvice el-get-start-process-list (around my-el-get-start-process-list--modify-shell-file-name activate)
  (let ((shell-file-name my-el-get-shell-file-name))
    ad-do-it))

el-get-start-process-list 関数内でコマンドライン引数に shell-quote-argument が適用されています。
shell-quote-argument は shell-file-name の値によって動作が変わるので、
この関数の中を実行しているときだけ shell-file-name が"cmdproxy.exe"になっていればOKです。

(setq el-get-verbose t) で詳細を表示するようにして、 :args 部分のパスに問題が無ければOKです。

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 のワークフローについて整理する - そんなこと覚えてない)

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

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