青の部隊 505小隊 ULZ

Vim日記

最終更新:

Bot(ページ名リンク)

- view
だれでも歓迎! 編集
Vimの進化っぷりに心奪われ、最近は疲れると仕事から逃避してせっせと.vimrcを修正しているぷんです。
そんなわけで、仕事に疲れるたびにVimの不思議な機能を発見しているので、それを日記形式で書いてってみようかと。


これまでのあらすじ・その1(初心者的Vim使用)

Vimを使い始めたのは入社1年目の新人研修が終わった直後。自分の机にあるWindowsマシンから、デバッグ室にあるLinuxマシン(開発用のテスト機)にTeratermでログインして、プログラミングとかをすることになった。
そのときに先輩方が使ってたのがVi。みんながみんなViだった。Viっつーと使いにくいエディタってイメージだったんだけど、別に誰も不便もしてないようなんで、倣って使うことにした。

このころ覚えて使ってた機能は以下。ほとんど使えてない。
  • モード変更。「i」で入力モードになり、「<ESC>」でコマンドモードに戻る。「:」でExモードになる。
  • 保存と終了。「:w」で保存。「:q」で終了。「:wq」で保存して終了。「:q!」で保存しないで終了。
  • 検索。基本的な「/」検索と、カーソル下の文字列を検索する「*」。
  • 一行コピーorカットandペースト。「yy」「dd」「p」。
  • 選択コピー。「V」「v」「Ctrl+V」で普通のエディタのように文字列を選択し、「y」でコピー、「d」でカット。
  • アンドゥとリドゥ。「u」でアンドゥ、「Ctrl+R」でリドゥ。
  • 一文字カット。「x」
  • 基本的な移動コマンド。「gg」ファイル先頭に移動。「G」ファイル末尾に移動。「(行番号)G」その行に移動。

これまでのあらすじ・その2(ctagsとcscope)

これまでプログラミングはずっとWindows上でIDEを使っていたので、エディタだけではきついだろうと思っていたのだけれど、ちゃんと補助機能はあった。ctagsとcscope。これがなかったら転職してたかも。

「ctags」
ソースコードを解析して、関数や変数、構造体などの定義位置をデータ化し、ファイルに保存するコマンド。
ソースディレクトリのルートで「$ ctags -R」と1コマンド叩くだけでOK。tagsというファイルが出来上がる。
vimでソースを読んでいて、定義を見たい関数や変数があったら「Ctrl+]」と押せば、vimtagsを見て、自動的に定義のあるファイルを開き、その位置まで飛んでくれる。そのあと、「Ctrl+T」を押せば元の位置に戻る。

「cscope」
CUIのソースコードブラウザ。起動するとメニュー画面になり、宣言や定義位置の検索、使われている箇所の検索、ある関数を呼んでいる関数の一覧表示、ある関数が呼ぶ関数の一覧表示、単に文字列の検索など、必要なことは大体できる。
一覧から好きなものを選択すれば、vimでファイルを開いてその位置まで飛んでくれる。

この二つがあれば、C言語の開発はそんなに不自由しないです。ただ、インテリセンス的なものが足りない感じはする。

さて、これらの機能は開発の初期に教えてもらってました。その後、実習にいったりWindows向けの開発したりしつつ、2年くらいはそんな感じで作業をしてました。
ところが最近、vimの新しいバージョンにインテリセンス的機能が追加されているとの情報をききつけた。使ってみたい!というわけでサイト検索したりヘルプ見たりしてると、実はそんな毛嫌いしなくてもちょっと覚えるだけで使える便利機能がたくさんあることが判明し、現在に至るわけです。


Teratermでフルカラー表示 2007/12位

Teratermでvimのフルカラー表示を有効にする方法。
TeratermはデフォルトでVT100という端末をエミュレートする。実際にはTeratermはVT100より高機能で、フルカラー表示などをサポートしてたりするんだけど、互換性を高めるため、Teratermはマシンに接続するときに、自分はVT100だと申告する。vimはそれを真に受けるので、最適なカラー情報を送信してくれず、結果的に中途半端なカラー表示になってしまう。
そこで今回は、Teratermでの接続だとvimに認識させ、カラー表示を実現する。

