← Vim研究所

Vimのカーソル移動まとめ 行頭・行末(0/^/$)と最終行(G)

2026-08-03 公開 ・ 更新: 2026-10-29 ・

Vimの移動キーは、覚えたそばから「どれを使えばいいのか」が分からなくなります。行頭へ行くキーだけでも0と^の2つがあり、違いを知らないとインデントの空白の前で止まったり、逆に空白を飛び越えたりします。最終行へ行くGも、VimとNeovimで止まる桁が違います。ここでは移動コマンドを距離の単位ごとに並べ、よく探される行頭・行末と先頭行・最終行を厚めに扱います。単語・画面単位の移動は要点だけにして、詳しい記事へ渡します。

目次(14項目)
動かしたい距離使うキー
1文字h j k l
単語w b e
行頭・行末0 ^ $ g_
先頭行・最終行gg G :$ {数字}G
画面Ctrl-f Ctrl-b Ctrl-d H M L

この記事の桁数と行数は、vim -n -Nu NONE -i NONE(Vim 9.1)とnvim -n -u NONE -i NONE(NVIM 0.12.6)を設定ファイル無しで起動して、col(".")やline(".")で読み取った値です。手元のvimrcでオプションを変えていると数字はずれます。

1文字ずつ動かす(hjkl)

h   " 左
j   " 下
k   " 上
l   " 右

ホームポジションから手を離さずに済むのが利点です。数字を前に置くと回数になり、10jで10行下へ動きます。何行下かを目で数えるのが面倒なら、行番号を表示する設定で相対表示にしておくと、その数字がそのまま画面に出ます。矢印キーとの使い分けはhjklと矢印キー、結局どっちを使うべきかにまとめています。

単語単位で動かす(w / b / e)

w   " 次の単語の先頭へ
b   " 前の単語の先頭へ
e   " 単語の末尾へ

foo-bar.baz qux endという行の1桁目からwを押し続けると、4桁目の-、5桁目のb、8桁目の.、9桁目のbと刻んでいき、5回目でようやくquxの先頭の13桁目に着きました。大文字のWなら1回で13桁目です。wは'iskeyword'に入っている文字(既定では英字・数字・アンダースコア)の連なりと記号の連なりを別の単語と見るので、-や.で必ず区切られます。Wは空白だけを区切りにします。

アンダースコアはキーワード文字なのでuser_nameはw1回で飛び越えますが、ケバブケースのクラス名やURLは記号の数だけ刻まれます。刻まれるのが煩わしい場所でだけWに持ち替えるのが実際的です。8種類の止まり位置の違いは単語移動8種類の違いで扱っています。

行頭へ移動する(0 と ^)

0    " 行の先頭(インデントの空白も含む)
^    " 最初の非空白文字
$    " 行の末尾
g_   " 最後の非空白文字

行頭・行末の行き先は4つあり、「行の端」と「中身の端」に分かれます。let x = 1;を4桁のインデントで書き、行末に半角空白を3つ残した17文字の行で測ると、次のようになりました。VimとNeovimで同じ桁です。

キー止まった桁そこにある文字
01インデントの空白
^5l
$17行末の空白
g_14;

インデントが深いコードで0を使うと空白の一番左まで移動してしまい、そこから改めて右に移動しないとコード本体にたどり着けません。プログラミング中は^のほうが実用的な場面が多くあります。正規表現の行頭を表す^と同じ記号なのは偶然ではなく、意味も対応しています。

行末(末尾)へ移動する($ と g_)

$は行の最後の文字へ移動します。0と^のような区別はなく、最後の文字が空白でも空白の上に止まります。上の表で$が17桁目の空白に止まったのはそのためです。末尾の空白を除いた最後の文字へ行きたいときはg_を使います。

行末に空白が残っているファイルで$からaで書き足すと、空白をはさんだ位置に文字が入ります。g_なら;の上に止まるので狙った位置に足せます。逆に行末の空白ごと消したいときはd$が正解で、dg_では空白が残ります。行の中の特定の1文字を狙うなら、端から数えるよりf と t による1文字検索のほうが短い手数で着きます。

$を押したあとにjで下の行へ移ると、行の長さが違ってもカーソルは行末に留まります。5文字の行で$を押してjを2回押すと、23文字の行では23桁目、8文字の行では8桁目に止まりました。桁の数字ではなく「行末にいる」という状態を覚えているためです。この状態はhやlで横に動かした時点で解除され、同じ操作の途中にhを1回はさむと次の行では4桁目に固定されました。行末をたどっているつもりが途中から桁が固定される、と感じたときは、間に横移動が入っていないかを確かめてください。

折り返し表示のときは g を前置する

