ホーム‎ > ‎VimとUTF-8‎ > ‎

はじめてのvi

はじめに

とりあえず vi/Vimを使ってみたいという人に向けて、ファイルのセーブ&ロード、簡単な編集と終了など viの使い方について入門方法を書いてみました。
以下に出てくる <C-h> のような表記は Ctrl+hというようにCtrlキーとの同時押しを表します。
また(viにはありません)と書かれているコマンドについてはVim(またはVimクローン)でのみ使用可能です。


モード

viは目的別にモードが分かれています。
「ノーマルモード」ではキー入力すると文字が挿入されるのではなく、対応したコマンドが実行されます。
基本は「ノーマルモード」でカーソル移動して「挿入モード」で入力です。

ノーマルモード
 移動・編集
挿入モード  文字入力
コマンドモード
 ファイルのロードやセーブ、置換、終了などのコマンドを実行
ビジュアルモード
 文字列を視覚的(ビジュアル)に選択
 (viにはありません)
* 「コマンドモード」は正確にはコマンドウィンドウへの移動を意味します。

わからなくなったらとりあえず <ESC> を連打すればノーマルモードへ戻れます。

<ESC>
 キャンセル。最重要。困ったら連打
<C-[>
 <ESC>同等キー
 <C-c>  現在の処理を強制終了(<ESC>でもどうしようもない場合にのみ使用します)
  <C-c>は強制終了なので、その後の動作がおかしくなることがあります。

ファイルのロード

ノーマルモードで : を入力するとコマンドウィンドウ(コマンドモード)に入ります。
コマンドウィンドウからは ファイルのロードやセーブ、置換、終了などのコマンドを実行します。

:e

 ファイルをロード。 (e)dit
 :e hoge.txtでカレントディレクトリのhoge.txtを開く
 ファイル名の入力中は tabで補完が効きます。
:e!  !を付けると編集中のファイルであっても再読込します。
:cd  カレントディレクトリを移動。

GUI環境ならメニューやツールバー、ドラッグアンドドロップでもロードできます。
もちろんコマンドラインからファイル名指定も可能です。

$ vi hoge.txt


Vimでは:e .でファイラ(netrw)が起動するのでファイル名がわからない場合や別ディレクトリのファイルを開きたい時は便利かもしれません。
 .  はカレントディレクトリを意味しています。

ファイルのセーブと終了

ファイルの保存や終了はコマンドウィンドウ(コマンドウモード)から行います。

:q
 :q!
 終了。 (q)uit
 !を付けると編集中のファイルがあっても強制終了します。
:w
:w!
 保存。 (w)rite
 !を付けるとリードオンリーでも強制保存します。

わからなくなったら<ESC>を押してノーマルモードへ移動してから:q!でファイルを保存せずに終了できます。
また:wqで「保存して終了」が一度に行えます。

Vimで複数ファイルを開いている場合は all の a を付けることで全バッファに対して処理を行うこともできます。

:qa
 :qa!
 全終了。
 !を付けると編集中のファイルがあっても強制終了します。
:wa
:wa!
 全保存。
 !を付けるとリードオンリーでも強制保存します。

カーソル移動(モーション)と文字入力

vi/Vimを起動すると「ノーマルモード」から始まります。
前述しましたが、基本は「ノーマルモード」でカーソル移動して「挿入モード」で入力です。

カーソル移動(モーション)

w b e
 単語単位で移動
 (w)ord
 (b)ack word
 (e)nd of word
h j k l
 文字単位で移動
 h l 左右
 j k 上下
<C-f>
<C-b>
 画面単位で移動
 (f)orward screen
 (b)ackward screen

2w のようにカウント指定すると 2単語先へ移動します。
2 w(ords) というような感じです。
同様に 3行下なら 3j のようにカウント指定します。

カーソル移動コマンドは他にも沢山ありますが、とりあえずこれだけ覚えておけば移動の効率はともかく一応困らないはずです。
カーソル移動は今時の環境ならマウスやらカーソルキーも使えます。

指定行へ移動


G
 最終行へ移動。 (G)o
 カウント指定すると指定行へ移動する。
gg  一行目へ移動(1Gと同等)
 カウント指定すると指定行へ移動する。
 (viにはありません)

23gg14Gのようにカウント指定すると指定行へ移動します。
カウント指定する場合コマンドに差はありません。

文字入力

カーソル位置へ文字を入力したい場合は、必ず挿入モードへ移行して入力を開始します。

i
 挿入モードへ
 (I)nsert
a
 カーソル位置の一文字後に移動してから挿入モードへ
 (a)ppend

文字入力が終わったら <ESC>でノーマルモードへ戻ります。
なお 3iHoge<ESC> のようにカウント指定して実行すると HogeHogeHoge のように指定カウント分繰り返して入力されます。

編集

カーソルを編集したい位置へ移動したら、編集コマンドを実行します。

c
 変更 (c)hange
d  削除 (d)elete
dd
 行単位の削除

c で変更、 d なら削除です。
c d は「カーソル移動(モーション)」や「検索」と組み合わせて使います。

cw
 カーソル位置から次の単語まで変更
cl
 カーソル位置の文字変更
 (実際には互換コマンドの s を使用した方がよいでしょう)
dw  カーソル位置から次の単語まで削除
dl
 カーソル位置の文字削除
 (実際には互換コマンドの x を使用した方がよいでしょう)

c のばあいカーソル位置の単語(文字)を削除してから挿入モードへ移行するので、変更したい文字を入力して <ESC>を押します。

カウント指定すると指定分の文字を処理します

d2w  カーソル位置から2単語削除
2dd
 カーソル位置から2行削除
3s
 カーソル位置から3文字を変更(3cl や c3l と同じ)

d(elete) 2 w(ords) とかやるわけですね。
ちなみに c2w2cw はおなじ動作になります。
また文字削除は 3dld3l のように実行すると3文字削除が可能ですが 3x と実行した方が簡単です。

アンドゥ/リドゥ

編集を取り消したり、再実行可能です。

u
 アンドゥ (u)ndo
<C-r>  リドゥ

カウント指定すると指定分だけアンドゥ/リドゥします。
Vim/Vimpulseのアンドゥは複数回実行可能ですが、viのアンドゥは一回だけです。

編集の繰り返し

.
 最後の編集を繰り返す

  . を押すと最後の編集を繰り返します。
cwfuga<ESC> でカーソル位置の単語を fuga に変更した後に移動して . を押すと、現在のカーソル位置の単語を fuga に変更します。
簡単なキーボードマクロのような物ですが、かなり汎用的で相当役に立ちます。
例えば検索と . による「編集の繰り返し」を組み合わせて利用すると単語の置換が簡単に行えます。
数値指定も可能なので ihoge<ESC>でhogeを入力した後 9. で更に9回hogeを入力するというようなこともできます。

<ESC>に次ぐ重要コマンドと言って良いかもしれません。


ヤンク(コピー)&ペースト


y
 ヤンク(コピー) (y)ank
yy
 行単位のヤンク(コピー)

y はヤンク(コピー)です。
c d 同様にモーション指定します。
例えば yw であればカーソル位置から次の単語まで(空白を含む)がヤンクされます。
yy は行単位のヤンクで 9yy とやるとカーソル位置から9行ヤンクされます。

ヤンクしたら pP で貼り付けます。

p
 カーソルの後に貼り付け (p)aste
P  カーソルの前に貼り付け


viにはありませんが、Vim等でノーマルモードでvを入力するとビジュアルモードになります。
ビジュアルモードでカーソルを移動すると選択中の範囲が反転等で表示され、その状態で y を押すと選択範囲がヤンク(コピー)されます。
同様にビジュアルモードを使用すると、選択範囲に対して各種コマンドを実行することが可能です。

検索

/ で文字入力すると検索が開始されます。
<CR>で確定してからは n N で検索を繰り返すことが出来ます。

/
 検索文字列の入力
n
 順方向に再検索 (n)ext
N
 逆方向に再検索

* を押すとカーソル位置の単語を拾って検索します。

*
 カーソル位置の単語を拾って検索

* の後でも n N で再検索可能です。

なおデフォルトで正規表現が有効なので必要なら \ でエスケープしてください。

正規表現について

正規表現は各実装で異なる部分があります。
特にVimの正規表現は高機能ですが独自拡張されているところがあり、高度な検索を行う際には気をつける必要があります。

置換

置換は : を押してコマンドウィンドウ(コマンドモード)へ移行してから s コマンドで行います。
現バッファ内の全ての hoge を fuga に確認を取りながら置換するのは以下のようになります。

:%s/hoge/fuga/gc

最初の % で現バッファの全行を対象にしていますが、s だけなら現在のカーソル行またはビジュアルモードで選択した行が指定範囲になります。
最後の gc でフラグ指定していて 「行内の全て(global)」を「確認して(check)」置換します。
g が無い場合は最初に見つかった一つの置換対象のみ置換されます。

行番号を指定する場合は , で区切って指定します。(Vimならビジュアルモードで指定後にsでも可能)
10-21行のhogeをfugaに確認を取りながら置換
:10,21s/hoge/fuga/gc


/ や正規表現が置換対象文字列と置換文字列に含まれる場合は \ でエスケープしてください。

(path/toをnew/pathに置換する例)
:%s/path\/to/new\/path/g

正規表現について

正規表現は各実装で異なる部分があります。
特にVimの正規表現は高機能ですが独自拡張されているところがあり、高度な置換を行う際には気をつける必要があります。

マルチバッファ(複数ファイルの切替)

viにはありませんが、Vimでは複数ファイルを開いて切り替えが可能です。
Vimはバッファという単位でファイルを管理していて、基本的には1ファイルが1バッファに対応しています。

:ls
:buffers
 バッファリスト
:b {num}
:b#
 {num}で指定した番号のバッファを表示
 b# は前回表示したバッファへ切替
:bn  次のバッファへ移動
:bp
 前のバッファへ移動

またVimではウィンドウを分割して複数ファイル表示も可能です。

<C-w>s
<C-w>v
 ウィンドウ水平分割 (s)plit
 ウィンドウ垂直分割 (v)ertical
<C-w>c
:q
 ウィンドウを閉じる


実際問題としてバッファ移動を数値指定で行うのは面倒なので、Vimではプラグインと呼ばれる拡張スクリプトを使用するのが楽かも知れません。(bufexplorerなどがよく使われているようです)
個人的にはmru.vim(最近使用したファイルリストを表示)というプラグインを改変して使用しています。
mru.vim改変版

その他のコマンド

viにはたくさんのコマンドがあります。
行末への移動は $ ですし、画面の最下行へ移動したい場合は L が使えます。
typo を type に修正するような場合、これまで紹介したコマンドだけだと o の上へカーソル移動して cwe<ESC>se<ESC> のように複雑なコマンドが必要になりますが、実際には r コマンドで一文字修正という具合によく使うような作業には専用コマンドが用意されていたりします。
なにか不便だとか面倒だと思ったら、大抵はコマンドが用意されているので調べてみて下さい。

Vimの場合は非常に充実したヘルプがあるのでヘルプを読む事をおすすめします。
vimtutorというチュートリアルも大抵は使えるようになっています。

コマンドは基本的に機能を表す英語の頭文字になっていますので英語のチートシートを見るのもおすすめです。
vi/vim cheet sheet
http://www.viemu.com/vi-vim-cheat-sheet.gif
(サイトに問題があったようなのでファイルをミラーしています)

チートシートは他にも色々あるようですので、好みの物を探してください。


市販の入門書としては「入門vi 第6版(amazon)」が訳自体も読みやすくチートシートもついているのでおすすめです。
表面的なコマンド解説だけの本ではないので viを理解するために最適な一冊と思います。
第6版では viだけでなく Vimについても触れられています。

入門vi 第6版


入門vi 第6版 (amazon)

リンダ・ラム アーノルド・ロビンス
オライリー・ジャパン






設定やカスタマイズ等は本サイトでも扱っています。

Vim
vim UTF-8日本語版
vimのカスタマイズとTips

終わりに

最後に余計なお世話ですが、viを覚える上での心構えみたいな物について書いておきます。
余談ですので以降を読む必要は特にありません。

viを使う上での原則は
「中の人(vi)に命令することを意識する
だと思います。

他のエディタと違ってviは「命令する」エディタで、「操作そのものを自分で直接実行しない」エディタだと考えています。
他のエディタでは自分でカーソルを移動させて編集するイメージですが、 viでは「画面一番下の行へ移動しろ」とか「この位置から2単語分を削除しろ」とか「中の人」に命令するイメージになります。
最初はちょっとまだろこしく感じるかもしれません。

しかし、ちょっと考えてみると、これはものすごく強力な方法であることがわかると思います。
「中の人」が使える奴ならこれ以上便利な物はありません。
他のエディタでも同じようなことはありますが、viは特に「中の人」で使い勝手が違ってくるエディタです。

たとえば画面一番下の行へ移動する方法はいくつかあります。
  • j を押しっぱなしで一番下まで移動する
    8jのようにカウント指定して移動するほうが少しだけスマートです :-)
  • 28gg のように行番号指定で移動する
  • Lで移動する
