目次
TL;DR
- macOSでのIME問題は
im-select.nvim+macismで解決できる - Neovim 0.11ではプラグインの互換性に注意が必要(Telescopeは
0.1.xタグを使用) - Nerd Fontなしでもシンプルな設定で十分実用的な環境が作れる
- LSP/補完は
mason.nvim+nvim-cmpの組み合わせが初心者にも扱いやすい
はじめに
この記事では、macOSでNeovimを快適に使うための設定を解説します。Vimの基本操作(モード切り替え、カーソル移動、保存・終了など)は知っているが、Neovimのプラグイン設定は初めてという方を想定しています。
以下の4つのトピックを扱います:
- macOS IME問題の解決 - 日本語入力で最もハマりやすいポイント
- Neovim 0.11のプラグイン互換性 - 最新版を使う際の注意点
- Nerd Font不要のミニマル設定 - フォント設定なしで使える環境
- LSP/補完の基本設定 - 定義ジャンプや自動補完を実現
前提環境
この記事の設定は以下の環境で動作確認しています:
| 項目 | バージョン |
|---|---|
| macOS | Sonoma 14.x 以降 |
| Neovim | 0.11.3 以降(LSP新APIに必要) |
| Homebrew | インストール済み |
| ターミナル | iTerm2(Terminal.appでも可) |
まだNeovimをインストールしていない場合は、以下のコマンドでインストールできます:
brew install neovim
1. macOS IME問題の解決
問題の概要
macOSでNeovim(Vim)を使う際、多くの人がつまずくのがIME(日本語入力)の問題です。
具体的には: 日本語入力モードのままノーマルモードに戻ると、jやkなどのコマンドが効かなくなる。
これは、InsertモードからNormalモードに戻っても、macOSのIME状態がそのままになるためです。日本語で文章を書いた後、Escでノーマルモードに戻ると、IMEが日本語入力のままなので、jjj...と入力しても「っっっ…」と日本語が入力されてしまいます。
解決策: im-select.nvim + macism
この問題を解決するには、2つのコンポーネントを組み合わせます:
-
im-select.nvim(Neovimプラグイン)
- モード切り替え(Insert→Normal等)を検知
- 外部のCLIツールを呼び出してIMEを切り替え
-
macism(CLIツール)
- 実際にmacOSのIMEを切り替えるコマンド
- im-select.nvimから呼び出される
つまり、im-select.nvimがNeovim内でモード変更を監視し、変更を検知したらmacismコマンドを実行してIMEを英数に切り替える、という仕組みです。
なぜmacismなのか
im-select.nvimはmacOS上でIMEを切り替えるCLIツールを呼び出します。macOS用のツールは複数ありますが、im-select.nvimの公式READMEではmacismを推奨しています。
Please install macism, this is the only one CLI tool can switch CJK and English input methods in macOS correctly. — im-select.nvim README
macismは、日本語などのCJK入力ソースを確実に切り替えられます。他のツール(input-source-switcher等)ではmacOSのバグにより、メニューバーのアイコンは変わっても実際には切り替わらない問題が発生することがあるようです。
インストール手順
macismは公式のHomebrew tapにないため、サードパーティのtapを追加する必要があります:
# tapの追加
brew tap laishulu/homebrew
# macismのインストール
brew install laishulu/homebrew/macism
インストール後、動作確認をしてみましょう:
# 現在の入力ソースを確認
macism
# 出力例: com.apple.inputmethod.Kotoeri.RomajiTyping.Japanese
# または: com.apple.keylayout.ABC
Neovimの設定
im-select.nvimプラグインを使って、モード切り替え時の動作を設定します。
-- プラグインマネージャー(lazy.nvim)での設定例
{
"keaising/im-select.nvim",
config = function()
require("im_select").setup({
-- 切り替え先の入力ソース(英数キーボード)
default_im_select = "com.apple.keylayout.ABC",
-- macismの絶対パス(Intel Macの場合は /usr/local/bin/macism)
default_command = "/opt/homebrew/bin/macism",
-- 英数に切り替えるタイミング
set_default_events = {
"VimEnter", -- Neovim起動時
"FocusGained", -- ウィンドウにフォーカスが戻った時
"InsertLeave", -- Insertモードを抜けた時
"CmdlineLeave" -- コマンドラインモードを抜けた時
},
-- InsertEnter時に前のIMEに戻す設定(空にして無効化)
set_previous_events = {},
})
end,
}
設定のポイント: なぜ set_previous_events = {} にしたか
デフォルトでは、set_previous_events = { "InsertEnter" } となっており、Insertモードに入ると直前のIME状態に戻ります。
しかし、この設定を空にして無効化しました。理由は以下の通りです:
トレードオフの比較:
| 設定 | メリット | デメリット |
|---|---|---|
{ "InsertEnter" }(デフォルト) | 日本語の連続入力に便利 | 英語コードを書く際に毎回切り替えが必要 |
{}(無効化) | 常に英数から始まるので予測しやすい | 日本語を続けて書く際は手動切り替え |
プログラミングでは英語入力が圧倒的に多いため、「常に英数に戻る」動作の方が快適でした。日本語を書く際は、手動で日本語入力に切り替えれば済みます。
もし日本語でドキュメントを書く機会が多い場合は、デフォルトの { "InsertEnter" } の方が便利かもしれません。
2. Neovim 0.11のプラグイン互換性
問題の概要
2025年3月にリリースされたNeovim 0.11では、LSP関連のAPIが大きく変更されました。この影響で、一部のプラグインがそのままでは動作しない場合があります。
Telescope.nvimの互換性問題
最も多くのユーザーが遭遇するのが、Telescope.nvim(ファジーファインダー)の問題です。
症状: Telescopeを開くとエラーが発生する、または表示がおかしい
原因: Telescope.nvimの安定版ブランチ(0.1.x)がNeovim 0.11のAPI変更に追従していない
解決策: 0.1.xタグを使用する(最新版では修正済み)
-- Neovim 0.11対応版
{
"nvim-telescope/telescope.nvim",
tag = "0.1.x", -- 安定版タグ(Neovim 0.11対応済み)
dependencies = { "nvim-lua/plenary.nvim" },
}
バージョン選択のポイント
2025年末時点では、Telescope v0.2.0もリリースされています。
| 指定方法 | 特徴 | 推奨度 |
|---|---|---|
tag = "0.1.x" | 安定版、Neovim 0.11対応済み | 推奨 |
tag = "0.1.8" 等 | 特定バージョン固定 | 再現性重視なら |
branch = "master" | 最新開発版 | 新機能を試したい場合 |
以前は0.1.xブランチがNeovim 0.11非対応でしたが、現在は修正されています。特に理由がなければtag = "0.1.x"を使えば問題ありません。
その他の互換性確認方法
プラグインが動作しない場合は、以下の手順で調査できます:
- GitHubのIssuesを確認:
[プラグイン名] Neovim 0.11で検索 - READMEのRequirementsを確認: 対応するNeovimバージョンが明記されていることが多い
- 最新版に更新:
:Lazy syncでプラグインを最新化
3. Nerd Font不要のミニマル設定
Nerd Fontとは
多くのNeovim設定記事では「Nerd Fontをインストールしてください」と書かれています。Nerd Fontは、通常のフォントにアイコン(ファイルタイプ、Git状態、フォルダなど)を追加したフォントファミリーです。
しかし、Nerd Fontの導入には以下のステップが必要です:
- Nerd Fontのダウンロード
- システムへのインストール
- ターミナルのフォント設定変更
- 設定の反映確認
なぜNerd Fontなしを選んだか
Nerd Fontを使わない選択をした理由は以下の通りです:
メリット:
- ターミナルのフォント設定をいじらなくて済む
- 複数マシン間で設定を共有しやすい(フォントのインストール不要)
- シンプルで軽量な見た目
デメリット:
- ファイルタイプが視覚的に分かりにくい
- 見た目が地味
プログラミング中はファイル名を見ればファイルタイプは分かるため、アイコンがなくても実用上の問題はありませんでした。
アイコンを無効化する設定
主要なプラグインでアイコンを無効化する方法を紹介します。
nvim-tree(ファイルエクスプローラー)
{
"nvim-tree/nvim-tree.lua",
config = function()
require("nvim-tree").setup({
renderer = {
icons = {
show = {
file = false, -- ファイルアイコン非表示
folder = false, -- フォルダアイコン非表示
folder_arrow = true, -- 展開/折りたたみの矢印は表示
git = false, -- Git状態アイコン非表示
},
glyphs = {
folder = {
arrow_closed = ">", -- 折りたたみ時の矢印
arrow_open = "v", -- 展開時の矢印
},
},
},
},
})
end,
}
lualine(ステータスライン)
{
"nvim-lualine/lualine.nvim",
config = function()
require("lualine").setup({
options = {
icons_enabled = false, -- アイコン全体を無効化
section_separators = "", -- セクション区切りなし
component_separators = "|", -- 区切り文字をシンプルに
},
})
end,
}
見た目の比較
Nerd Fontあり:
init.lua main lua utf-8 100% 42:1
Nerd Fontなし:
NORMAL | main | init.lua | lua | utf-8 | 100% | 42:1
アイコンの代わりにテキストで情報が表示されます。慣れれば十分読みやすいです。
4. LSP/補完の基本設定
LSPとは
LSP(Language Server Protocol)は、エディタと言語サーバーの間の通信プロトコルです。これを使うことで、以下の機能が実現できます:
- 定義ジャンプ: 関数や変数の定義元にジャンプ
- 参照検索: 関数や変数がどこで使われているか一覧表示
- 自動補完: 入力中に候補を表示
- 診断: エラーや警告をリアルタイムで表示
- リネーム: シンボル名を一括変更
プラグイン構成の全体像
LSP/補完を実現するために、以下のプラグインを組み合わせます:
mason.nvim # 言語サーバーのインストーラー
└── mason-lspconfig # masonとlspconfigの橋渡し
└── nvim-lspconfig # 言語サーバーの設定
nvim-cmp # 補完エンジン
├── cmp-nvim-lsp # LSPからの補完ソース
├── cmp-buffer # バッファ内の単語を補完
├── cmp-path # ファイルパスを補完
└── LuaSnip # スニペット展開
なぜこの構成を選んだか
| 観点 | 選択 | 理由 |
|---|---|---|
| LSPインストール | mason.nvim | GUIで管理でき、初心者に分かりやすい |
| 補完エンジン | nvim-cmp | 最も広く使われており、情報が豊富 |
| スニペット | LuaSnip | nvim-cmpとの連携がスムーズ |
mason.nvimによる言語サーバーの自動インストール
mason.nvimを使うと、:MasonコマンドでGUIから言語サーバーを管理できます。また、mason-lspconfigを使えば、必要な言語サーバーを自動でインストールできます。
{
"neovim/nvim-lspconfig",
dependencies = {
"williamboman/mason.nvim",
"williamboman/mason-lspconfig.nvim",
},
config = function()
-- masonの初期化(:Masonコマンドが使えるようになる)
require("mason").setup()
-- 自動インストールする言語サーバーを指定
require("mason-lspconfig").setup({
ensure_installed = {
"lua_ls", -- Lua
"ts_ls", -- TypeScript/JavaScript
"pyright", -- Python
},
})
end,
}
初回起動時に、指定した言語サーバーが自動でインストールされます。
Neovim 0.11の新しいLSP設定API
Neovim 0.11では、LSPの設定方法が大きく変わりました。
旧来の方法(nvim-lspconfig依存):
local lspconfig = require("lspconfig")
lspconfig.lua_ls.setup({
settings = {
Lua = {
diagnostics = { globals = { "vim" } },
},
},
})
新しい方法(Neovim 0.11.3+ネイティブ):
-- 言語サーバーごとの設定
vim.lsp.config('lua_ls', {
settings = {
Lua = {
diagnostics = { globals = { "vim" } },
},
},
})
-- 言語サーバーを有効化
vim.lsp.enable({ "lua_ls", "pyright", "ts_ls" })
Note: nvim-lspconfigは廃止されていません。内部的に
vim.lsp.configを呼び出すラッパーとして機能するため、従来のlspconfig.xxx.setup({})形式も引き続き使えます。新規で設定する場合は、プラグイン依存を減らせる新APIがおすすめです。
新しいAPIを使うメリット:
- Neovimのビルトイン機能なので、将来的に安定
- シンプルで分かりやすい記述
- ファイルベースの設定も可能(
~/.config/nvim/lsp/配下)
LSPキーマップの設定
LSPの機能をキーに割り当てます。LspAttachイベントを使うと、LSPが有効なバッファでのみキーマップが設定されます。
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local bufnr = args.buf
local opts = { buffer = bufnr, silent = true }
-- 定義・宣言・実装へのジャンプ
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
-- ドキュメント表示・編集操作
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
-- 診断の移動
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float, opts)
end,
})
なぜLspAttachイベントを使うか
キーマップの設定方法には複数の選択肢があります:
| 方法 | 説明 | 問題点 |
|---|---|---|
| グローバルキーマップ | 全バッファで有効 | LSPがないファイルでもキーが有効 |
| lspconfig.on_attach | lspconfig経由で設定 | lspconfigに依存 |
| LspAttachイベント | LSPアタッチ時に設定 | なし |
LspAttachはNeovimのビルトインイベントなので、プラグインに依存せず、確実に動作します。
nvim-cmpによる補完設定
補完エンジンnvim-cmpの基本設定です。
{
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp", -- LSP補完ソース
"hrsh7th/cmp-buffer", -- バッファ補完
"hrsh7th/cmp-path", -- パス補完
"L3MON4D3/LuaSnip", -- スニペットエンジン
"saadparwaiz1/cmp_luasnip", -- スニペット補完
},
config = function()
local cmp = require("cmp")
local luasnip = require("luasnip")
cmp.setup({
-- スニペット展開の設定
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
-- キーマップ
mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(), -- 手動で補完を開く
["<C-e>"] = cmp.mapping.abort(), -- 補完をキャンセル
["<CR>"] = cmp.mapping.confirm({ select = true }), -- 確定
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item() -- 次の候補
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item() -- 前の候補
else
fallback()
end
end, { "i", "s" }),
}),
-- 補完ソースの優先順位
sources = cmp.config.sources({
{ name = "nvim_lsp" }, -- LSP(最優先)
{ name = "luasnip" }, -- スニペット
}, {
{ name = "buffer" }, -- バッファ内の単語
{ name = "path" }, -- ファイルパス
}),
})
end,
}
補完ソースの優先順位は、最初のグループ(LSP、スニペット)が優先され、該当がなければ次のグループ(バッファ、パス)から候補が表示されます。
設定ファイルの構成について
この記事で紹介した設定は、すべて~/.config/nvim/init.lua一つにまとめています。
なぜ単一ファイルにしたか:
| 構成 | メリット | デメリット |
|---|---|---|
| 単一ファイル | 全体が見渡せる、検索しやすい | 長くなると見づらい |
| 複数ファイル | 責務が明確、大規模向き | ファイル間の依存関係が複雑 |
400行程度の設定であれば、単一ファイルで十分管理できます。設定が増えてきたら分割を検討すれば良いでしょう。
まとめ
この記事では、macOSでNeovimを快適に使うための4つの設定を解説しました。
- IME問題:
im-select.nvim+macismで解決。set_previous_events = {}で常に英数に戻す設定がプログラミング向き - Neovim 0.11互換性: Telescopeは
0.1.xタグを使用(修正済み) - Nerd Font不要: 各プラグインでアイコンを無効化すればシンプルな環境が作れる
- LSP/補完: mason.nvim + nvim-cmpの組み合わせで、GUIでの管理と豊富な補完が実現
これらの設定は、あくまで一つの選択肢です。使っていく中で、自分の好みや用途に合わせてカスタマイズしていってください。
参考資料
公式ドキュメント
プラグイン
- im-select.nvim - IME自動切り替え
- macism - macOS用IME制御CLI
- nvim-lspconfig - LSP設定
- mason.nvim - 言語サーバー管理
- nvim-cmp - 補完エンジン
- telescope.nvim - ファジーファインダー
- lazy.nvim - プラグインマネージャー