最近仕事ではJavaScriptを書いてます。JSのフレームワークにはjQueryなどいくつかありますが、アリエルではGoogle Closure Libraryを使っています。個人的には好きなフレームワークです。prototypeを勝手にいじくりまわさない辺りはお行儀がよろしいと思います。
Google JavaScript Style
Closure Libraryには以下のようなコーディング規約があります。同じメソッド定義でも、JSではいろんな書き方ができるので、こういう規約には従っておいたほうがいいです。
僕はEmacsでJavaScriptを書くときはjs2-modeを使っています。しかし、既に周知のように、js2-modeのインデントはクソです。特にgoog.array.forEachなどにfunctionを渡すときのインデントは発狂ものです。
// × js2-mode
goog.array.forEach(coll, function(elem) {
// ここに自動インデント
});
// ○ Google JavaScript Style
goog.array.forEach(coll, function(elem) {
// ここにインデントしたい
});
espresso-modeのインデントを使う
そこでインデントだけespresso-modeのインデントを使います。espresso-modeは以下のサイトからダウンロードしてください。
(autoload 'js2-mode "js2" nil t)
(add-hook 'js2-mode-hook
#'(lambda ()
(require 'espresso)
(setq espresso-indent-level 2
espresso-expr-indent-offset 2
indent-tabs-mode nil)
(set (make-local-variable 'indent-line-function) 'espresso-indent-line)))
espresso-modeのインデントは割と素直なので、ほとんど困ることはありません。
case文のインデントを修正
ただし、これでもswitch文のcaseラベルのインデントが規約に沿いません。
var Fruit = some.long.namespace.Fruit;
// × caseが文頭に並んでしまう
switch (fruit) {
case Fruit.APPLE:
...
case Fruit.BANANA:
...
})
// ○ 規約では他と同じ2つのインデント
switch (fruit) {
case Fruit.APPLE:
...
case Fruit.BANANA:
...
})
そこで自前でインデント関数を書いて、case文のときだけインデントを変えるようにします。
(autoload 'js2-mode "js2" nil t)
(add-hook 'js2-mode-hook
#'(lambda ()
(require 'espresso)
(setq espresso-indent-level 2
espresso-expr-indent-offset 2
indent-tabs-mode nil)
(defun my-js-indent-line ()
(interactive)
(let* ((parse-status (save-excursion (syntax-ppss (point-at-bol))))
(offset (- (current-column) (current-indentation)))
(indentation (espresso--proper-indentation parse-status)))
(back-to-indentation)
(if (looking-at "case\\s-")
(indent-line-to (+ indentation 2))
(espresso-indent-line))
(when (> offset 0) (forward-char offset))))
(set (make-local-variable 'indent-line-function) 'my-js-indent-line)))
まとめ
これで大体Closure Libraryの規約と同じです。実はあと1個だけちゃんとインデントできないところがあるのですが、対応が面倒そうなので秘密にしておきます。最初に見つけた人にはペロペロキャンディをあげる。




コメントする