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 asciiis 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以外の場所い他に 設定がある? ↩
