ラベル Vim tips の投稿を表示しています。 すべての投稿を表示
ラベル Vim tips の投稿を表示しています。 すべての投稿を表示

2009年6月17日水曜日

Vim: 同じ高さのインデントに移動



プロトコルが複雑なデバドラ等のコードの場合、switch-case文が長かったりネストしていたりと一画面に収まらない場面がある。そんな時、同レベルのcase文を追いたい場合、通常なら「case」まで移動して「*」や「#」でジャンプしたりする。
でもこれだと、検索レジスタ「"/」を汚してしまうし、ネストしたcase文には対応できない。

そこで、同じ高さのインデントに移動する術を期待し、Vimの本家で「move same indent」というフレーズで検索したら見事ヒット!
一行でしかもキーマップまで書けてしまうとは。。

このWikiには「Alt-,/.」に割り当てているが、しかしMeta(Alt)キーがうまく動作しない。
原因はここにあるようにgnome-terminalがAltの前にESCを付けてしまうのが問題らしい。


よって、以下の設定にした。
nn <C-k> k:call search ("^". matchstr (getline (line (".")+ 1), '\(\s*\)') ."\\S", 'b')<CR>^
nn <C-j> :call search ("^". matchstr (getline (line (".")), '\(\s*\)') ."\\S")<CR>^
※nnってのは:nn[TAB]で補完されるようにnnoremapの略

j/k」の上下移動にちなんで、「Ctrl-j/k」で同インデントに上下移動でき(カーソルが行頭にある必要もなし)、こっちの方がフィーリング的に合っている。
ちなみに、「Ctrl-j/k」はデフォルトでは大した機能に割り当てられておらず、またその機能には代替キーも用意されているので問題無い。


2009年6月7日日曜日

Vimスクリプト: 2HTML

ソースコードや設定ファイルをtoHTMLしてくれるVimスクリプト。しかも使用中のsyntaxに近い配色で。

Fedora10のvimにも入っている。
$ locate 2html.vim
/usr/share/vim/vim72/syntax/2html.vim
$ rpm -qf `!!`
rpm -qf `locate 2html.vim`
vim-common-7.2.148-1.fc10.i386
$ rpm -ql $(!!) |grep \.vim$ |view -
rpm -ql $(rpm -qf `locate 2html.vim`) |grep \.vim$ |view -
Vim: 標準入力から読込中...

とすると、標準でたくさんのVimスクリプトが入っているのがわかる。
気になるVimスクリプトは「gf」としてその中を覗いてみまっしょう。
「:set hidden」な状態の人は、「C-^」で検索結果に戻れるので他のスクリプトにもどんどん跳んでってください。

で、使い方だが
$ vi hello.c
:%TOhtml
hello.c.htmlという filename.htmlファイルが作成される。

ファイル内の一部分だけtoHTMLしたければ、「%(カレント・ファイル)」の代わりに Shift-Vでその部分に対し行選択してTOhtmlに渡せばよい。
:'<,'>TOhtml

保存して確認する(ファイルに落とさないとFirefox側からは読めないので)
:w |!firefox %

Vim表示に比べてちょいと蛍光色掛かって明る過ぎだけど、使用中のsyntaxに近い配色に仕上がっている。

恥ずかしながら今までは、インデント等の整形やHTMLの特殊文字の変換を一記号ずつ置換していた。。
例えば必要な範囲に対し、Shift-Vで行選択し「:'<,'>s/ /&nbsp;/g」や「:'<,'>s/^I/&nbsp;&nbsp;&nbsp;&nbsp/g」みたいな置換をいちいちしてたけど、流石はVim!そんなのとっくに用意済みで、2HTMLでは「:'<,'>TOhtml」(:TO[Tab]でOK)とするだけ!
しかも色付けまでしてくれる。無知って怖ッ!


2009年6月1日月曜日

Vim: ctags

vimでお馴染みなのctags。無いとコードが読めないくい必須のアイテム。しかし、デフォルトでは少々使い辛い部分があるのでカスタマイズ。

タグファイルの配置場所

デフォルトではカレントの「tags」か「TAGS」になっている。
:set tags?
  tags=./tags,./TAGS,tags,TAGS