もちろん実際には「中の人」がいないので、カーソル移動などの具体的な方法は自分で考えて実行する必要があります。
画面の最終行から一行上にある行に移動したいなら、Lを押してからkですが、そこがたまたま最下行であって、特定の単語に移動したいのなら / コマンドで移動するべきでしょう。
常に自分のやりたいことに対して、どれが最適かを考えて移動方法を選んでください。
大抵の編集はパターンが決まっているので、慣れてくると考えなくても最適な移動方法を選ぶことが出来るようになります。

最初は速度を気にせずにパズルでも解くような気分で「どうすれば効率よく編集できるか」だけを考えてください。
そのうち、本当に「中の人」に命令しているように無意識に編集できるようになります。
そうなったら信じられないくらい楽に効率よく作業できるはずです。

また viだと非常に手が楽です。
特に他のエディタでカーソル移動にCTRLキーを多用しているならかなり楽になる、という事は言えます。
個人的にはスペースキーを画面送りに設定していて、主にスペースキーをバンバン叩いて移動して編集というあまり頭の良くない方法で使っていたりしますが、効率はともかく少なくとも手はかなり楽です :-P

最初のうちは(挿入モードでも)マウスやカーソルキーを使ったりしてもかまいません。
「できるだけマウスやカーソルキーを触らない」、「挿入モードには長居しない」ということだけ意識して使ってみてください。
いずれそのうちマウスやカーソルキーに手を伸ばすのが面倒になります :-P