TeratermでLinuxマシンにログインし、環境変数TERMの内容を確認する。
$ echo $TERM
vt100
LinuxマシンもTeratermの設定もデフォルトのままであれば、おそらく上記のようになるはず。
vimはこの環境変数TERMで、端末の種類を確認している。というわけで、TERMをteratermに書き換えよう。
$ export TERM=teraterm
これだけでOK。このあと、vimで*.cを開くと、カラー表示が有効になっているはず。
本当はTeratermがちゃんと自分はTeratermだと申告してくれればいいんだけどね。なんか方法あるのかな???

ちなみに僕は、.bashrcに、もしTERMがvt100だったらteratermに変更する、という処理を追加して、この問題を回避してます。もっといい方法があれば教えてください。
C:\Program Files\teraterm\TERATERM.INI
; Telnet terminal type
;TermType=vt100
TermType=xterm
これでいけるっぽい噂。ウソなら消しておいてくれ。

いけますた。ありがとう。ちゃんとxtermがコメントアウとされてるんだね。
別にteratermを指定しなくても、xtermで問題なさげ。

ちなみに、vimが認識している端末名を確認したければ、'term'オプションの内容を表示してみればいい。
:set term
 term=teraterm

既にvimで開いたソースファイルをそのときだけフルカラー表示したいのであれば、その場で'term'オプションを書き換えればいい。
:set term=teraterm

2008/10/27追記
ずっとterm=xtermでつかってたけど。
term=xterm-256color にするともっときれいな色がでるっぽい。
vimdiffとか使うと結構画面全体がえぐい配色になるので、中間色でダメージを減らしましょう。

ちょっと便利なペースト(2007/12位)

ノーマルモードでコピペする方法は、viをかじった人なら誰でも知ってると思う。
yyで一行コピー、y{移動}で現在のカーソル位置から移動先のカーソル位置までをコピー。
pでカーソルの直後にペースト、Pでカーソル直前にペーストだ。

ところで、たまーにExモードでペーストしたくなることがある。例えば、テキスト中にあるファイル名を引数にしてコマンドを実行したいとか。
実は、Exモードでもペーストはできる。
<C-R>"
これで、直前にコピーorカットした部分をペーストできる。ちなみに、インサートモードでも同じことができるので、いちいちノーマルモードに戻るのが面倒って人も使ってみるといいと思うよ。
# ちなみに、「"」はレジスタ名です。


ついでに、直前に検索した語をペーストする方法も記載しておく。
ノーマルモードなら次のようにする。
"/p または "/P
インサートモードやExモードなら次のように。
<C-R>/
つまり、直前に検索した語は「/」という名前のレジスタにはいってるということです。

vimdiff(2008/1位)

vimでdiff表示する機能がある。これは実行ファイルとして用意してあって、その名は「vimdiff」。
2008/12/10 追記: 実行ファイルっていうか、シンボリックリンクなので語弊がありますね。

$ vimdiff old.c new.c
シェルで上記のコマンドを叩くと、左右2分割画面のvimが起動し、左にold.c、右にnew.cが表示される。単に二つのファイルを左右2分割で開いたのとはちょっと違う。
  • 二つのファイルが同じ部分は折りたたまれている。
  • 異なる部分の前後は折りたたまれず、色違いで表示される。
  • 一方に存在しない行は、「-----------...」と表示される。
  • どちらかのテキストをスクロールさせると、もう一方もスクロールする。

単なるdiffビューアとしてだけではなく、編集もできる。
たとえば、new.cのある部分をold.cに反映し、その部分のdiffを無くしたいとする。その場合、その部分までカーソルを持っていって、次のコマンドを入力する。
(new.cにカーソルがある状態で)dp
または
(old.cにカーソルがある状態で)do

