git-gutter.elを更新しました

Sublime Text2のプラグイン GitGutterEmacs版 git-gutter.elを更新しました。

インストール

MELPAと el-getに pull requestを送りましたんで、いずれそれらから
インストールできるようになるかと思います。MELPAはマージされたん
ですが、Webアプリの調子が悪いのか、package-listを更新しても
出て来ませんね。まあそのうちなんとかなるでしょう。

追記

2013年 1月 24日 MELPAに登録されていることが確認できたので、
package-installコマンドからインストールすることができます。

インタフェースの追加

  • git-gutter:clear
  • git-gutter:toggle

差分情報を表示する git-gutter関数だけ提供していたのですが、
画面をクリアするための git-gutter:clearと表示・非表示を交互に
行う git-gutter:toggleを追加しました

差分の印に複数文字が指定可能に

'+'とか '-'の 1文字しか指定できなかったのですが、複数文字を
設定できるようにしました。

複数文字に設定する

以下のように設定します。

(setq git-gutter:modified-sign "  ") ;; two space
(setq git-gutter:added-sign "++")    ;; multiple character is OK
(setq git-gutter:deleted-sign "--")

(set-face-background 'git-gutter:modified "purple")
(set-face-foreground 'git-gutter:added "green")
(set-face-foreground 'git-gutter:deleted "red")

上記の設定でのスクリーンショットは以下のようになります。

(注意)全角文字を設定する場合

Emacsには char-widthという文字幅を求める関数があり、
一部の全角文字は正しく判定されるのですが、誤って判定される
文字もあります。そのため、全角文字を設定する場合は、明示的に
その文字の長さを指定してください。modified, added, deletedの
中の最長のものを指定すれば良いです。


正しく設定することで絵文字的なものも利用することが可能です。

(setq git-gutter:window-width 2)
;; HTMLエスケープされてますが、実際は絵文字 
(setq git-gutter:modified-sign "❄")
(setq git-gutter:added-sign "☀")
(setq git-gutter:deleted-sign "☂")

(set-face-foreground 'git-gutter:modified "white")
(set-face-foreground 'git-gutter:added "orange")
(set-face-foreground 'git-gutter:deleted "cyan")


おわりに

気になった方はぜひ使ってみてください。
問題があれば githubの issuesまでお願いします。

rm -rf symlink/して不幸になりたくなければ unlinkを使えばいい

シンボリックリンクをrm -rf symlink/すると不幸になる - かーねる・う゛いえむにっき


ですが、ディレクトリを消してしまうというリスクをそもそもなくして
しまえばいいですよね。その答えが unlinkコマンドです。

unlinkコマンド

ファイルだけ消せる rmコマンドのように思っていただければよいかと
思います。ディレクトリは消せません。オプションもほとんどありません。
coreutilsだと rmとソースは違いますが、FreeBSDだと rmのハードリンクです。


ついでにソースは以下のような感じでした。(FreeBSDの bin/rm/rm.cより抜粋)

        if (strcmp(p, "unlink") == 0) {
                while (getopt(argc, argv, "") != -1)
                        usage();
                argc -= optind;
                argv += optind;
                if (argc != 1)
                        usage();
                rm_file(&argv[0]);
                exit(eval);
        }

ファイルしか消せないので、うっかり後ろにバックスラッシュをつけても
大丈夫です。

% ln -sf somedir symdir
% unlink symdir/ # NG
unlink: cannot unlink `symdir/': Not a directory
% unlink symdir # OK
%

おわりに

私も含め、ファイル・ディレクトリを削除は rmコマンドに慣れきっていると
思うんですが、シンボリックリンクを消すときは unlinkって覚えておけば、
不幸に機会を一つ減らせるのではないでしょうか.

IPC::Open3::open3に関するメモ

Plack::Middleware::File::Less を lessc でコンパイルするように - naoyaのはてなダイアリー


で紹介されている。Plack::Middleware::File::Lessのソースの
以下の部分が気になりました。

sub less_command {
    my $less = shift;
    my $pid = open3(my $in, my $out, my $err, "lessc", "-");
    print $in $less;
    close $in;

    my $buf = join '', <$out>;
    waitpid $pid, 0;

    return $buf;
}

標準エラー出力に書きまくるような LESSを入力に与えれば、
blockした状態になりつづけるんじゃないかなって思って試して
みたんですけど、どうもうまくいきません。参考記事から 0(false)を
指定すると、標準エラー出力が標準出力に dupされることは知っていたの
ですが、これは undefだしハンドルが設定されるんじゃないかなって思って
IPC::Open3のソースを確認してみたのですが、undefでも dupされてしまった
ようです。


問題の部分は以下でした。

# IPC::Open3::_open3関数 209行目
 $handles[2]{parent} ||= $handles[1]{parent};

ハッシュの要素なので undefでも特に問題なく dupされていたようです。
以下のように書かれていたらわかったと思うんですが・・・。

    my $pid = open3(my $in, my $out, 0, "lessc", "-");

まだまだ Perl力が低かったです。

おわりに

たぶんこのことを見越して書かれたコードなのだとは思いますが、
自分で書くときは 0にしておかないと読み間違えてしまいそうだなと
思いました。なお明示的に標準エラー出力のハンドラを設定したい
場合は, Symbol::gensym関数を変数に設定して、第三引数として
設定してください。詳しくはドキュメントを見てください。


flymakeの設定する前に flycheckを確認しよう

flycheck/flycheck · GitHub


twitterで前に少し書いたのですが、記事にもしておきます。


動的にエラー表示を行なってくれる flymakeはとても便利なんですが、
設定が面倒です。初期関数だったり、エラー出力を解析するための正規表現
指定やら、苦労したことある人は多いと思います。


そんな人に flycheckはお勧めです。簡単に言うと各言語用の flymakeの設定を
まとめてくれているパッケージです。対応言語も多く、設定も簡単なのです。


対応言語

2013年 1月 25日現在以下の言語に対応しています。

インストール

MELPAには登録されているので package.elを使っている人は
以下のようににしてください。

  M-x package-refresh-contents
  M-x package-install flycheck


el-getには現状登録されていないので、レシピを自分で書く等
してください。


設定

対応するモードの hookに flycheck-modeを追加するだけです。

;; Python
(add-hook 'python-mode-hook 'flycheck-mode)

;; Ruby
(add-hook 'ruby-mode-hook 'flycheck-mode)

おわりに

特殊な設定を要する場合は自作する必要がありますが、ただエラーチェックを
したいという場合はまず flycheckが対応しているか確認しましょう。もし
未対応で汎用的に使えるっていうものがあれば、flycheckへ pull requestする
ことを検討してみるとよいかと思います。

おまけ

flymakeを使う場合は、flymake-goto-next-error、flymake-goto-prev-error
適当なキーに割り当てておくと便利です。smartrepを使うと少々長いキーを
割り当てても楽に移動できます。以下は私の設定です。

;; flymake
(smartrep-define-key
    global-map "M-g" '(("M-n" . 'flymake-goto-next-error)
                       ("M-p" . 'flymake-goto-prev-error)))

Emacs Lispパッケージを書く場合のテンプレート

Emacs Lisp使ったパッケージを書く場合はとりあえず以下のようにしましょう。

;;; ファイル名.el --- パッケージ概要

;; Copyright (C) 2013 by 名前

;; Author: 名前 <メールアドレス>
;; URL: リポジトリの URL等
;; Version: 0.01
;; Package-Requires: ((依存パッケージ1) (依存パッケージ2))

;; ライセンス

;;; Code:

(provide 'パッケージ名)

;;; ファイル名.el ends here

詳細はこちらにあります。
とりあえずこうするのが無難ということにしておいてください。一行目のファイル名と
概要の間にあるハイフンは 3本です。2本ではありません。3本です。


私は yasnippetの snippetとして以下を登録しています。

# name : Package Template
# key  : package
# --
;;; `(file-name-nondirectory (buffer-file-name))` ---

;; Copyright (C) `(format-time-string "%Y" (current-time))` by Syohei YOSHIDA

;; Author: Syohei YOSHIDA <syohex@gmail.com>
;; URL:
;; Version: 0.01

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;; Code:

$0

(provide '`(file-name-sans-extension (file-name-nondirectory (buffer-file-name)))`)

;;; `(file-name-nondirectory (buffer-file-name))` ends here

あとは好きに書いてください。