これでは、階層を持ったソースコード群のトップ・ディレクトリで「ctags -R」と作成した場合、一つ下に潜った状態でviを起動したら当然タグファイルを見つけられなくなる。

かと言って、tags+=../tags,../../tags,… とかするのは現実的ではない。
そこで、~/.vimrcに以下を記述すると親ディレクトリを再帰的に/(ルート)まで探してくれるようになる。
:set tags=tags;
※正確にはタグファイルが見つかってもそのタグファイルに定義が存在しない場合は次(親ディレクトリ)のタグファイルを探しに行く

タグファイル名

上記でだいぶ使い易くなったが、もう一つ不満が。
それはgrepやgrep.vimでワイルドカード(*)指定したときにtagsファイルも検索対象になってしまい、タグ化しているので当然ヒットしてしまい判断の邪魔になる。

そこでタグファイル名をドットファイルにする。
「:set tags=」はタグファイルの場所を指定する以前にタグファイル名を指定するものなので以下のようにする。
:set tags=.tags;

すると今度は、ctagsコマンドがデフォルトで生成するタグファイル名は"tags"なので、毎度
$ ctags -f .tags
とするのは面倒になるから、~/.bashrcに以下のaliasを追加してしまう。
alias ctags='ctags -f .tags'


[今日の一言]

右のリリース・カウンタの値が増えたので、Fedora11のリリースがまた一週間伸びたようです。まぁ気長に待ちましょう。



2009年4月20日月曜日

Vimアドオン: grep.vim

前回前々回とmanpageview.vimを紹介したのでアドオン繋がりで今回はgrep.vim。

アドオンを一つだけ選ぶとすれば、このgrep.vimというくらい重宝しているアドオン。これさえあれば他はデフォルト機能だけでやっていけるというくらいの代物!

インストール

ここからDL。
DLしたgrep.vimを ~/.vim/plugin/ 以下に配置すれば完了。

検索対象ファイルに対して検索するには
:Grep search_phase search_file
再帰検索の場合は
:Rgrep search_phase search_path

結果がQuickfix(下10行が水平分割される)で表示され、目的の行で「Enter」を押せばその場所に跳べる(もちろんQuickfixリスト内もVim操作が可能なので、検索結果の最後に跳びたければ「G」でOK)。

しかし、これでは使い勝手がVimの内部コマンド(:grep)と検索結果がQuickfix以外さほど変わりない。
そう、Vimの基本ポリシー"カーソル下の単語に対して~"を満たしていないのだ。

キーマップ設定

そこでDLページの説明にもあるように、キーマップの設定を行う。
Vimでは当然既に通常キー及びそれらにShiftやCtrlを加えたキーバインドは埋まっている。なのでLinuxでは大して使用しないF3やF4を使うことにする。

~/.vimrcに以下を追加する。
nnoremap <silent> <F3> :Grep<CR>
nnoremap <silent> <F4> :Rgrep<CR>

すると、「F3」でカーソル下の単語(ここではsignal_names)が :Grepの第1引数に入り
Search for pattern: signal_names
Enter」でカレントDirの全ファイル(*)が第2引数に入る。
Search in files: *

これで、「F3」「Enter」「Enter」でカーソル下の単語をカレントDirの全ファイルから検索し、Quickfixリスト内に表示された結果から「Enter」で目的の場所へ跳べるようになる。


更に「C-W Enter」とすると水平分割で元のコードを残したまま目的の場所へ跳べる。



2009年4月19日日曜日

manpageviewの補足

前回のmanpageviewについての補足。

アンインストール方法

以前はVim7.2以上という制限があり(現在はVim7.0以上となっているが)、かつFedora9デフォルトのVim7.1.Xだったので、起動時にエラーが出て使えずアンインストールする必要があった。
しかし、アンインストーラがなく複数のファイルが散らばってインストールされるので、他のアドオンを使っている場合は、~/.vim/以下をバッサリと言う訳にはいかない。

そこで、アンインストール方法。
インストールした日時で判別する。その当日ならば以下でインストールされるファイル群を見つけられるので、xargsで受けて消せばよい。
$ find .vim/ -mtime 0 -type f
.vim/.VimballRecord
.vim/autoload/manpageview.vim
.vim/syntax/manphp.vim
.vim/syntax/info.vim
.vim/syntax/man.vim
.vim/syntax/mankey.vim
.vim/plugin/manpageviewPlugin.vim
.vim/doc/tags
.vim/doc/manpageview.txt