gj   " 見た目の1行下
gk   " 見た目の1行上
g0   " 折り返し単位での行頭
g^   " 折り返し単位での行頭(インデント考慮)
g$   " 折り返し単位での行末

jや0/^/$が見ているのはファイルの行で、画面に見えている行ではありません。400文字の1行を80桁のウインドウで開くと画面上では5行に折り返されますが、行頭でjを押すと折り返しをまたいで次の行の1桁目に移りました。同じ位置でgjを押すと同じ行のまま81桁目、つまり折り返しの2行目の先頭に止まり、g$は80桁目に止まります。

使い分けの基準は、そのバッファで折り返しが起きるかどうかです。'wrap'が有効なまま長い文章を書くファイルではg付きのほうが目で見た動きと一致します。コードのように1行が短いファイルなら折り返しはほとんど起きないので、行番号とそのまま対応するj kのほうが回数を数えやすくなります。

使ってみて

最初は0ばかり使っていて、インデントの深いコードのたびに右へ余分に移動していました。^に切り替えてからは、その無駄な移動がまるごと消えました。長いMarkdown文書を折り返し表示で編集するときにg$の存在を知らず、意図しない位置まで飛んで戸惑ったこともあります。今では折り返し表示のファイルを開いた瞬間にg付きのコマンドへ意識を切り替えるようにしています。

行頭・行末から入力を始める(I と A)

I   " 行頭(インデント考慮)からインサートモードへ
A   " 行末からインサートモードへ

IとAは移動だけでなく、そのままインサートモードに入るショートカットです。^iや$aと書く代わりにこの1文字で済むので、行頭・行末から書き始めたいときはこちらのほうが手数が少なくなります。

先頭行・最終行へ移動する(gg / G / :$)

gg       " 先頭行へ
G        " 最終行(一番下の行)へ
:$       " 最終行へ(Exコマンド)
:1       " 先頭行へ(Exコマンド)
G$       " 最終行の行末へ
Ctrl-End " 最終行の最後の文字へ

ファイルの最後の行に移動するのはG、最初の行はggです。コマンドラインに慣れているなら:$と:1でも同じ行へ行けます。前の節の「末尾」は1行の中の末尾なので、ファイルの最後の行の末尾まで行きたいときはG$と2つ続けます。Ctrl-Endはこの2つを1キーで済ませるもので、VimでもNeovimでも最終行の最後の文字に止まりました。

注意したいのは、Gやggで着いたあとの桁です。これは'startofline'で決まり、既定値がVimとNeovimで違います。8桁のインデントが付いた最終行のあるファイルで、1行目の5桁目からGを押して比べました。

環境'startofline'の既定Gで止まった桁
Vim 9.1オン9(最初の非空白文字)
NVIM 0.12.6オフ5(元の桁のまま)

:$と:1、ggも同じ設定に従い、Vimでは行の最初の非空白文字に、Neovimでは元の桁のまま止まりました。Neovimで最終行のコードの先頭から書きたいときは、Gのあとに^を足すか、:set startoflineでVimと同じ動きに戻します。

指定した行・空行へ移動する(42G / { })

42G   " 42行目へ
:42   " 42行目へ(Exコマンド)
{ }   " 前後の空行へ

エラーメッセージが行番号を出してきたときは42Gか:42が最短です。行番号ではなく中身で探すなら文字列検索(/ と ?)のほうが早く、戻る場所に印を付けておきたいならマーク機能が使えます。

行番号も検索語も持っていないときに効くのが{と}です。ヘルプでは段落単位の移動と説明されていますが、境界として見ているのは本当に空の行だけです。

Note that a blank line (only containing white space) is NOT a paragraph boundary.

半角空白だけの行を3行目に置いたファイルで確かめると、1行目からの}は3行目を素通りして、本当に空の6行目に止まりました。コードで}が関数の切れ目にうまく効くのは、関数と関数のあいだに空行を入れる書き方が広く行われているからにすぎません。}が思ったところで止まらないときは、まずその行に空白が残っていないかを疑うと早く片付きます。

画面単位で動かす(Ctrl-f / Ctrl-d / H M L)

Ctrl-f   " 1画面ぶん進む
Ctrl-b   " 1画面ぶん戻る
Ctrl-d   " 半画面ぶん進む
H M L    " 画面の最上行 / 中央 / 最下行へ

Ctrl-fとHは見た目が似ていますが、前者は画面のほうを動かし、後者はカーソルを画面の中で動かします。Ctrl-fは37行のウインドウの1行目で押すと画面の先頭が36行目になり、直前に読んでいた2行が次の画面の先頭に残ります。読み下すときに文脈が切れないための重なりで、行数を正確に進めたい場面には向きません。

