読者です 読者をやめる 読者になる 読者になる

cat, less コマンドの表示を Syntax Highlight させる

環境: Mac

Pygments という Python のパッケージがあり、その中の pygmentize コマンドラインツールを使うことでシンタックスハイライト表示できるようになる。

Pygments インストール

まずは Pygments のインストール。

$ pip install Pygments

または

$ sudo easy_install Pygments

lessfilter の作成

次にlessfilterという名前でシェルスクリプトファイルを作成してパスが通っている場所に置く。

# パス確認
$ printenv PATH

/usr/local/bin/配下に作ることにする。

$ vi /usr/local/bin/lessfilter
$ chmod 755 /usr/local/bin/lessfilter

lessfilter

#!/bin/bash
case "$1" in
    *.sh|*.awk|*.diff|*.patch|*.sql|\
    *.php|*.pl|*.pm|*.py|*.rb|*.haml|*.slim|\
    *.java|*.groovy|*.scala|*.clj|*.cljs|\
    *.c|*.h|*.m|*.swift|*.go|*.lua|*.hs|*.erl|*.fs|*.ml|*.exs|\
    *.html|*.js|*.coffee|*.css|*.sass|*.scss|\
    *.json|*.xml|*.yaml|*.yml)
        pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -g "$1"
        ;;
    .zshrc|.bashrc|.bash_aliases|.bash_environment)
        pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1"
        ;;
    Gemfile|Rakefile)
        pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l ruby "$1"
        ;;
    *)
        grep '#!/bin/bash\|#!/bin/sh' "$1" > /dev/null
        if [ "$?" -eq "0" ]; then
            pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1"
        else
            exit 1
        fi
esac

exit 0

lessfilterでは pygmentize コマンドを使ってファイルを開く。
-gオプションを指定することで入力ファイル名から lexer を推測してくれる。
ここに pygments で使える lexer 一覧があるので必要な物を自分で追加してカスタマイズする。

環境変数の設定

続いて環境変数LESSLESSOPENを設定する。
zsh を使っているので.zshrcに以下を追加。bash なら.bashrcなどに。

# cat
alias c='pygmentize -O style=monokai -f terminal256 -g -O encoding=utf-8'
function cl() {
    c $1 | nl -n ln -b a
}
alias cl=cl

# less
export LESS='-R'
export LESSOPEN='|lessfilter %s'

反映

$ source ~/.zshrc

使い方

# cat のシンタックスハイライト
$ c foo.rb

# cat + 行番号表示
$ cl foo.rb

# less のシンタックスハイライト
$ less foo.rb

通常の cat コマンドとは別にcclいうエイリアスで設定する。
こちらを使うとシンタックスハイライト表示になる。

こちらの記事を参考にしました。

catやlessをシンタックスハイライト+行番号表示してコードを見やすくする - Qiita
http://qiita.com/zaru/items/4a7811ac21f74a13481c
linux - Get colors in 'less'' command - Super User
http://superuser.com/questions/117841/get-colors-in-less-command


追記

lessfilterを修正した。

lessfilter

#!/bin/bash

case `basename $1` in
    *.log)
        ;;
    .zshrc)
        pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1"
        ;;
    Gemfile|Podfile)
        pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l ruby "$1"
        ;;
    *)
        head -n 1 "$1" | grep '#!/bin/bash\|#!/bin/sh' > /dev/null
        if [ "$?" -eq "0" ]; then
            pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -l sh "$1"
        else
            pygmentize -O encoding=utf-8 -O style=monokai -f terminal256 -g "$1"
        fi
        ;;
esac
  • 拡張子ホワイトリスト方式は止めた。-gでよしなにやってくれるので
  • case文の条件がフルパスだとマッチしてなかったので修正した
  • .bash 系のファイルとか Rakefile は lexer で対象になっていたので削除
  • シバン(shebang)のチェックは1行目のみを対象
  • .logファイルはスキップするようにした

-gで開く場合、拡張子に対応する lexer がない場合はてっきりシンタックスハイライトは適用されないと思っていたが、そういう場合は text とみなされ TextLexer が適用されるみたい。で、ログファイルのようなでかいファイルを開くときにもシンタックスハイライトしようとして解析に時間がかかって開けなくて困った。なのでとりあえず個別に除外するようにした。他にもあればここに追加していく。

ちなみに-gでどの lexer が適用されるかは-Nオプションで確認することができる。

$ pygmentize -N config/application.rb
rb
$ pygmentize -N log/development.log
text