水平分割の割合

K」でコードを水平分割してmanを開けるようになったが、その際デフォルトではmanがほとんど占めてしまいコードが4行しか見えなくなってしまう。
好みの問題だと思うけど自分はもう少しコード部分を残してmanを見たいので、以下のように変更。
[autoload/manpageview.vim:394]
g:manpageview_winopen == "hsplit"
...
    3wincmd -
...
水平分割は horizontal split なので、"hsplit"の部分
    3wincmd -
       ↓
    9wincmd -
これで10行分のコードは表示されるようになる。

man中のmanからの戻り

man中から更に別のmanに跳んだ後、「C-o」や「C-^」で戻れない。
:lsすると前のmanが代替ファイル(#)に入っていないのが原因のようだけど回避策今のところ不明。まだまだ修行がたりましぇん。。



2009年4月15日水曜日

Vimアドオン: manpageview

前回紹介した「K」でカーソル下の単語のmanを引く方法ですが、ただmanコマンドを起動しているだけなので、いくつか不満があり(そりゃmanのページャがVimでないのでストレスが溜まるってもんです!)今回はそれらを補ってくれるアドオンを紹介しちゃいまっす。

不満点その1

C-w K」としても水平分割してmanを開いてくれず、コーディングしながらmanを見る場合、複雑な型だったりすると一度に覚えきれずmanとコードを行ったり来たりしなくてはならなくなる。
タグジャンプの場合なら「C-w C-]」とすれば水平分割して定義場所に跳んでくれるのに。

ちなみにEmacsではmanにしてもgdbにしても水平分割が基本みたい。ただし、Vimのように"K"一文字で開いてくれる訳ではなさそう。このポリシーの違いでVim派なだけであって、Emacsの方が優れているとかいないとかいう優劣を付ける気はさらさらない(まぁどちらも同等の機能を有しており、片方で出来ることはもう片方でも出来るはずなので)。
それに複数あることは選べる自由があるということで良い事である。GnomeとKDEとかもね。

→ このmanpageviewというアドオンを入れると、「K」とするだけで(デフォルトで)水平分割してmanを開いてくれるようになる!

不満点その2

デフォルトの「K」だと、単にmanコマンドに制御を移しているだけなのでmanのページャが起動される為、Vim操作が出来ない。Vim操作が出来ないとman内で「*」検索ができないし、man中の説明に出てくるコマンドや標準関数のmanを更に引きたい場合に「K」コマンドが使えない。

→ manpageviewでは、manのページャがVimになるので上記操作が可能になる!

不満点その3

上記に関連するがページャがVimでない為、必要なインクルード・ファイルを確認したとき、"#include~"を「yy」でコピれない!
散々Vimでマウスを使うのはNGと言ってきましたが、このアドオンを知るまでは自分もこの時ばかりは渋々マウスでコピペしてました(もちろん納得はいかずこのアドオンを見つけるに至った)。

→ manpageviewでは、以下でコピペできるようになる!
インクルード・ファイルの行にカーソルを持って行き
yy」でヤンク(コピー)
C-w C-w」でフォーカス・ウィンドウをコードの方に切り替えて
gg」でソースの先頭行に移動して
}」でインクルード・ブロックの最下行に移動して
P」で貼り付けて
d0」で前の空白を消去(インデントを揃える)

インストール

インストール方法はここよりmanpageview.vba.gzをDLして、そのページにもあるように
$ vim manpageview.vba.gz
   :so %
   :q
とする。

