・ 開発環境

WezTermとNeovimの設定と連携でつくる、ターミナル完結の開発環境
はじめに
こんにちは!最強の開発環境を追求するエンジニアです!✨
今回は、私が長年カスタマイズしてきたWezTermとNeovimの設定について詳しく解説します。テーマやキーバインドに加えて、2つをつなぐterminfoの設定とペイン移動の共通化まで、実際に使っている内容をそのまま載せました。
※この記事は 7 割程度が AI によって執筆されています。
WezTermとは?
WezTermの基本概要
https://wezterm.org/index.html
WezTermは、Rustで書かれたモダンなターミナルエミュレータです。高速でカスタマイズ性が高く、特にLua言語で設定を記述できることが特徴です。
WezTermの主な特徴
- 高速レンダリング: GPU加速による高速描画
- tmuxの機能が標準搭載: ターミナルマルチプレクサの機能を内蔵しており、タブやペイン分割、セッション保持などが標準で利用
- 機能が豊富: クイック選択や画像表示機能に加え、SSHやリモート環境との連携も容易
- Lua設定: 柔軟で強力な設定システム
- フォント設定: 豊富なフォントサポート
Neovimとは?
Neovimの基本概要
Neovimは、Vimの改良版として開発されたテキストエディタです。Vimとの互換性を保ちながら、より現代的なアーキテクチャを採用しています。
Neovimの主な特徴
- 非同期処理: プラグインの高速実行
- LSP内蔵: Language Server Protocol対応
- Lua設定: 設定とプラグイン開発にLuaを使用
- プラグインシステム: 豊富なプラグインエコシステム
- モダンUI: 浮動ウィンドウやポップアップ表示
私のWezTerm設定詳細
まず、見た目はこのようにしています!😁