ただ、このdiff表示、かなり重いんだけど……。もしかすると、GUI版のgvimならさくさく動くのかもしれないです。


Text object selection(2008/2位)

「*」でカーソル下の単語を検索することができる。これはすごく便利で、周りの先輩がみんな使ってたので知ってました。これが使いやすい点は、例えば「function(arg1,arg2)」という文字列があったときに、「func*tion(arg1,arg2)」の*の位置で「*」を入力すると、ちゃんと単語を認識して「function」を検索してくれるところ。
他にも単語単位の移動コマンドなどがあることからもわかるように、vimには単語を認識する機能が備わってる。

じゃあ、単語をコピーする機能もあるんじゃないか、と調べた結果見つけたのが、以下のコマンド。
yiw
これで、カーソルの下にある単語をヤンクできる。

この機能は"Text object selection"というらしい。ヘルプを見ると、微妙に動作が違ういろんな機能があるので要チェックです。詳しくは :h iw の周辺を読んでみてください。

ちなみに、selectionという名称だけあって、ビジュアルモードと組み合わせることが可能。
viw
とすれば、カーソルの下の単語を選択できる。ヘルプで興味のあるText object selectionを見つけたら、vと組み合わせてみると、動作を理解しやすいと思うよ。

2008/12/10 追記
そういえば、 ci( もかなり便利。ソース直してると、引数全部変えるとか、ifの条件総書き換えとかあるじゃないですか。
括弧の中でci(ってやると、括弧の中が全部消えて挿入モードになります。

インクリメンタルサーチ(2008/04)

インクリメンタルサーチって知ってますか?昔の検索機能って、検索語を入力し、エンターを押すと、初めて検索が開始されて、最初に見つかった語にジャンプします。これに対して、インクリメンタルサーチは、一文字入力するたびに検索が行われ、最初に見つかった語にジャンプする機能のことです。
vimにもこの機能があります。有効にするかどうかは個人の好みですが、一応やり方。
:set incsearch
これだけ。試しに使ってみて、気に入ればvimrcに登録してください。

ちなみに、最後に検索した語をすべてハイライトしっぱなしにするっていう機能もあります。
:set hlsearch

Exモードでのペースト(2008/04/30)

http://www.karashi.org/~poppen/d/20080412.html#p01
<C-R>"で張り付けていたが、<S-Insert>でもできるとのこと。
Teratermデフォルトだとできないかもしれないけど、試してみよう。

Teraterm+Vim+マウス(2008/11/24)

すみません、設計フェイズにはいっててしばらくコードさわらないうちに、この日記わすれてますた。
家のマシンでCygtermでVimつかってて、マウスが使えることに気づいた。
なんだこりゃ、Linuxにtelnet接続してるときはつかえねーぞ、と思ってたのだが、
本日昼休みに、オプションがあることに気づく。
:set mouse=a
これで、マウスを使っていろいろできるようになる。たとえば
  • カーソル移動(クリックでカーソル移動する)
  • 選択(ドラッグすると自動的にビジュアルモードになる)
  • ウィンドウ移動(ウィンドウを超えてカーソル移動する)

特にウィンドウ移動できるのはいいっすね。Ctrl-W連打だるかったんすよ。
でも、まだ慣れてないせいか、気がつくとキーボードだけで操作してるけど。

今、試すついでにヘルプみてますが、mapとかもできる様子。
ヘルプでダブルクリックしたらタグジャンプするし。
しばらくはこれで遊べそう。

2008/12/07 追記
:set ttymouse=xterm2
上記を加えておくと、screen経由でもマウスを使えます。
ただ、マルチウィンドウでステータスラインをドラッグしても、ウィンドウのサイズが変えられない。
ドラッグイベントがvimに届いていない気がする。teratermではできないんだろうか。。。。

2008/12/13 追記
PuTTYでやってみた。できるじゃないですか。こりゃ便利。
でも会社では、諸処の事情でTeraTermしか使えませぬ。

screen256色表示(2008/12/07)

Vimじゃないですが、いくらがんばってもできないと嘆いていたscreenの256色表示がついにできますた。

端的には、下記の記述を~/.screenrcに加える必要があった。
termcapinfo xterm* 'Co#256:pa#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm:'
attrcolor b ".I"
意味はわからない。termcapを勉強しないと。

もちろん、先人たちのサイトでも多く述べられているように、configureするときに--enable-colors256を指定するとか、
いろいろほかのこともやんないとだめなようです。しかし、もはや俺には何が必要で何が不要なのかわかりません。
上記の記述も、.screenrcに記載する順序とか、影響することが結構あるようなんだけども、
termcapがわかってないので、何が何だかさぱーり。

とりあえず、myへたれ.screenrcをさらしておく。
escape ^Jj
hardstatus alwayslastline "%w"
vbell off
shell bash

autodetach on
startup_message off

termcapinfo xterm* 'Co#256:pa#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm:'
termcapinfo xterm* 'is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l'
attrcolor b ".I"
defbce "on"
term xterm-256color

タブ!(2008/12/07)

vimの便利さに気づいた頃、メインで使ってたサーバのvimがバージョン6.3で、タブは使えないものと切り捨てていたんですよ。
しばらくして、どーしてもオムニ補完が使いたくなってvim7.1を導入したので、この時点でタブも使える状態に。
ところが、マルチウィンドウ覚えて有頂天になっていたせいか、タブのことはきれいさっぱり忘れてたんですね。

ふと先週の金曜に思い出して、タブをつかってみたところ、やっぱりタブも便利じゃないですか。

使い方その1:vim起動時に複数ファイルを開く
$ vim -p file1 file2 ...
タブでいっぺんに開きます。開きすぎに注意。(tabpagemax以上は開かないようになってますが。)

使い方その2:新しいタブでファイルを開く
:tabnew  file1
:tabedit file1
:tabe    file1
どれでもOK。

使い方その3:タブ移動
大きく分けて、やり方は3種類。あ、4種類か。

① CTRL+PageUp/Down
② gt/gT
③ :tabnext/:tabprev
④ マウスでタブをクリック

私はワンキーで移動したいのでCtrl+PageUp/Downが使いたいところですが、
なんかうちの環境だとデフォルトでは認識してくれなかったので、
設定見直しのついでに、どうせ使っていないPageUp/PageDownに直接割り当てることにしました。
nnoremap <PageUp>   <C-PageUp>
nnoremap <PageDown> <C-PageDown>

使いたてですが、とても快適ですよ。
2008/12/10 追記
やっぱPageUp/Downのキーが遠すぎて使いにくいっす。gt/gTの方がいいかも。

クイックフィックスウィンドウでcscope(2008/12/07)

vimとctagsを組み合わせる方法は皆さんご存じでしょう。
ctagsコマンドでtagsファイルを作っておいて、vimでソースファイルを開き、
関数コール部で関数名の上にカーソルを置き、CTRL+]。
これで関数に飛びます。戻るときはCTRL+T。

しかしこれ、逆に検索したいときが多々あります。
つまり、ある関数を読んでいて、この関数をコールしているところを探したい!っていうこと。
普通はcscopeを使うんですけど、なんというか、ちょっとめんどい。
ちょっとかんがえてみると、これはクイックフィックスウィンドウの出番ですよ、ってことに気づく。
そこでちょいと調べてみると、ありますね、cscope-quickfixという機能が。
vimをメイクするときにオプション指定しとかなきゃならんそうです。……してないけど。
2008/12/10 追記
嘘つきました。オプション指定されてました。cscopeとquickfixウィンドウが有効になってればよさげ。
でも、どちらにしても、cscope-quickfixはいまいち使いにくい感が否めない。使い方、もうちょっと考えてみます。

もう一つの手段として、cscope with quickfixっていうプラグインがありました。
これを使ってしまいましょう。


ゲットしたcscope_quickfix.vimを ${HOME}/.vim/pluginの中に放り込んでください。
(cscope.outはすでにあると仮定)関数名の上でおもむろに Ctrl+\ c。
quickfixウィンドウが開き、関数コール部が一覧表示されます。便利。


そうだ。いつ覚えたか忘れたけど、:makeコマンドも書いとこう。
ソースコード修正したら、いちいちシェルに戻らずに、おもむろに:makeコマンドを実行しましょう。
エラーがなければ何もないんですが、エラーがあった場合にはquickfixウィンドウが開き、
makeの出力が表示されます。
このとき、エラーメッセージの上にカーソルを置いてEnterすると、その箇所に飛んでいってくれます。

ソース修正後の:wを忘れずに。


PuTTYとw3m(2008/12/13)

いやあこれはこれはすばらしい。
上のほうのマウスの項にも加筆したんですが、PuTTYを使ってみたんですよ。
ほんで、フルスクリーン表示があるのに気づいたんですね。
フルスクリーンにしてみたら、これはみやすい、と。

でも、フルスクリーンにしたらブラウザとかがみえない。
ほんで、w3mとか入ってるっけなぁと思い立って起動してみたら、
w3mって超便利。wikiの更新がVimでできるじゃないですか。
使ったことないも同然だけど、キーバインドもViベースだし、
ちょっといじくってみようかな。


各行の同じ位置に同じ文字列を挿入(2009/02/14)

状況が一言で説明できないんだけど、たとえば、
printf("a\n");
printf("b\n");
printf("c\n");
fprintf( fp, "a\n");
fprintf( fp, "b\n");
fprintf( fp, "c\n");
に変更する方法。
まず、C_VでVisualBlockモード(矩形選択モードっていうとわかるかな)にはいり、先頭のpを三行分選択します。
次にIで挿入モードに入ります。このとき、選択を表す矩形は消え、一行目のpにカーソルが来て、挿入モードになります。
続けてfをうちましょう。このとき、一行目しか編集していないように見えますが、心配無用。
最後にESCを押して挿入モードから抜けると、2行目と3行目にもfが挿入されます。
同様に、先頭に近いダブルクォーテーション3つをビジュアルブロックで選択し、Iを押し、「 fp, 」と入力し、ESC。

こういう操作は、置換を使ったり、qのマクロを使ったりしてましたが、この方法を覚えてからはこれを使うことが多くなりました。
この方法は、なんとなく、直感的に操作しやすい感じがします。



雑記

とりとめなく書いてきたけど、すんげー読みにくい文章だし、分量もたまってきたら、
もうそろそろまとめようかなぁ。
よくみると、オムニ補完のこと書いてないし。

↓これ、調査中に見つけたとてもわかりやすい解説。こーゆーの作りたいよね。とか言ってると挫折するんだけどね。
PuTTY + screen + Vim + マウスが便利すぎるキャプチャ



使ってて思ったこと。
GUIのエディタって、メニューがついていて、そこからすべての機能にアクセスできて、
たいていの機能にはショートカットが割り当たっている。
最初はメニューをちょろちょろみながら機能を試してみて、便利な機能でよく使うものはショートカットを覚える、
ってかんじの使い方だと思うのです。
そもそも、エディタなら必ず備えてる機能には、どのエディタでも同じショートカットが割り当たっている、と。

vimやemacsの場合は、メニューなんてものはついてなくて、ヘルプをみるとショートカットが書いてある。
つまり、ショートカットの使用を強制されるわけ。
大量のショートカット強制的に覚えさせられたら、そりゃあすんげー便利に決まってるし、
それらはほかでは使えない独自の変態ショートカットだから、ほかのエディタは使えなくなるに決まっとるがな。

タグ:

+ タグ編集
  • タグ:
添付ファイル
ウィキ募集バナー