普通のアドオンは~/vim/plugin/に配置すれば良いだけだが、manpageviewはいろいろ突っ込む必要があり、インストーラとしてVimスクリプトを用意してくれているので、インストール方法が異なる。
$ tree ~/.vim/
.vim/
|-- autoload
|   `-- manpageview.vim
|-- doc
|   |-- manpageview.txt
|   `-- tags
|-- plugin
|   `-- manpageviewPlugin.vim
`-- syntax
    |-- info.vim
    |-- man.vim
    |-- mankey.vim
    `-- manphp.vim

4 directories, 8 files




2009年4月14日火曜日

Vim: 「K」 カーソル下のフレーズのmanを引く

またまたカーソル下の単語に対してシリーズ。今回はmanを引く方法。
スクリプトを読んでいるときコマンドやそのオプション、Cのコードを読んでいるとき標準関数の引数、を調べたくなった場合、またコーディング中では標準関数の使用するヘッダ・ファイルを知りたい場合などでmanを引くことが良くあると思う。
ここでも、別端末にコピペしてmanを引くなんて行為はVimでは御法度!

Vimの正しい使い方は、そのフレーズ上にカーソルを持って行き、「K」を押す。これだけ!!
すると、そのmanが開く。これだけでもコードリーディングに集中できるようになるでしょう!

コードに戻る場合は、単にmanを実行中なだけなのでman操作に従い「q」を押しmanを終了させ、その後「続けるにはENTERを押すかコマンドを入力してください」と表示されるので、Enterを押せば良い。


ちなみに、manで良くあるFAQとしてprintf(1)とprintf(3)の引き方だが、コマンドラインではセクション番号を指定しない場合小さい方が優先される。
$ man printf
とするとコマンド(セクション1)のprintfのmanが開く。
標準関数(セクション3)のprintfのmanを開くには次のようにセクション番号を指定する必要がある。
$ man 3 printf

Vimの場合も同様で、printf上で「K」を押すとprintf(1)のmanが表示されてしまう。そこでprintf(3)のmanを表示したい場合は、「3K」とセクション番号を頭に付ける。

この操作方法は、「10j」とすると「j」10回分を意味するのと同じように、数値を指定したい時のVim操作の基本に沿っていると言える。



2009年4月12日日曜日

ページャとしてのview

UNIX系コマンドは結果を標準出力に出力するのが一般的だ。その出力量が端末の画面範囲を越えた場合パイプ経由でページャを使用することが多いだろう。
そこで皆さんはページャに何をお使いだろうか? more?less?lv?私は当然viewです!
それには単にVimerだからという以外にちゃんとした理由がある。

moreやlessやlvはページャなのでデフォルトで標準入力からの入力に対応してるが、Vimでは「-」というオプション(これはtarのと同じ)と共に起動すれば可能。
$ ps ax | view -


で、なぜVimかだが、今まで(+これから)紹介してきた機能が使えるからだ!
more等他のページャとエディタであるVimが決定的に異なるのは、カーソルという概念があるか否かである。
Vimの特徴であるカーソル下の単語に対しての検索やファイル・オープンが使えると、マウスの出番は廻って来ずに済む。


「*」の場合

例えば、マルチプロセスなプログラムのシステムコールをトレースした場合、ここで紹介した*」検索を使えば、同じPIDを追いたい時に先頭のPID上で「*」を押せば素早く追える。
*」が単語を表す正規表現を含んでいたことを思い出せば、ディスクリプ番号のみの検索も容易である。
$ strace -fF multi_process 2>&1 | view -
straceの場合はカラー表示にもなる!

また、objdump等でアドレスを追っていく場合でも「g*」で簡単に追える。
$ objdump -d my_prog | view -
更に関数名からtagジャンプもできる!



「gf」の場合

極めつけは、grepとの連携!
grepでソースコードやスクリプト、設定ファイル等を検索する場合、検索結果をVimで受けることで幸せになれる。

前回紹介したように「gf」とすれば、カーソル下のファイルが開けるのであった。そしてgrep結果の先頭にはファイルパスが! そう、検索結果から該当ファイルにジャンプできるのだ。
$ grep -nr pthread_ * | view -
再帰検索でも相対パスで表示されるので問題なく開ける。

だだし、上記「gf」だとファイルはオープンできるが、grepが出力する行番号にまでは跳んでくれない。
そこで、「gf」の代わりに「gF」を使うと、今度はちゃんと該当行にまで跳んでくれるようになる!

なお、標準入力から「view -」で受け取りファイルにジャンプ後「Ctrl-O」で検索結果に戻ろうとしても空ファイルになってしまう。これを回避したい場合は「:set hidden」な状態にしておけばOK!

さらに、開いたファイルの上でタグジャンプ等の移動コマンドを多用する場合など移動履歴のスタックが増え最初の検索結果に戻るのが大変になりそうな時は「Ctrl-W gF」で新規タブとして開いてから跳んでいくとよい。



2009年4月10日金曜日

Vim: 「gf」 カーソル下のファイルをオープン

前回に引き続きカーソル下の単語がある場合のTips。カーソル下の単語がファイルパスのとき「gf」とするとそのファイルをオープンできる。これはスクリプトを読んでいる時に出てくるファイルパスやCのインクルード・ファイルを見たいときに便利。
なので、端末をもう一つ開いてマウスでコピペしてという使い方はVimの正しい使い方ではない!


スクリプト

例えば、~/.bash_profile を view すると ~/.bashrc を読み込んでいる箇所がある。スクリプトを読む側としてはこの ~/.bashrc で何をしているのか気になるところだ。そこで ~/.bashrc 上にカーソルを持って行き「gf」と押してみよう。すると ~/.bashrc を開いてジャンプしてくれる!
$ view .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/binexport PATH


ジャンプした先の ~/.bashrc 内では更に /etc/bashrc を読み込んでいる。なので更にそこにカーソルを持って行き「gf」を押すと見事 /etc/bashrc にまで跳んでくれるのでっす!

戻る場合は、「Ctrl-^」や「Ctrl-O」を使う。(厳密には「Ctrl-O」は前のファイルに戻るという訳ではなく、直前のカーソル位置に戻る。一方、「Ctrl-^」は直前のファイルに戻るので、連続して実行すると2つのファイルを行ったり来たりしてしまい最初に開いたファイルには戻れない)
よって、/etc/bashrc まで跳んだ場合は「Ctrl-O」を2度押せば元の ~/.bash_profile に戻って来れるでしょう。


タブで開く

上述のように「gf」として開いて行った場合、最初の方に開いていたファイルに戻る為には辿ったスタックを一つ一つ戻る必要があり面倒に思うことがある。
そこで、「Ctrl-W gf」とすると、開こうとするカーソル下のファイルをタブで開いてくれる。
タブ間の移動は「gt」もしくは「gT」で行い、閉じる場合は普段通りに「:q」とする。

でも、開いていたファイルの左側のタブに開くのが違和感あり。感覚的に新規タブって右側でしょ?


Cコード

Cのコードの場合、プリプロセスで#includeされるヘッダー・ファイルの確認時等に使用できる。
「<>」で囲まれた標準ライブラリ関数のヘッダー・ファイルや「""」で囲まれたローカルなヘッダー・ファイルを開き定義等を確認したい場合も、カーソル下に持って行き「gf」とすればよい。

ちなみにインクルード・ファイルの検索パス設定は以下で確認できる。
:set path?
   ↓
  path=.,/usr/include,,
デフォルトではカレントdirと標準インクルードパスが設定されている。

従って、gccの「-I」でインクルードdirを指定してコンパイルするプログラムの場合は、この"path"に追加すれば「gf」でオープン出来るようになる。
また、クロスコンパイルする場合も検索パスにそのコンパイラの標準インクルードパスを加えればよい。


まとめ

このように、Vimでは気になったファイルパス記述があった場合、新たな端末を開いてファイルパスをマウスでコピペして別途開くという一連の面倒な作業を軽減してくれる(一度きり操作だったら苦にはならないとは思うけど何度も繰り返してたら地獄でしょ)。
何せマウスを使う行為は一度キーボードから手を離なし再度ホーム・ポジションまで持って来なくてはならないので、どうしても遅くなってしまうものだから。。


2009年4月9日木曜日

Vim: 「*」/「#」 カーソル下のフレーズを検索

Vimの好きなところはいくつもある。個人的な見解だがVi系ってキーを打たずに済むポリシーのように感じる。キータイプが遅い自分としてはそこが一番気に入っている。
キーを打たないとは、カーソル下の単語に何かをするのである。
その何かとは、例えば検索だったり、ファイルパスだったり、manだったりする。

今回はその中で「検索」についてのTips(まぁVi系の基本操作の部類に入ると思うけれど)。
検索したいフレーズがあった場合マウスでその単語をコピペして検索してませんか? Vim(gVimを除く)においてマウスを使う行為はVimを冒涜していると言っても過言ではないかもしれません(笑
なぜならVimではマウスなんて使う必要がないのだから!

検索したいフレーズにカーソルを持って行き(もちろんジャンプ系コマンドで素早く。矢印キー連打なんて厳禁ですぞ!)、おもむろに「*」を叩いて見よう。すると次の検索対象にジャンプすると共に他の検索対象がハイライトされるでしょう。次のに移動したけりゃ「n」、前のに移動したけりゃ「N」を押せばよい。

また、「*」が正順方向に検索したのに対し「#」を使うと逆順方向に検索する。n/Nの動作も逆になる。


ちなみにVimの最下行のステータス・ラインに現在検索中のフレーズが表示されるが、お気付きのように「\<\>」に囲まれた正規表現の「単語」になっている。
よって"proc"にヒットしても"process"にはヒットしないので目的の単語が素早く見つけられる。これはループカウンタによく用いられる「i」とか一文字の変数名等を検索するのに便利。

この正規表現が邪魔な場合は頭に「g」を付ける。「g*」とするとステータス行(?)にも上記の正規表現は付かず"proc"で検索しても"process"にもヒットするようになる。「g#」も同様に使える。


このように検索したい時は単語を打つ必要が無く、その単語上にカーソルを持って行き「*」を押して「n」を押していけば良いのである。ん~楽チン。


2009年4月5日日曜日

visdo, vim(root), view

sudoコマンドを使えるように設定

(ubuntuはsudoで全て行うポリシーなのでデフォルトで設定済みかと思うけど)
# visudo
...
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
okap    ALL=(ALL)       ALL
...

ちなみに、visudoは/etc/sudoersをviで編集しているだけだが、排他のため/etc/sudoers.tmpを編集している。vipwやvigrも同様に排他をかけている。

rootユーザでもvimを

Fedora(というよりRedHat)ではrootユーザではviがvimにリンクされていない。
「vim」と打てば良いだけだが意外と面倒である。(rootでvimを使うときって大概設定ファイルをいじる時だからカラー表示してくれるだけでも違う!)

そこで、rootでもviでvimが起動出来るようにする。
# vi /etc/profile.d/vim.sh
if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n "$ZSH_VERSION" ]; then
  [ -x //usr/bin/id ] || return
  [ `//usr/bin/id -u` -le 100 ] && return
  # for bash and zsh, only if no alias is already set
  alias vi >/dev/null 2>&1 || alias vi=vim