Ctrl-dが進む行数は'scroll'が持っていて、既定ではウインドウの高さの半分です。回数を前に置くとその値が書き換わり、1行目で10Ctrl-dを押すと11行目に着いて、'scroll'も10になりました。以降は素のCtrl-dも10行ずつ進むので、半画面に戻したいときは:set scroll=0にします。HとLが'scrolloff'の分だけ画面の端に届かないことや、zzのような表示位置の調整は画面スクロールとジャンプ操作にまとめてあります。

戻れる移動と、戻れない移動がある

移動コマンドでいちばん見落とされる点です。Vimは大きく飛んだ移動だけをジャンプリストに記録していて、Ctrl-oで戻れるのは記録された移動だけです。距離が長いかどうかではなく、キーの種類で決まります。300行のファイルの6行目からキーを押し、getjumplist()で記録が増えたかを確かめました。

キージャンプとして記録されるか
G gg { } /される(Ctrl-oで戻れる)
j 3j w 0 Ctrl-fされない

3jで3行下がっても、Ctrl-fで1画面ぶんスクロールしても記録は残りません。一方でGや/で飛んだあとはCtrl-oで元の位置に戻れます。ジャンプリストの中身の読み方やg;との違いはCtrl-oで前の位置に戻るで扱っています。

要点:戻る前提で遠くへ飛ぶならGや/を使います。Ctrl-fの連打で同じ場所まで行っても、Ctrl-oでは戻れません。
使ってみて

長いファイルの末尾だけ見て元の場所に帰るつもりが、Ctrl-oを何度押しても数行しか動かず、結局Ctrl-bで画面を目で追いながら戻る羽目になったことがあります。降りるときにCtrl-fを連打していたせいだと気づくまでに、キーマッピングが壊れたのかとvimrcを読み直す時間まで使いました。今でも読みながら少しずつ降りる場面ではスクロールを使いますが、そのときは行番号を頭に入れてから降りる癖がつきました。

移動キーは削除やコピーの範囲にもなる

d$   " カーソルから行末まで削除
d^   " カーソルからインデント後の行頭まで削除(逆方向)
y0   " カーソルから行頭まで(インデントの空白も含めて)ヤンク
dG   " 今の行から最終行まで削除
dgg  " 今の行から先頭行まで削除
BEFORE
let x = 1; // TODO
          ^ カーソル
d$
AFTER
let x = 1;

ここまでのキーの多くは、そのままdやyの後ろに置けます。d$は行の途中から末尾までをまとめて消すときに特によく使います。Gとggは行単位のモーションなので、dGは桁に関係なく今の行から最終行までを行ごと消します。組み合わせの考え方はオペレータ+モーションの練習ドリルで扱っています。

ただしCtrl-fのような画面スクロールはモーションではないため、dの後ろには置けません。300行のファイルの50行目でdに続けてCtrl-fを押しても、行数は300のままで'modified'も0のままでした。エラーは出ず、待ち状態のオペレータごと黙って捨てられます。一方で画面基準のHとLは行単位のモーションとして働き、82行目を先頭にした画面の100行目でdHを押すと、82行目から100行目までの19行が消えて281行になりました。

ビジュアルモードでの $ は改行まで含む

行頭・行末のキーはビジュアルモードでもそのまま使えます。v$でカーソル位置から行末まで、v^でインデント後の行頭までを選べます。選択範囲を目で確認しながら操作したい場合は、オペレータと直接組み合わせるよりビジュアルモード経由のほうが安心です。

ノーマルモードの$は最後の文字に止まりますが、ビジュアルモードでは最後の文字の後ろ、つまり改行まで選択に入ります。abc defの4桁目からv$yでヤンクすると、レジスタには defと改行が入りました。行頭からv$dで消すと改行ごと消えて下の行が繰り上がり、空行は残りません。中身だけ消して行を残したいときはvg_dにすると、改行を含まずに空行が残ります。矩形選択のときだけは$の意味が変わり、長さの違う行それぞれの末尾まで範囲が伸びます。行末にまとめて文字を足すときは、Ctrl-vで行を選んでから$を押し、Aで入力します。

まとめ

行頭はインデントを飛ばす^を基本にし、行の1文字目が要るときだけ0を使います。行末は$、末尾の空白を避けたいならg_です。最終行はG、先頭行はggで、Neovimでは着いた桁が元のままになる点だけ覚えておくと迷いません。それより大きな移動では、位置の基準がファイル側か画面側か、ジャンプとして記録されてCtrl-oで戻れるかの2つを当てはめると、押すキーが1つに絞れます。

ここで扱ったキーは、ブラウザ上で動くVim道場の行の端とファイルの端へ飛ぶでそのまま試せます。インストールもログインも要りません。

関連記事

← Vim研究所 トップへ戻る