Personal tools
You are here: Home ブログ matsuyama Emacs Lisp を仕事で使ってみた
Document Actions

Emacs Lisp を仕事で使ってみた

先日、仕事で開発している製品の CSS のインデント幅を 4 から 2 に変更する必要がありました。 Unix ラブで最小主義の僕は、この場合は sed で処理するのがベストだろうと思い、以下のコマンドを叩きました。

% sed -e 's/^    /  /g' *.css

しかし問題がありました。

test.css:

/*
   Comments
*/
.hoge {
    background-color: blue;
}

上記のような CSS を変換すると、コメントのインデントまで変換されてしまうのです。

test.css 変換後:

/*
  Comments
*/
.hoge {
  background-color: blue;
}

どうしようかあれこれ考えてたら、開発部長が一言。

「 Emacs Lisp で書けばいいじゃないですか」

なるほど。必要な要件は以下のような感じなので確かにベストチョイスかもしれません。

  • インデント幅をそろえる
  • コメントをいじるとまずい

早速 Emacs で次のようなコードを書いてみます。

(with-current-buffer (find-file-noselect "test.css") ; test.css で
  (let ((pos (point-min)))
    (goto-char pos)                     ; 最初から
    (while (setq pos (re-search-forward "^[\t\s]+" (point-max) t)) ; 行頭がスペースかタブで初まるものに対して
      (if (not (eq (get-text-property pos 'face) 'font-lock-comment-face)) ; コメント内ではない場合に
          (indent-for-tab-command)))))   ; インデントする

これを eval すると test.css が開かれてインデントが実行されます。

test.css 変換後:

/*
    Comments
*/
.hoge {
  background-color: blue;
}

うまくいっているようです。このコードを利用してそのまま Emacs 上で変換を行ってもいいのですが、コマンドラインから再利用できるようにするためにスクリプト化しておきます。スクリプト化に関しては「Software Design 2月号」の Elisp 特集が大変参考になりました。

indent-css.el:

(require 'cl)
(require 'css-mode)

(setq cssm-indent-function #'cssm-c-style-indenter)
(setq cssm-indent-level 2)              ; インデント幅は 2

(dolist (file command-line-args-left)   ; それぞれコマンドライン引数に対して
  (with-current-buffer (find-file-noselect file) ; ファイルを開き
    (font-lock-fontify-buffer)                   ; コメント判断のために font-lock をかける
    (let ((pos (point-min)))
      (goto-char pos)                   ; 最初から
      (while (setq pos (re-search-forward "^[\t\s]+" (point-max) t)) ; 行頭がスペースかタブで初まるものに対して
        (if (not (eq (get-text-property pos 'face) 'font-lock-comment-face)) ; コメント内ではない場合に
            (indent-for-tab-command)))) ; インデントする
    (save-buffer)))                     ; その結果を保存する

変換を実行するには以下のコマンドを実行します。

% emacs --script indent-css.el *.css

css-mode に問題があって -moz-opacity などの処理でおかしくなっていましたが、大半は意図した通りちゃんと動いてくれました。

シェルと Emacs の、この見事な調和に芸術性を感じない人はおそらくいないはずです。

処理結果を (save-buffer) するだけで保存できることに気付いたときは感動で死にそうになりました。なんと直感的なのでしょう!

テキスト処理に awk や perl を使う時代は終わりました。これからは Emacs Lisp の時代です。なんといってもエディタなのですから。


Category(s)
emacs
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/matsuyama/use-emacs-lisp-for-work/tbping

Re:Emacs Lisp を仕事で使ってみた

Posted by hamabe at 2008-02-09 14:09
すごすぎ(笑)

Re:Emacs Lisp を仕事で使ってみた

Posted by Anonymous User at 2008-02-09 16:33
コメントのインデント幅だけ4にする理由がわかりません。
特別な理由がないのなら、インデント幅は統一したほうが良い様な気がします。

Re:Emacs Lisp を仕事で使ってみた

Posted by Anonymous User at 2008-02-15 10:12
mark-whole-buffer
indent-region

でできるともっと楽ですね。

Re:Emacs Lisp を仕事で使ってみた

Posted by matsuyama at 2008-02-16 19:44
書くの忘れてましたけど、 css-mode がダメダメでコメント内で TAB するといろんなことやってくれます。なので今回は indent-region 使ってないのですが、 indent-line-function を使えば mark-whole-buffer + indent-region という組合せも可能だと思います。

Re:Emacs Lisp を仕事で使ってみた

Posted by Anonymous User at 2008-04-23 15:21
sed は苦手ですが、

$ sed '/\/\*.*\*\//{p;d};/\/\*/,/\*\//{p;d};s/^ / /' *.css

とか?

Re:Emacs Lisp を仕事で使ってみた

Posted by forged Steel valve at 2010-05-09 22:18
Much like your blog, let me

Re:Emacs Lisp を仕事で使ってみた

Posted by safety valve at 2010-05-09 22:19
Good: you know, your blog writing is very good
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.