また vi系のエディタでは日本語を扱うのが面倒だと言われる事が良くありますが、viはともかく Vimは設定さえ行えばさほど問題ではありません。
vimと日本語
私は日本語文書を大量に書く必要があるのですが、むしろ他のエディタより楽になりました。

もしこれからテキスト編集に長時間を割く予定があるというのであれば viは覚えて損のないエディタだと思います。
特にプログラマの場合はサーバ管理やgit等でvi(Vim)を扱うことがあるはずなので、このページにあるコマンドぐらいは、覚えておいて損はしません。


個人的なおすすめ

スペースキーでスクロール

Space で一画面スクロール、 Shift+Space で一画面逆スクロールみたいにするとまるでブラウザみたいになります。
<C-f> と <C-b> でもいいのですが、押しやすさが断然違います。
これはブラウザを立ち上げてテキストファイルを読んで、必要になったら挿入モードに移行する様なイメージで、意外と viに慣れるためのいいステップかもしれないと思います。
早い話が viはテキストエディタではなく、テキスト用ブラウザなのだと考えるとしっくりくるかもしれません。
なんにせよスクロールするのにスペースキーだけですむのって楽だと思いませんか。

以下を設定ファイルに追加します。
  • Vim
    .vimrcに追加します(端末で<S-SPACE>は使えないことがあります)
