manの表示を環境変数で設定
man
コマンドでの表示はMANPAGER
またはPAGER
という
環境変数を設定しておくとそれを使ってマニュアルを表示します
1。
PAGERの方は他のプログラムも使うので、
man
だけに対して使いたいものがある場合はMANPAGER
に指定しておきます。
man
の結果はパイプで渡される様な形で表示プログラムに渡される様で、
Vimで表示したい場合には単に
export MANPAGER=vim
としておいてもダメで、
$ man bash
Vim: Warning: Input is not from a terminal
みたいに表示されておかしくなります。
表示するためには
export MANPAGER="vim -"
の様に標準入力(stdin)を表示するように設定しておきます。
ただ、これをPAGER
の方に設定しておくと
git diff
やgit log
等PAGERを使うコマンドがおかしくなるので注意。
また、man
で表示されるマニュアルには表示用のシンタックス記号等が入ってる?らしく
(manファイルをさらにmanコマンドが修正したもの)、
そのまま表示すると文字化けの様になる部分が出るため
export MANPAGER="col -b -x|vim -"
の様に、col
コマンドをはさみます。
col
は入力に色々フィルターをかけて出力しなおしてくれるコマンドで、
-b
はバックスペースを消したり各word毎に余計な記号を消して?くれて、
-x
でタブをスペースに変換します。
さらにもう一歩Vim側の設定を加えて
export MANPAGER="col -b -x|vim -R -c 'set ft=man nolist nomod noma' -"
こんな感じにしておくと良い感じになります。
-R
オプションで読み込み専用に。
-c
でVimコマンドを実行して
filetype
をman
にします。Vimには予めman
用に
シンタックスファイルも用意されてるので
2
filetype
を指定することで良い感じの色表示にしてくれます。
それから編集するわけではないのでnolist
で余計な記号を映さないように。
nomod
は指定する必要があるのがよく分かりませんが、
下に上げる参考ページ等大概の場所で設定してあるので取り敢えず
3。
後はnoma
(nomodifiable
)を設定して編集そのものを禁止してしまいます。
(-R
と両方設定するのは冗長かも。)
下のページなんかだとGNUのman
だとMANPAGE
にパイプを設定するのが
うまくいかない、ということで
export MANPAGER="/bin/sh -c \"col -b -x|vim -R -c 'set ft=man nolist nonu noma' -\""
みたいにシェルをコマンドとして指定してその引数でパイプを使ったコマンド を呼ぶようにする必要があることもあるみたいです。
ただ、使える範囲のGNU manを使ってる様なRedHatやDebian GNU、Cygwin等では 最初の方法でそのまま上手く行きました。
Vimの中からHelpを開く
man
で1つ開く分には上ので十分なのですが、
VimではさらにVimの中からManを呼ぶ機能が有ります。
:Man
というコマンドでマニュアルが開けたりします。
が、このコマンドはVimデフォルトだと
ftplugin/man.vim
で定義されていて
4
、filetype
がman
の時のみに使える様になります。
使える主なコマンド/ショートカットは次の様なもの。
:Man <command>
でcommandのマニュアルを表示。:Man <n> <command>
でcommandのセクションnのマニュアルを表示。<C-]>
でカーソル下の文字のコマンドのマニュアルを表示。<C-t>
で戻る。
参考:
:help Man
また、コマンドに当たる文字列の上にカーソルを置いてK
(または<Leader>K
)を押すと
:! man <command>
を呼んで、外部コマンドでman
を呼びます。
参考:
:help K
:Man
コマンド等についてはftplugin
で定義されてるので、
通常は有効化されていません。
man
以外のファイルタイプでも有効にしたい場合は
.vimrcに
runtime ftplugin/man.vim
と書いて常に読み込む様にしておきます。
この場合でも<C-]>
/<C-t>
に関してはman
以外のファイルタイプでは
通常のタグジャンプのマッピングになったままなので
挙動をおかしくしたりはしません。
また、K
(<Leader>K
)に関してはman.vim
を改めて読み込まなくても
使える様になっています
5。
しかし、これらのコマンドはMANPAGER
やPAGER
が定義されていると
:! man 'bash'
sh: -c: line 0: syntax error near unexpected token `||'
sh: -c: line 0: `(cd '/usr/local/share/man' && /usr/bin/tbl '/usr/local/share/man/man1/bash.1' | /usr/bin/groff -Wall -mtty-char -Tascii -mandoc -c | ( || true))'
Error executing formatting or display command.
System command (cd '/usr/local/share/man' && /usr/bin/tbl '/usr/local/share/man/man1/bash.1' | /usr/bin/groff -Wall -mtty-char -Tascii -mandoc -c | ( || true)) exited with status 512.
sh: -c: line 0: syntax error near unexpected token `||'
sh: -c: line 0: `(cd '/usr/share/man' && /usr/bin/gunzip -c '/usr/share/man/man1/bash.1.gz' | /usr/bin/tbl | /usr/bin/groff -Wall -mtty-char -Tascii -mandoc -c | ( || true))'
Error executing formatting or display command.
System command (cd '/usr/share/man' && /usr/bin/gunzip -c '/usr/share/man/man1/bash.1.gz' | /usr/bin/tbl | /usr/bin/groff -Wall -mtty-char -Tascii -mandoc -c | ( || true)) exited with status 512.
No manual entry for bash
みたいなエラーを出したりします 6 。 定義されてるとダメなので、
$ export PAGER=
みたいに空文字にしておいても駄目。
$ unset PAGER
として変数を消して置く必要が有ります。
なので.vimrc
の中で値を
let $PAGER = ''
みたいにして消しても駄目。
ということで、最初の環境変数を使った方法だと 中でさらに他のマニュアルを見たい時に上手く行きません。
ラッパー関数を作る
環境変数だけでやろうとすると不具合が出てくるので、
man
コマンド自体を変更してしまいます。
こんな感じ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
vim
に渡す引数の最後の-
を忘れないように注意。
やってることはPAGER
やMANPAGER
を一旦unset
した後に
man
を呼んであとで回復させてます。
また、man
コマンドは直接vim
には渡さず、
一度結果をみてエラーならそのままecho
、
そうでないならvim
に渡す、と言った形。
また、vim
の引数にはft=man
のみ指定していますが、
他のオプションは.vimrc
の方で下の様に設定しています。
1 2 3 4 5 6 7 8 9 |
|
.vimrc
ではpluginを有効にし、runtime ftplugin/man.vim
とプラグインを読み込んで、
autocmd
でq
のマップとsetlocal
を行っています。
q
の方はq
だけで直ぐにファイルを閉じれる様にしているだけです。
(通常less
などでマニュアルを開いたのと同じ様に。)
2つ目のautocmd
の方でsetlocal
を行っていて、ここで
- nospell: スペルチェックを表示しない(編集するわけでもないのに特殊な用語とかをチェックしても仕方ないので)
- ts=8: 内部から
:Man
した時にはcol
を通して無いのでタブがVimで設定した幅になってしまうので、マニュアルで通常使われる8幅に。 - nolist: 特殊文字を表示しない。
- ro: readonly。内部で開いた時には
-R
が渡されてないので。 - nomod:
nomodified
状態に。 - noma:
nomodifiable
に。
の設定に指定ます(上の環境変数の物に少し追加)。
こんな感じで設定しておくと、通常のman
コマンドで
開く時も、
Vimで何か編集中に:Man
でマニュアルを開くことも、
マニュアルページで<C-]>
でさらにカーソル下のマニュアルページに飛ぶことも、
K
で外部コマンドでman
を開くことも出来る様になります。
おまけ
上のautocmd
についてはman
の場合だけじゃなくて、
他の場合にも有用で、
実際にはhelp
、qf
、ref
なんかの場合にも設定しています。
1 2 |
|
その他参考:
man ascii
is misaligned when using vim as a pager - Unix & Linux Stack Exchange
-
使われるページャは
man -P <pager>
で指定されたpager。- MANPAGERで指定されたプログラム。
- PAGERで指定されたプログラム。
の順で優先され使われます。 何も指定されてない場合は通常は
/usr/bin/less -is
。 ↩ -
nomod
(nomodified
)はバッファが編集されてない、という時に設定されてる値で、:q<CR>
とかで終了する時に保存してないよ、等の注意が出なくなります。 逆にバッファを編集するとmod
(modified
)が設定されてE37: No write since last change E162: No write since last change for buffer "a.txt"
と出るようになるので
:q!<CR>
とする必要がでてくる、と。通常
man
で開いてる限りは最初はnomodified
なので 必要無い気がするんですが、modified
になってる場合もあるのかも。。。? ↩ -
これらのコマンドですが、 元々は manpageview というプラグインがあって、ここでも同じコマンドが定義されています。 manpageviewについて書いてあるページなどを見ると このプラグインを入れると上記のコマンドが使える、などと書いてあるので 上のftplugin/man.vimはmanpageviewを元にして 入れたものな感じです。 (ftplugin/man.vimは2013年、manpageviewは2011年に最後の編集があります。)
ただ、manpageviewは古いVim用で、 含まれる manpageview/plugin/manpageview.vba を無理やり読み込もうとすると
UseVimball
がないといった感じのエラーが出たり、 さらに~/.vim/
以下に~/.vim/autoload/
等のディレクトリを作って その中にmanpageview.vim
等のファイルを作ったりして邪魔な事になるので注意。manpageviewの方では
g:manpageview_winopen
というオプションがあり、 このオプションで:Man
でマニュアルページを呼び出すときの Windowの表示方法を変える事が出来る様な設定があります。hsplit
とすると縦分割、vsplit
とすると横分割で開けるような設定 があるのですが、ftplugin/man.vimにはありません。ftplugin/man.vimでは
:Man
コマンドでマニュアルページを開こうとすると、 filetypeがman
の場合にはその領域に新たにウィンドウを作り、 それ以外の場合にはhsplit
的な縦分割をします。ただし、開いてるウィンドウの中にfiletypeが
man
の物があると そこへ新たなウィンドウを作って開きます(2つ以上ある場合には左上の方から使う?)。 ↩ -
<Leader>K
に関しては ftplugin/man.vim の中で定義されてる様に見えるし、 他で定義されてる様にも見えないし、 そもそもMan
などは定義されてない状態ですが、 何故使えるのか良く理解できない。。。 ↩ -
ただし、
K
(<Leader>K
)に関しては、filetypeがman
でない場合にはPAGER
とかがless
等に設定されてる場合は表示できます。この辺もちょっと謎。やはりftplugin/man.vim以外の場所い他に 設定がある? ↩