はじめに
よく使うコマンドの筆頭にman
コマンドがありますが(僕調べ)、builtinコマンドや、"if"などの予約語についても同じように調べたいことがあるかと思います。
また、manページをlessで表示するときに、デフォルトでは白黒となっていますが、より見やすくするために色付きで表示するようにします。
使用するシェルはzshで、それ以外のシェルでは動作しません。
ビルトインコマンド、エイリアス、予約語に対する扱い
$ whence -wa cd
を実行すると、
cd: alias
cd: builtin
のように、cd
がシェルにどのように解釈されるかを表示することができます。
(上の例のように複数の対象が存在する場合にはfzf
などで選択すればよいでしょう。)
": "の右側には"builtin","reserved","alias","function","command","hash","none"がくるので、この値に応じて異なる動作をするように新たにman
コマンドを定義し直すことにします。
参考になるもの:
ただし、上の場合にはbashのビルトインコマンドに関しての話なので、今回はzsh用にしてみたいと思います。
for builtin commands
man zshbuiltins
を実行し、そのあと/cd
のように実行されるようにします。
$ man_indent=7
$ _space="$(printf '%*s' "${man_indent}" '')"
$ /usr/bin/man --pager="less -p'^${_space}cd '" zshbuiltins
(TODO: コマンドの字下げ幅は環境依存でないか?)
注意
Ubuntuなどでzshbuiltinsがない場合には、手動でインストールする必要があります(バージョンに注意)。
$ mkdir -p ~/Downloads/zsh-doc; cd $_
$ wget http://downloads.sourceforge.net/project/zsh/zsh/5.0.2/zsh-5.0.2.tar.bz2
$ tar -xvf zsh-5.0.2.tar.bz2
$ sudo cp Doc/*.1 /usr/local/share/man/man1
例
man cd
for reserved words
man zshall
の"COMPLEX COMMANDS"と"ALTERNATE FORMS FOR COMPLEX COMMANDS"のセクションに、具体的な使い方が書かれているので、
$ /usr/bin/man --pager="less -p'^COMPLEX COMMANDS$'" zshall
が実行されるようにします。
(builtinの時と同じようにしてもよかったのですが、esac
などがマッチしないので。)
例
man esac
for aliases
whence
コマンドのcshフォーマットでの出力をみるようにします。
例
$ whence -c dot
dot: aliased to dot_main
(dot_main
は関数)
for functions
whence -f dot_main
とすれば、その関数dot_main
の中身を表示します。
pygmentize
コマンドなどが使えれば、カラーでハイライトして表示できるので、それを使い$MANPAGER
で表示します。
(後述するようにless -R
を指定していればカラー表示出来るようになります。)
if hash pygmentize 2>/dev/null; then
whence -f "$1" \
| pygmentize -l sh \
| ${MANPAGER:-${PAGER:-less}}
else
whence -f "$1" | ${MANPAGER:-${PAGER:-less}}
fi
例
man man
その他の場合
通常のman hoge
が実行されるようにします。
以上をまとめると
# vim: set ft=zsh
#=#=#=
# man (available for buitlin commands)
#
# **Features:**
#
# * for zsh builtin commands
# * for reserved word
# * for alias
# * for zsh function
# * for (natural) command
# * if the same name exists, choose one by fzf
# * with color
#
# >* [Can I get individual man pages for the bash builtin commands? - Unix & Linux Stack Exchange](http://unix.stackexchange.com/questions/18087/can-i-get-individual-man-pages-for-the-bash-builtin-commands)
# >* [manpage - How to make `man` work for shell builtin commands and keywords? - Ask Ubuntu](http://askubuntu.com/questions/439410/how-to-make-man-work-for-shell-builtin-commands-and-keywords)
#
# But I want to know about zsh builtins, so I wrote this.
#
# Install zsh manuals to enable `man zshbuiltins`:
#
# ```
# $ mkdir -p ~/Downloads/zsh-doc; cd $_
# $ wget http://downloads.sourceforge.net/project/zsh/zsh/5.0.2/zsh-5.0.2.tar.bz2
# $ tar -xvf zsh-5.0.2.tar.bz2
# $ sudo cp zsh-5.0.2/Doc/*.1 /usr/local/share/man/man1
# ```
#
# **Require:**
#
# * fzf
# * "pygmentize" or "highlight" for highlighting scripts
# * LESS="R" option for ansi color in "less" command
#=#=
function man() {
# Stock current LANG
_LANG=${LANG}
# set language (but if MANLANG is already set, use that)
export LANG=${MANLANG:-${_LANG}}
function restore_lang() {
# restore LANG and clean up name space
export LANG=${_LANG}
unset _LANG
unset -f $0
}
trap restore_lang 1 2 3 EXIT
if [ ! -n "$1" ]; then
echo "What manual page do you want?"
return 1
fi
# get man type (using fzf but you can replace it with peco or percol or zaw)
word="$(whence -wa -- $1 | uniq | fzf -1 | sed 's/: / /' | cut -d' ' -f2)"
# if escaped, do nothing
if [ ! -n "${word}" ]; then
return 0
fi
# switch operation by word
case ${word} in
builtin) # built-in command
local man_indent _space
# TODO: get how many spaces before the commands
man_indent=7
_space="$(printf '%*s' "$man_indent" '')"
/usr/bin/man --pager="less -p'^${_space}\\$1 '" zshbuiltins
;;
reserved) # reserved words
/usr/bin/man --pager="less -p'^COMPLEX COMMANDS$'" zshall
;;
alias) # alias
whence -c $1
;;
function) # function
if hash pygmentize 2>/dev/null; then
whence -f "$1" \
| pygmentize -l sh
elif hash highlight 2>/dev/null; then
whence -f "$1" \
| highlight --out-format=ansi --src-lang=Bash
else
whence -f "$1"
fi
;;
*) # try using man
/usr/bin/man "$@"
;;
esac
}
manページを色付きで表示する
上にあげた画像を見てもらえれば分かるように、色付きでmanページが見られるといろいろと捗ります。
参考:
~/.zshrc
で
export PAGER=less
としておけば、manコマンド実行時にはlessコマンドを使って表示します。
lessコマンドのオプションは環境変数LESS
に指定することができるので(See man less
)、
export LESS='-iMRj.5'
と指定しておきます。
オプション | 意味 |
---|---|
-i |
ignore-case |
-M |
long-prompt |
-R |
ANSIカラー表示 |
-j.5 |
ターゲット行を画面の中心に |
また参考リンクのように~/.zshrc
に以下のように書いておけば、太字や下線、ハイライト時の色を指定することができます。
export LESS_TERMCAP_mb=$(tput bold) # begin blinking
export LESS_TERMCAP_md=$(tput bold; tput setaf 4) # begin bold (blue)
export LESS_TERMCAP_me=$(tput sgr0) # end mode
export LESS_TERMCAP_se=$(tput sgr0) # end standout-mode
export LESS_TERMCAP_so=$(tput bold; tput setaf 3) # begin standout-mode (yellow)
export LESS_TERMCAP_ue=$(tput rmul; tput sgr0) # end underline
export LESS_TERMCAP_us=$(tput smul; tput setaf 2) # begin underline (green)
僕はtputを使って色などを指定していますが、エスケープ文字を使って直接指定することもできるので、細かく調節したい人はこちらを使うといいと思います。
まとめると:
終わりに
manコマンドを活用するために、ビルトインコマンド等も同じman
で参照できるようにしました。また、色付きで表示されると見やすくなると思いますので、色付き表示の仕方もご紹介しました。
何かしら役に立てば幸いです。