前回は 基本的な移動 を紹介しました、今回はより高度な移動を紹介し、更に速やかにジャンプしましょう。
1.ジャンプ・テーブルを使う
Vimにて、色んなコマンドはカーソルをジャンプ(移動)させます。Vimはジャンプ前のカーソルの位置をジャンプ・テーブルに記録し、このジャンプ・テーブルを使う幾つかのコマンドを提供しています。具体的にどういうコマンドはジャンプをさせるか「:help jump-motions」を参照します。ジャンプ・テーブルを確認するのは「:jumps」です。
「’’」と「``」は最近のジャンプ位置に戻ります。例えば、今カーソルは1234行にあります、「G」コマンドで4321行へ移動しました。この時、「’’」または「``」を使って1234行へ戻ります。この二つも移動コマンドですので、4321行もジャンプ・テーブルに記録され、もう一度「’’」または「``」を押すとカーソルは1234行に戻ります。
この二つの違いは、「``」は前回の列まで戻るが、「’’」は前回の行のはじめの空白でない文字に戻ります。
もっと古いジャンプ場所へ戻るには「CTRL-O」を使います。これと逆に、「CTRL-I」はもっと新しいジャンプ場所へ移動します。この二つのコマンドも数字を入れて倍数を指定できます。関連ヘルプは「:help CTRL-O と :help CTRL-I」
2.マークを使う
マーク(mark)はVimのより精度の高いジャンプ技術です。マーク名を指定すれば、直接該当マークへ移動できます。
Vimのマークは全て名前を持っています。この名前は一つの文字からなります。大文字と小文字のアルファベット(A-Za-z)はマーク名として使えます。これらのマークの場所はユーザから設定できます。名前は数字と符号のマークは、ユーザから設定できません。ここではアルファベット・マークについて説明します、数字と符号マークは「:help mark-motions」を参照してください。
小文字アルファベット・マークのスコープはバッファです。各バッファの小文字マークは同じ名前を使っても構いません。例えば、AとB二つのファイルにそれぞれ t というマークを設定した場合、Aファイルの中で「’t」コマンドはAファイルのt位置へ移動します。同様に、Bファイルの中で「’t」コマンドはBファイルのt位置へ移動します。バッファ・リストから、ファイルを削除すれば、小文字マークも消えます。
大文字マークはグローバル・マークで、スコープはファイルです。AファイルにTマークを付けた場合、編集中のファイルに関らず「’T」はAファイルのT位置へ移動します。
指定のマークへ移動する時、「’{a-zA-Z}」或いは「`{a-zA-Z}」を使います。例えば、「’t」はマークtへ移動します。前回にも紹介した通り、「’」と「`」の違いは、「’」はマークした行の一番目の空白でない文字へ移動するのに対し、「`」はマークした行のマークした列まで移動します。
マークの付け方は簡単です。「m{a-zA-Z}」を使います。例えば、「mt」はカーソルにある位置をマークtに付けます、「mT」はカーソルにある行をマークTに付けます。関連ヘルプ「:help m」。
マークを削除するには、「:delmarks」を使います。「:marks」コマンドは全てのマークを表示します。
3.マーク関連のプラグイン
マークについて、よく使うプラグインは二つあります。ShowMarks と marks browserです。
3.1 ShowMarks
ShowMarks はマークの位置をハイライトします。マークを付ければ、ShowMarksはマークの名前を表示し、マークした行をハイライトします。
ShowMarksのインストールについて、http://www.vim.org/scripts/script.php?script_id=152 からShowMarksをダウンロードし、$HOME/.vimに解凍します。
私のvimrcに、以下のようにShowMarksを設定しています。
""""""""""""""""""""""""""""""
" showmarks setting
""""""""""""""""""""""""""""""
" Enable ShowMarks
let showmarks_enable = 1
" Show which marks
let showmarks_include = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
" Ignore help, quickfix, non-modifiable buffers
let showmarks_ignore_type = "hqm"
" Hilight lower & upper marks
let showmarks_hlline_lower = 1
let showmarks_hlline_upper = 1 |
少し説明しましょう。まずはShowMarksを有効にします、そしてアルファベットのマークしか表示しないようにします。help、quickfixと編集不可のバッファについて、マークを表示しない。
ShowMarksは幾つかのキーバインドを定義しています。
| <Leader>mt |
ShowMarksを有効/無効にする |
| <Leader>mo |
強制的にShowMarksを有効にする |
| <Leader>mh |
作業行のマークをクリア |
| <Leader>ma |
作業バッファの全てのマークをクリア |
| <Leader>mm |
次の有効なマーク名を使って作業行をマーク |
私はよく使うのは <Leader>mm と <Leader>mh です。
Vim 7.0 にて、大文字のマークがあれば、内部関数line()はほかのバッファにても該当マークの行番号を返すため、ShowMarksは全てのバッファに、この大文字のマークを表示してしまいます。以下のパッチを見つけた、このパッチを適用することでこの問題を対応します。
パッチの内容は以下の通りです。
--- easwy/showmarks.vim 2007-03-13 10:15:07.000000000 +0800
+++ plugin/showmarks.vim 2007-03-23 09:35:01.000000000 +0800
@@ -144,6 +144,25 @@
hi default ShowMarksHLo ctermfg=darkblue ctermbg=blue cterm=bold guifg=blue guibg=lightblue gui=bold
hi default ShowMarksHLm ctermfg=darkblue ctermbg=blue cterm=bold guifg=blue guibg=lightblue gui=bold
+" Function: GetMarkLine()
+" Authors: Easwy Yang
+" Description: This function will return the line number where the mark
+" placed. In VIM 7.0 and later, function line() always returns line number but
+" not 0 in case an uppercase mark or number mark is placed. However, in VIM 6,
+" it only returns 0 when the uppercase mark isn’t placed in current file.
+fun! s:GetMarkLine(mark)
+ if v:version < 700
+ let lnum = line(a:mark)
+ else
+ let pos = getpos(a:mark)
+ let lnum = pos[1]
+ if pos[0] && bufnr("%") != pos[0]
+ let lnum = 0
+ endif
+ endif
+ return lnum
+endf
+
" Function: IncludeMarks()
" Description: This function returns the list of marks (in priority order) to
" show in this buffer. Each buffer, if not already set, inherits the global
@@ -354,7 +373,8 @@
let c = strpart(s:IncludeMarks(), n, 1)
let nm = s:NameOfMark(c)
let id = n + (s:maxmarks * winbufnr(0))
- let ln = line("’".c)
+ "let ln = line("’".c)
+ let ln = s:GetMarkLine("’".c)
if ln == 0 && (exists(’b:placed_’.nm) && b:placed_{nm} != ln)
exe ’sign unplace ’.id.’ buffer=’.winbufnr(0)
@@ -393,11 +413,18 @@
let s:maxmarks = strlen(s:IncludeMarks())
while n < s:maxmarks
let c = strpart(s:IncludeMarks(), n, 1)
- if c =~# ’[a-zA-Z]’ && ln == line("’".c)
+ "if c =~# ’[a-zA-Z]’ && ln == line("’".c)
+ if c =~# ’[a-zA-Z]’ && ln == s:GetMarkLine("’".c)
let nm = s:NameOfMark(c)
let id = n + (s:maxmarks * winbufnr(0))
exe ’sign unplace ’.id.’ buffer=’.winbufnr(0)
- exe ’1 mark ’.c
+ " Easwy, we can really remove marks in VIM 7.0 and later
+ if v:version >= 700
+ exe ’delm ’.c
+ else
+ exe ’1 mark ’.c
+ endif
+ " Easwy, end
let b:placed_{nm} = 1
endif
let n = n + 1
@@ -417,7 +444,13 @@
let nm = s:NameOfMark(c)
let id = n + (s:maxmarks * winbufnr(0))
exe ’sign unplace ’.id.’ buffer=’.winbufnr(0)
- exe ’1 mark ’.c
+ " Easwy, we can really remove marks in VIM 7.0 and later
+ if v:version >= 700
+ exe ’delm ’.c
+ else
+ exe ’1 mark ’.c
+ endif
+ " Easwy, end
let b:placed_{nm} = 1
endif
let n = n + 1
@@ -466,7 +499,8 @@
while n < s:maxmarks
let c = strpart(s:IncludeMarks(), n, 1)
if c =~# ’[a-z]’
- if line("’".c) <= 1
+ "if line("’".c) <= 1
+ if s:GetMarkLine("’".c) <= 1
" Found an unused [a-z] mark; we’re done.
let next_mark = n
break |
以下は適用方法です。
1. 上記パッチを適当なフォルダに保存する。例:/tmp/showmarks.vim.patch
2. $HOME/.vimへ移動する。cd ~/.vim
3. パッチを適用する。cat /tmp/showmarks.vim.patch | patch -p0
3.2 Marks Browser
Marks Browser は作業バッファの小文字マークを表示します。
http://www.vim.org/scripts/script.php?script_id=1706 からダウンロードし、$HOME/.vim/plugin フォルダに解凍すればインストールは完了します。
私のvimrcにはこういう風に設定しています。
""""""""""""""""""""""""""""""
" markbrowser setting
""""""""""""""""""""""""""""""
nmap <silent> <leader>mk :MarksBrowser<cr> |
「,mk」を押せばMark Browserウィンドが開きます。
以下はShowMarksとMarks Browserのイメージです。
このファイルにマークを三つ付けました。大文字A、小文字aとt。画面上部はMarks Browserウィンド、メイン編集区域のハイライトとマーク名はShowMarksの効果です。

4.折畳み
ファイルが大きくなると、移動も難しくなります。この場合、暫く見ない内容を折畳むことで、ファイルが見やすくなり、移動もしやすくなります。
Vimの折畳み方式について、手動で折畳む以外、インデント、文法、式などによる折畳みもできます。ソースファイルは文法による折畳みを選んだほうがいいでしょう。
折畳み機能を有効にするには「foldenable」オプションを使います。「foldmethod」オプションは折畳み方式を設定します。ソースファイルについて、文法ハイライトによる折畳みを使います。たま、文法ハイライトによる折畳みを使うには、ファイルタイプ認識とハイライトを有効しなければなりません、詳しくは 8.ファイル・タイプ認識 と 9.多彩なVim を参照します。
以下は私のvimrcの設定です。自動コマンドを使って、ファイルタイプがc又はcppの場合、文法による折畳みを行います。
| autocmd FileType c,cpp setl fdm=syntax | setl fen |
※ここはコマンドの省略を使っています。Vimは略称を持つコマンドが多く存在します。略称はヘルプから確認できます、ヘルプを開く場合も略称を使っていいです。例えば、「foldmethod」のヘルプを開くときは、「:help fdm」だけ入力しても構わない。
折畳みのイメージです。
「+--」から始まるのは折畳んだ行です。折畳みの背景色と表示する文字などは設定できます、詳しくは「:help folding」を参照します。
以下はよく使う折畳みのコマンドです。
| zi |
折り畳みの有効無効の切り替え |
| zf |
折り畳みを作成する |
| za |
折り畳みの開け閉め |
| zd |
折り畳みを削除する |
| zA |
折り畳みの開け閉め(再帰) |
| zD |
折り畳みを削除する(再帰) |
| zE |
全ての折り畳みを削除 |
| zR |
全ての折り畳みを開く |
| zM |
全ての折り畳みを閉じる |
折畳みの間で移動するコマンドもありますが、あまり使わないので、詳しくは「:help fold-commands」を参照します。
5.ソースファイルの中で移動
Vimの作者はプログラマですので、Vimはソースファイルの中で移動しやすいように、色々なコマンドが提供されています。例えば、tagファイルとcscopeタグによるジャンプ、関数、コメント、セグメントなどの中の移動コマンドは利用可能です。
これらのコマンドの紹介について、ここでは割愛します。プログラマたちは「:help usr_29.txt」を熟度しましょう。これらのコマンドはソースファイル内の移動に、きっと役立ちます。
ここで、移動関連のプラグインを二つ紹介します。一つは a.vim、もう一つはmatchitです。
5.1 a.vim
a.vim の機能は非常にシンプルです。a.vim はソース・ファイルとヘッダ・ファイルの間の移動を行います。
http://www.vim.org/scripts/script.php?script_id=31 からダウンロードし、$HOME/.vim/pluginに解凍すればインストール完了。
例えば、C言語のソースファイルを見ているとき、ソースのヘッダ・ファイルを編集したい場合、「:A」コマンドだけでヘッダ・ファイルに切り替ります(ソースとヘッダが同じフォルダにあること)。a.vim はほかのコマンドとキーバインドがあります、a.vim のヘルプを参照してください。
5.2 Matchit
Vimにて、「%」はマッチした項目へジャンプします。例えば、カーソルは { にある時、% を押せば、カーソルはマッチした } へ移動します(:help %)。
しかし、Vimの「%」のマッチ項目について、括弧(([{}]))、Cスタイルのコメント(/* */)、或いはC preprocessor conditionals しか対応していません。ほかのソース、例えばHTML、「%」は<html>から</html>へジャンプできません。
Matchitプラグインは「%」コマンドを拡張し、ほかの言語にも対応できるようにしました。
http://www.vim.org/scripts/script.php?script_id=39 からダウンロードし、$HOME/.vim/pluginフォルダに解凍してインストールは完了します。Matchitは現在サポートしている言語がAda, ASP with VBS, Csh, DTD, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, SGML, Shell, Tcsh, Vim, XMLなどあります。
6.挿入モードでの移動
上記紹介したコマンドは全て通常モードで使うもので、挿入モードの移動コマンドについては「:help ins-special-special」を参照します。
本当に挿入モードで移動しなければ成らないですか?私は殆どしていない。私はいつもESCを押して通常モードに戻してから移動します。慣れてこれば、効率が高いと決まっているでしょう。
まとめ
このコンテンツの内容は、usr_03.txtのヘルプとよく似いていることに気づきましたか?その通りです、usr_03.txtにあるコマンドを把握すれば、よく使う移動用コマンドは手に入れたでしょう。
ほかの移動に関するコマンドに興味があれば、motion.txtを参照してください。よく使うコマンドを覚えれば、速やかな移動は出来るでしょう。
== 関連ヘルプ ==
:help usr_03.txt
:help motion.txt
:help usr_29.txt
:help scroll.txt
:help folding |
|