" Spaceキーで画面スクロール
nnoremap <SPACE>   <PageDown>
" Shift+Spaceキーで画面逆スクロール
nnoremap <S-SPACE> <PageUp>
;; Spaceキーで画面スクロール
(define-key viper-vi-global-user-map [?\ ] 'viper-scroll-screen)
;; Shift+Spaceキーで画面逆スクロール
(define-key viper-vi-global-user-map [?\S-\ ] 'viper-scroll-screen-back)

ZZを無効化

viのノーマルモードには ZZ という全て自動保存して終了するコマンドがあります。
ZZは単純に危険なので慣れないうちは無効にしておいた方がよいのではないかと思います。

これは取り返しの付かない(アンドゥ出来ない)結果になるコマンドだからです。
ノーマルモードにいることに気がつかず 「ZZガンダムが……」と書こうとしただけで他のファイルまで全て上書き保存して終了されたら結構ダメージ大きくないですか?
  • vi/Vim
map ZZ z.
  • Vim
" 強制全保存終了を無効化
nnoremap ZZ zz
;; 強制全保存終了を無効化
(define-key viper-vi-global-user-map ZZ 'viper-nil)

vim 7.3以降では終了後も継続可能なアンドゥが実装されていますが、デフォルトでは有効ではありません。
ZZガンダムはともかくとして Capsロックがかかっているのに zz コマンドを実行しようとしてひどい目にあった新人さんを知っています :-P


Comments