基本設定ファイル構成
~/.dotfiles/config/wezterm/
├── wezterm.lua # メイン設定ファイル
├── config/
│ ├── background.lua # 背景とテーマ設定
│ ├── keybind.lua # キーバインド設定
│ └── your_name.gif # 背景画像
🎨 テーマとビジュアル設定
私のWezTermはTokyo Nightテーマを使い、背景画像の上に半透明の黒を重ねて文字を読みやすくしています:
-- カラースキーム
config.color_scheme = "Tokyo Night"
-- フォント設定
config.font = wezterm.font("Firge35Nerd Console", {
weight="Regular",
stretch="Normal",
style="Normal"
})
config.font_size = 16.0
🖼️ 背景画像設定
特に印象的なのは、背景画像の設定です:
-- 背景画像(your_name.gif)
config.background = {
{
source = { File = script_dir .. "your_name.gif" },
opacity = 0.95,
hsb = { brightness = 1.0, hue = 1.0, saturation = 0.8 }
},
-- 半透明オーバーレイ
{
source = { Color = "rgba(0, 0, 0, 0.7)" },
height = "100%",
width = "100%",
}
}
📊 高機能ステータスバー
WezTermの右側に表示される情報豊富なステータスバーを実装しています:
- ホスト名とディレクトリ: 現在の作業場所を表示
- 日付と時刻: リアルタイム表示
- バッテリー残量: フルスクリーン時に表示
- リーダーキー状態: アクティブ時に表示
-- ステータスバー要素の例
local function GetHostAndCwd(elems, pane)
-- ホームディレクトリを~に置換
local home = os.getenv("HOME")
if home and cwd_str:find(home, 1, true) == 1 then
cwd_str = "~" .. cwd_str:sub(#home + 1)
end
-- 長いパスを短縮
if #dir > 30 then
dir = ".../" .. parts[#parts-1] .. "/" .. parts[#parts]
end
end
私のNeovim設定詳細
プラグイン管理システム
lazy.nvimを使用したモダンなプラグイン管理を採用しています:
-- lazy.nvim bootstrap
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
vim.fn.system({"git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath})
end
🔭 Telescope - 最強のファジーファインダー
Telescopeは私のワークフローの中核となるツールです:
-- 主要なキーバインド
keymap('n', '<leader>ff', builtin.find_files, { desc = 'Find files' })
keymap('n', '<leader>fg', builtin.live_grep, { desc = 'Live grep' })
keymap('n', '<leader>fb', builtin.buffers, { desc = 'Find buffers' })
keymap('n', '<leader>gg', git_commands, { desc = 'Git commands' })
📷 画像プレビューシステム
Oil.nvimとWezTermを連携させた画像プレビューシステムを実装しています:
-- 画像プレビューの特徴
- WezTermペインとの統合
- 自動プレビュー機能
- デバウンス機能付きカーソル移動追従
- 複数ファイル形式対応
🎯 Language Server Protocol (LSP) 設定
Go言語とTypeScript/JavaScriptの開発に最適化されたLSP設定:
-- Go言語用LSP設定
lspconfig.gopls.setup({
settings = {
gopls = {
completeUnimported = true, -- 未インポート補完
usePlaceholders = true, -- プレースホルダー有効
staticcheck = true, -- 静的解析
gofumpt = true, -- gofumptフォーマット
},
},
})
🌿 Git統合システム
複数のGitツールを統合した包括的なGitワークフロー:
- GitSigns: ハンク表示とブレーム
- vim-fugitive: 基本的なGitコマンド
- DiffView: 高度な差分表示
- Octo.nvim: GitHub統合
-- Git統合の例
keymap('n', '<leader>gg', git_commands, { desc = 'Git commands' })
keymap('n', '<leader>gd', git_diff_files, { desc = 'Git diff files' })
keymap('n', '<leader>gv', '<cmd>DiffviewOpen<cr>', { desc = 'Open diffview' })
🔗 WezTermとNeovimをつなぐ設定
ここまでは2つのツールをそれぞれ単体で設定してきました。WezTermの上でNeovimを動かす場合は、2つをつなぐ設定が別に要ります。ここを飛ばすと、診断の下線が全部同じ色に見えたり、ペイン移動のキーが片方にしか届かなかったりします。私が最初につまずいたのもこの2つでした。
🖍️ 色付き下線とundercurlを表示できるようにする
Neovimは診断のハイライトで、下線の色を重要度ごとに分けて指定しています。エラーは赤、警告は黄、ヒントは青、という具合です(highlight_group.c)。ところがWezTermの公式ドキュメントにある通り、WezTermが渡すTERMの初期値はxterm-256colorです。この値のままでは、色付き下線も波線(undercurl)もNeovimから使えません。エラーも警告も、同じ見た目の下線として表示されます。
公式FAQの手順に沿って、WezTermのterminfoをインストールしてからtermを切り替えます。terminfoを入れる前にtermだけ変えると、TERMが未知の値になって画面表示が崩れるので、順番に注意してください。
# 1. WezTermのterminfoをインストールする
tempfile=$(mktemp) \
&& curl -o $tempfile https://raw.githubusercontent.com/wezterm/wezterm/main/termwiz/data/wezterm.terminfo \
&& tic -x -o ~/.terminfo $tempfile \
&& rm $tempfile
-- 2. wezterm.lua で TERM を切り替える
config.term = "wezterm"
設定を変える前に試したい時は、env TERM=wezterm nvimで起動すると挙動を確認できます。
⚠️ Windowsでの注意点: ConPTYはこれらのエスケープシーケンスを落としてしまいます。WSL上のNeovimで使う場合は、公式FAQの通り
wezterm sshかWezTermのマルチプレクサ経由で接続してください。
🪟 ペイン移動をWezTermとNeovimで共通化する
WezTermのペインとNeovimのウィンドウ分割は別々の仕組みなので、素の状態ではCtrl + h/j/k/lがどちらか一方だけを動かします。今カーソルがNeovimの中にいるのか、隣のペインにいるのか。これを意識しながら移動するのは地味にストレスでした。
smart-splits.nvimを入れると、Neovimの分割の端まで移動した時点で、そのままWezTermのペインへカーソルが抜けます。WezTerm側はプラグイン機構でそのまま読み込めます。
-- wezterm.lua
local smart_splits = wezterm.plugin.require('https://github.com/mrjones2014/smart-splits.nvim')
smart_splits.apply_to_config(config, {
direction_keys = { 'h', 'j', 'k', 'l' },
modifiers = {
move = 'CTRL',
resize = 'META',
},
})
-- Neovim側のキーマップ
vim.keymap.set('n', '<C-h>', require('smart-splits').move_cursor_left)
vim.keymap.set('n', '<C-j>', require('smart-splits').move_cursor_down)
vim.keymap.set('n', '<C-k>', require('smart-splits').move_cursor_up)
vim.keymap.set('n', '<C-l>', require('smart-splits').move_cursor_right)
vim.keymap.set('n', '<A-h>', require('smart-splits').resize_left)
vim.keymap.set('n', '<A-j>', require('smart-splits').resize_down)
vim.keymap.set('n', '<A-k>', require('smart-splits').resize_up)
vim.keymap.set('n', '<A-l>', require('smart-splits').resize_right)
導入時につまずきやすい点は次の2つです。
- 連携には**
weztermコマンドがPATHに通っている必要があります**(WezTermのCLI経由でペインを操作するため) wezterm.plugin.requireは、指定したGitリポジトリをランタイムディレクトリのplugins/配下にcloneします。更新したい時はDebug Overlay(Ctrl + Shift + L)でwezterm.plugin.update_all()を実行します
🔌 Neovim側からWezTermを操作する(wezterm.nvim)
smart-splits.nvimは「ペイン間を移動する」プラグインですが、逆にNeovimの中からWezTermのタブ・ペーンを操作したい場合はwillothy/wezterm.nvimが候補になります。Neovim 0.10以上が必須で、lazy.nvimなら次の1行で導入できます。
-- lazy.nvim
{
'willothy/wezterm.nvim',
config = true,
}
導入するとWeztermSpawn <コマンド> <引数>...ユーザーコマンドが生えて、Neovimを離れずに新しいWezTermタブでコマンドを実行できます。このコマンド自動生成が不要なら、opts = { create_commands = false }にしてLua APIだけをrequire("wezterm").日本語のように呼び出す構成にもできます。API仕様の全体は:h wezterm.nvim(doc/wezterm.nvim.txt)にまとまっています。
この3つを設定しておくと、前述の画像プレビューのようにWezTermのペインを道具として使うNeovim側の仕組みも、素直に動くようになります。
🚀 開発効率を向上させる機能
自動化機能
- Go言語: 保存時に自動インポート整理とフォーマット
- 画像プレビュー: カーソル移動時の自動プレビュー更新
- Git統合: ワンキーでの複雑なGitワークフロー
キーバインド設計
すべてのキーバインドは論理的に配置され、筋肉記憶に優しい設計:
-- リーダーキー設定
vim.g.mapleader = " "
-- ファイル操作(<leader>f)
<leader>ff - ファイル検索
<leader>fg - 文字列検索
<leader>fb - バッファ切り替え
-- Git操作(<leader>g)
<leader>gg - Git コマンドメニュー
<leader>gf - Git ファイル
<leader>gd - Git 差分ファイル
パフォーマンス最適化
- lazy loading: 必要時のみプラグインを読み込み
- debouncing: 無駄な処理を防ぐ遅延実行
- 非同期処理: UIをブロックしない処理
🎨 美しいユーザーインターフェース
カラースキーム
Tokyo Nightテーマを基調とした一貫したカラーリング:
- WezTerm: Tokyo Night
- Neovim: VSCodeテーマ
- ステータスバー: カスタムカラー
フォント選択
Firge35Nerd Consoleを使用し、日本語とアイコンの両方に対応:
config.font = wezterm.font("Firge35Nerd Console", {
weight="Regular",
stretch="Normal",
style="Normal"
})
config.font_size = 16.0
💡 実用的な使用例
1. プロジェクト開発時のワークフロー
# 1. プロジェクトディレクトリに移動
cd ~/projects/my-app
# 2. WezTermでNeovimを起動
nvim
# 3. Telescopeでファイル検索
<leader>ff
# 4. Git操作
<leader>gg
2. 画像リソースの管理
# 1. Oil.nvimでディレクトリを開く
:Oil
# 2. 画像ファイルに移動
# → 自動でWezTermペインに画像プレビュー表示
# 3. 画像編集後の確認
# → リアルタイムでプレビュー更新
3. コード開発とレビュー
# 1. コード編集
# → LSPによる自動補完とエラーチェック
# 2. Git差分確認
<leader>gd
# 3. GitHub PR作成
<leader>ghc
🛠️ カスタマイズのコツ
段階的な設定構築
- 基本設定から開始: 最低限の設定で動作確認
- 機能追加: 必要に応じてプラグインを追加
- 最適化: パフォーマンスとUXの改善
設定ファイルの分割
-- 設定の分割例
config/
├── nvim/
│ ├── init.lua # エントリーポイント
│ └── lua/plugins/
│ ├── telescope.lua # ファジーファインダー
│ ├── lsp.lua # LSP設定
│ ├── git.lua # Git統合
│ └── image-preview.lua # 画像プレビュー
バックアップとバージョン管理
# dotfiles repository
~/.dotfiles/
├── config/
│ ├── nvim/
│ └── wezterm/
├── install.sh
└── CLAUDE.md
🎯 まとめ
WezTermとNeovimの組み合わせは、現代的で効率的な開発環境を構築するための最強のツールセットです。
主要な利点
- 統合性: WezTermとNeovimの深い連携
- カスタマイズ性: Luaによる柔軟な設定
- 美しさ: 一貫したテーマとUI
- 効率性: 自動化による生産性向上
今後の展望
この設定は継続的に進化させています:
- 新しいプラグインの追加: 開発効率の向上
- パフォーマンス改善: より高速な動作
- ワークフロー最適化: より直感的な操作
開発環境は開発者の生産性に直結する重要な要素です。ぜひこの設定を参考に、あなた自身の最適な環境を構築してください!
💡 ポイント: 設定は日々の開発作業の中で育てるものです。使っていて引っかかった所をその日のうちに直していくと、少しずつ自分の手に馴染みます。
設定は個人のdotfilesリポジトリ(非公開)で管理しています。記事に載せたコードは、そこから該当部分を抜き出したものです。
wonderful!!