メンテナンス層、2026-09-01 確認。 Vim では、タブ文字とタブページは互いに無関係な機能です。このガイドでは、現在の Vim と Neovim の文書に基づいて両方を説明します。2019 年の完全なエクスポートは日付付きアーカイブとして文末に残し、現在の設定方法としては扱いません。
最も役立つ考え方は単純です。バッファはテキストを保持し、ウィンドウはバッファを表示し、タブページはウィンドウのレイアウトを保持します。セッションは、より大きな編集ワークスペースを復元できます。これらを分けて考えると、開く、移動する、閉じる、マッピングする、インデントを直すという操作が予測しやすくなります。
Table of Contents
「Tab」が持つ二つの意味
Vim では「Tab」という語が二つの異なる意味で使われます。
- タブ文字は、テキスト中の水平タブ、つまりバイト 9 です。
tabstop、softtabstop、shiftwidth、expandtabなどのオプションが、インデントの表示と入力を制御します。 - タブページは、一つ以上のウィンドウの集合です。ワークスペースのレイアウトであって、ファイルの入れ物でもバッファでもありません。
挿入モードでキーボードの Tab キーを押してもタブページは作られません。同様に、:tabnew はインデントを変更しません。この二つを分けることで、元のメモにあった混乱の多くを解消できます。
バッファ、ウィンドウ、タブページ、セッション
| オブジェクト | 表すもの | 確認方法 | 代表的な操作 |
|---|---|---|---|
| バッファ | メモリへ読み込まれたテキスト。通常はファイル由来 | :ls | :buffer {name-or-number} |
| ウィンドウ | 一つのバッファを表示するビューポート | :tabs または CTRL-W w | :split、:vsplit、:close |
| タブページ | ウィンドウの一集合 | :tabs | :tabedit、gt、:tabclose |
| セッション | ウィンドウ、タブページ、選択された状態を復元する Vim スクリプト | :set sessionoptions? | :mksession、vim -S |
同じバッファを複数のウィンドウに表示でき、別々のタブページにあるウィンドウで共有することもできます。そのため、一つのウィンドウを閉じてもバッファが削除されるとは限らず、タブページを閉じることも「一つのファイルを閉じる」という意味ではありません。
再現可能な二ワークスペース演習
一つのファイルで Vim または Neovim を起動します。
vim README.md
次に、組み込みコマンドだけで二つのレイアウトを作ります。
:vsplit src/main.py
:tabedit tests/test_main.py
:split tests/test_cli.py
:tabs
結果は次のようになります。
Tab page 1
├── window: README.md buffer
└── window: src/main.py buffer
Tab page 2
├── window: tests/test_main.py buffer
└── window: tests/test_cli.py buffer
gt と gT でタブページ間を移動します。一つのタブページ内では、CTRL-W h、CTRL-W j、CTRL-W k、CTRL-W l でウィンドウ間を移動します。:ls を実行すると、表示レイアウトとは独立してバッファを確認できます。
ファイル名は例です。使い捨てのテスト用リポジトリに実在するファイルへ置き換えてください。指定したファイルが存在しない場合、Vim はその名前で未保存の新規バッファを作ります。
タブページを開く、移動する、確認する、並べ替える
ほとんどのタブページ操作は、次の組み込みコマンドで足ります。
:tabedit path/to/file
:tabnew
:tabs
:tabnext
:tabprevious
:tabfirst
:tablast
:tabmove 0
:tabmove
:tabedit {file}は新しいタブページを作り、そこでファイルを編集します。:tabnewは空のウィンドウを持つ新しいタブページを作ります。:tabsは全タブページとそのウィンドウを一覧表示します。プラス記号は変更済みバッファを示します。gtと:tabnextは次のタブページへ、gTと:tabpreviousは前のタブページへ移動します。2gtのような{count}gtは、現在の番号でタブページを選びます。:tabmove 0は現在のタブページを先頭へ、:tabmoveは末尾へ移動します。
タブページを開く、閉じる、移動する操作により番号は変わります。番号は永続的な識別子ではなく、現在の位置として扱ってください。
ウィンドウとバッファを直接操作する
別の表示が必要ならウィンドウを使い、別のテキストが必要ならバッファコマンドを使います。
:split path/to/file
:vsplit path/to/file
:close
:only
:ls
:buffer 3
:bnext
:bprevious
:bdelete 3
:close は現在のウィンドウを取り除きます。:only は、安全に閉じられる場合、現在のタブページにある他のウィンドウを閉じます。どちらも「ファイルを削除する」という意味ではありません。
:buffer、:bnext、:bprevious は、現在のウィンドウが表示するバッファを切り替えます。:bdelete はバッファを一覧から外し、そのバッファを表示するウィンドウを閉じます。! がなければ、未保存の変更を放棄する操作は拒否されます。一つの表示だけを消したいなら、代わりに :close を使います。
正しい対象を安全に閉じる
通常は ! のないコマンドから始める方が安全です。
| 目的 | コマンド | 動作 |
|---|---|---|
| 現在のバッファを保存 | :write | このバッファをファイルへ書き込む |
| 変更済みバッファをすべて保存 | :wall | 変更済みバッファをすべて書き込もうとする |
| 一つのウィンドウを閉じる | :close | 可能な限り他の表示とバッファを保つ |
| 現在のタブページを閉じる | :tabclose | 全ウィンドウを閉じるが、危険な破棄は拒否する |
| 一つのバッファを外す | :bdelete {name} | 一覧から外すが、未保存内容の損失は拒否する |
| 現在のウィンドウを終了 | :quit | 最後のウィンドウだった場合だけ Vim を終了する |
反射的に ! を追加しないでください。:quit! や :bdelete! では変更を破棄する可能性があります。Vim が未保存バッファを報告したら、:ls で確認し、残す変更なら :write を使い、破棄するなら明示的に判断します。
大きなレイアウトを整理する前には、次の保守的な順序を使えます。
:ls
:wall
:tabs
:tabclose
名前がない、読み取り専用、または別の理由で書き込めないバッファでは、:wall も失敗します。すべて保存されたと思い込まず、メッセージを確認してください。
セッションを保存して復元する
セッションは実行可能な Vim スクリプトです。sessionoptions に従い、ウィンドウ配置、タブページ、バッファ、選択されたオプションを復元できます。
ポリシーを確認してから、現在のワークスペースを保存します。
:set sessionoptions?
:wall
:mksession Session.vim
bang のない形式は既存のセッションファイルを上書きしません。意図的に更新する場合は次を使います。
:wall
:mksession! Session.vim
シェルから復元します。
vim -S Session.vim
Neovim では、代わりに nvim -S Session.vim を使います。
Vim 内から復元することもできます。
:source Session.vim
sessionoptions から tabpages を削除していない限り、セッションには全タブページが含まれます。すべての状態が復元されるわけではなく、プラグインも独自の影響を加えることがあります。セッションはコードとして source されるため、内容を確認し、信頼できるファイルだけを読み込んでください。公開する意図のない個人パスが含まれるなら、セッションをコミットしてはいけません。
最小限で確認可能なマッピングを追加する
マッピングを足す前に、gt、gT、Ex コマンドを覚えます。覚えやすいキーが本当に必要なら、非再帰のノーマルモードマッピングを使い、安全な bang なしコマンドを見える形で残します。
let mapleader = " "
nnoremap <silent> <leader>tn <Cmd>tabnew<CR>
nnoremap <silent> <leader>tc <Cmd>tabclose<CR>
nnoremap <silent> <leader>tl <Cmd>tabs<CR>
予期しないマッピングと、それを最後に定義したスクリプトを確認します。
:verbose nmap gt
:verbose nmap <leader>tc
Neovim の Lua 設定では、同等の明示的なマッピングは次のようになります。
vim.g.mapleader = " "
vim.keymap.set("n", "<leader>tn", "<cmd>tabnew<cr>", { desc = "New tab page" })
vim.keymap.set("n", "<leader>tc", "<cmd>tabclose<cr>", { desc = "Close tab page" })
vim.keymap.set("n", "<leader>tl", "<cmd>tabs<cr>", { desc = "List tab pages" })
タブ移動だけのために大規模な設定を導入しないでください。組み込み機能から始め、説明できるマッピングだけを追加し、:verbose nmap で衝突を確認します。
タブ文字とインデントを設定する
これらはバッファローカルなオプションです。対象ファイル内で確認してください。
:setlocal tabstop? shiftwidth? softtabstop? expandtab?
tabstopは、実際のタブ文字が表示上占めるカラム数を制御します。shiftwidthは、>>、<<、自動インデントなどのインデント幅を制御します。softtabstopは、編集中の Tab と Backspace の動きを制御します。expandtabは、一般的な挿入やインデント操作で実タブではなくスペースを挿入します。
一般的な 4 スペース、スペースのみの方針は次のとおりです。
setlocal expandtab
setlocal tabstop=4
setlocal shiftwidth=4
setlocal softtabstop=4
タブベースのプロジェクトでは、次の設定が必要な場合があります。
setlocal noexpandtab
setlocal tabstop=8
setlocal shiftwidth=8
setlocal softtabstop=8
これらは例であり、普遍的な規則ではありません。リポジトリの既存スタイルに従ってください。tabstop を変えても実タブの見え方が変わるだけで、ファイルは書き換わりません。
既存ファイルを慎重に確認して正規化する
変更前に不可視の空白を表示します。
:setlocal list
:setlocal listchars=tab:>-,trail:·
プロジェクトの方針を決めた後、まずメモリ上でスペースのみへ変換できます。
:setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4
:%retab
! がない :retab は、タブを含む空白列を対象にします。expandtab が有効なら、表示上の位置を保つ適切な数のスペースへ置き換えます。それでも文字列やデータ内のタブを変更する可能性があるため、採用前にバッファとバージョン管理の diff を確認してください。メモリ上の変換が意図と違う場合は u で元に戻せます。
その後、明示的に書き込み、リポジトリの diff を確認します。
:write
アーカイブにある「8 個のリテラルスペースを 4 個へ全置換する」コマンドはタブ文字を置換せず、意図的な位置合わせを壊す可能性があります。来歴のために保存していますが、一般的な修復方法としては推奨しません。
ファイルタイプ別の規則を適用する
永続的な規則は、自分で管理する設定に置きます。次の Vimscript 例は augroup を使い、設定を再読み込みしても autocmd が重複しないようにします。
augroup indentation_rules
autocmd!
autocmd FileType python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4
autocmd FileType c setlocal noexpandtab tabstop=8 shiftwidth=8 softtabstop=8
augroup END
C の行は一例にすぎません。スペースや別の幅を採用する C プロジェクトも多くあります。言語名だけで決めず、対象プロジェクトに合わせます。
オプションが何度も変わる場合は、現在値を最後に設定した場所を Vim に表示させます。
:verbose setlocal expandtab?
:verbose setlocal tabstop?
:verbose setlocal shiftwidth?
:verbose setlocal softtabstop?
これにより、期待値を上書きしたファイルタイププラグイン、autocmd、modeline、設定レイヤーを特定できることがあります。
Vim と他エディタの不一致を診断する
Vim では揃うのに Notepad++ などのエディタでは崩れる場合、変換前に診断します。
:setlocal listを実行し、実タブとスペースを区別する。tabstop、shiftwidth、softtabstop、expandtabを確認する。- 相手側エディタのタブ表示幅と、Tab キーがタブかスペースのどちらを挿入するかを確認する。
- 既存ファイルとツールからリポジトリの規約を確かめる。
- ファイルが本当に不統一な場合だけ変換し、diff を確認する。
表示幅とファイル内容は別の問題です。同じ実タブを二つのエディタが異なる幅で表示することも、同じ見た目の二つのファイルが異なるバイトを含むこともあります。
トラブルシューティング
gtが動かない: タブページが一つしかないか、マッピングで上書きされている可能性があります。:tabsと:verbose nmap gtを実行します。- タブページを閉じてもファイルが
:lsに残る: ウィンドウを閉じてもバッファはロード済みまたは非表示で残る場合があります。バッファ自体を外したい場合だけ:bdelete {name}を使います。 :bdeleteが複数の表示へ影響した: 複数ウィンドウが同じバッファを表示していました。一つのウィンドウだけを消すには:closeを使います。- Vim が「No write since last change」と報告する: 安全確認です。バッファを保存するか、変更を破棄するか明示的に決めます。
- セッション復元後にマッピングやオプションが変わる:
sourceの前にsessionoptionsと生成済みセッションを確認します。セッションは選択されたグローバル状態を復元できます。 - タブラベルがファイル名のように見える: ラベルはタブページのウィンドウ集合を表し、一つのバッファの所有権を示しません。
:%retabで巨大な diff が生じた: 元に戻し、元のtabstopと、データや文字列内にタブがあるかを確認してから再試行を判断します。
Vim と Neovim の一次資料
- Vim ソースマニュアル:バッファとウィンドウ
- Vim ソースマニュアル:タブページ
- Vim ソースマニュアル:セッション
- Vim ソースマニュアル:マッピング
- Vim ソースマニュアル:インデントオプション
- Vim ソースマニュアル:`:retab`
- Neovim マニュアル:バッファとウィンドウ
- Neovim マニュアル:タブページ
- Neovim マニュアル:セッション
- Neovim マニュアル:マッピング
- Neovim Lua ガイド:`vim.keymap.set`
- Neovim マニュアル:オプション
---
2019 年の原アーカイブ(英語原文を保存)
以下は、元のメタデータ、語句、順序、コマンド、見出しを含む WordPress エクスポートの全文です。2019-04-21 に公開・最終更新されました。上記のメンテナンス済み推奨とは異なる歴史資料です。リポジトリの形式を整えるため、目に見えない行末空白だけを正規化しています。
---
id: 1876
title: 'Vim Configuration and Tab Inconsistency Between Vim and Notepad++'
slug: 'vim-configuration-and-tab-inconsistency-between-vim-and-notepad'
date: '2019-04-21T03:42:35'
modified: '2019-04-21T03:42:42'
status: 'publish'
link: 'https://blog.lazying.art/en/html/computer_internet/unix_linux/v_ivim/1876/vim-configuration-and-tab-inconsistency-between-vim-and-notepad.html'
author: 'Lachlan Chen'
categories:
- 'VI&VIM'
---
General
A completed configuration can be installed by running this
git clone --depth=1 https://github.com/amix/vimrc.git ~/.vim_runtime
sh ~/.vim_runtime/install_awesome_vimrc.sh
If you want to add some customized configurations,
vim ~/.vim_runtime/my_configs.vim
Some sample configuration of your vim
set shiftwidth=4 " used by >>, << and tab.
set tabstop=4 " number of space characters used when displaying TAB
set expandtab " replace TAB by spaces
set softtabstop=4 " will erase 4 spaces at once when using BS in the begining of lines only
If this is an existed file, you might run this to sort out your file
:%retab
Python
C
Vim and Notepad++ Inconsistency
To solve the inconsistency, you might want to use
:%s/ / /g