fi

このスクリプトを見ると、uidが100以下の場合は以降のaliasが設定されない。
rootは当然uid=0なので、その判定をコメントアウトしてしまう。
  [ `//usr/bin/id -u` -le 100 ] && return
                    ↓
# [ `//usr/bin/id -u` -le 100 ] && return

これで、この設定を読み込むか新しいセッションではrootでviとしてもvimが起動するようになる。

viewでもvimに

viewとは "vi -R" つまりRead-onlyでファイルを開くコマンドである。"view:眺める(Read-only)"と"vi"をかけているのだと思う(笑
Vimerが言うのも何だがvimでファイルを閲覧中にキーを触って(vimのコマンド・モードが幸いし)変更してしまうことがる。なのでソースやスクリプトを見るときはviewを使用している。
でも上記同様Fedoraでは、viewは一般ユーザでもviにリンクされているのでviewとしてもカラー表示されない。
# which view
/bin/view
# ll `!!`
ll `which view`
lrwxrwxrwx 1 root root 2 2009-03-23 17:54 /bin/view -> vi

なので、vimにリンクを張り直す。
# rm /bin/view
rm: remove シンボリックリンク `/bin/view'? y
# which vim
/usr/bin/vim
# ln -s /usr/bin/vim /bin/view
# ll `which view`
lrwxrwxrwx 1 root root 12 2009-04-05 22:19 /bin/view -> /usr/bin/vim

これで、新しいセッションではviewでもvimが起動するようになる。

ちなみにこのリンクでコマンド名を変える手法はbusyboxのに似ている。
lsなら、"busybox ls"と引数指定でも実行出来るけど、/bin/busybox を /bin/ls にリンクを張っておくと、lsで実行出来るようになる。argv[0]で判別しているのだと思う。