📘
nvimでphpを開くlspの設定(intelephenseで補完とか)
キラキラしたやつはさておいて、lsp
を入れといた方がいいかなと。となるとphpではまあほぼほぼintelephense
となるのだが、これに関してあんまり記事がなかったような、みつけられてないだけかもしれないけど。
環境
$ nvim --version
NVIM v0.10.3
Build type: RelWithDebInfo
LuaJIT 2.1.1713484068
Run "nvim -V1 -v" for more info
init.lua
~/.config/nvim/init.lua
-- Lazy.nvimの初期化
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
-- Mason (LSPやツールのインストーラ)
{
"williamboman/mason.nvim",
config = function()
require("mason").setup()
end,
},
-- MasonとLSPconfigの連携
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "neovim/nvim-lspconfig" },
config = function()
require("mason-lspconfig").setup({
ensure_installed = { "jsonls" }, -- JSON LSPをインストール
})
-- LSPの設定
local lspconfig = require("lspconfig")
lspconfig.jsonls.setup({
settings = {
json = {
schemas = require("schemastore").json.schemas(), -- スキーマサポートを追加
validate = { enable = true }, -- 検証を有効化
},
},
})
end,
},
-- JSONスキーマのサポート (オプション)
{
"b0o/schemastore.nvim",
},
})
などとしてnvimを起動
ここではphp
ではなくjson
で様子を見ている。適当なjsonを開いてミスってやると
こうなるはずだ。
--- a/init.lua
+++ b/init.lua
@@ -33,13 +33,42 @@ require("lazy").setup({
-- LSPの設定
local lspconfig = require("lspconfig")
+ local capabilities = require("cmp_nvim_lsp").default_capabilities()
+
+ -- JSON LSPの設定
lspconfig.jsonls.setup({
- settings = {
- json = {
- schemas = require("schemastore").json.schemas(), -- スキーマサポートを追加
- validate = { enable = true }, -- 検証を有効化
- },
+ capabilities = capabilities,
+ })
+ end,
+ },
+
+ -- nvim-cmp (補完エンジン)
+ {
+ "hrsh7th/nvim-cmp",
+ dependencies = {
+ "hrsh7th/cmp-nvim-lsp", -- LSP補完
+ "hrsh7th/cmp-buffer", -- バッファ補完
+ "hrsh7th/cmp-path", -- パス補完
+ "hrsh7th/cmp-vsnip", -- スニペット補完
+ "hrsh7th/vim-vsnip", -- スニペットエンジン
+ },
+ config = function()
+ local cmp = require("cmp")
+ cmp.setup({
+ snippet = {
+ expand = function(args)
+ vim.fn["vsnip#anonymous"](args.body)
+ end,
},
+ mapping = cmp.mapping.preset.insert({
+ ["<C-y>"] = cmp.mapping.confirm({ select = true }), -- Enterで補完確定
+ ["<C-Space>"] = cmp.mapping.complete(), -- 手動補完
+ }),
+ sources = cmp.config.sources({
+ { name = "nvim_lsp" },
+ { name = "buffer" },
+ { name = "path" },
+ }),
})
end,
},
などして
これでinstallする。ただjsonの補完つのはあんまなさそうなので、さっさとintelephense
を入れる。なぜ最初にjsonから初めたかというと、他のlspを追記するデモを作りたかった為なのでご了承願いたい。
--- a/init.lua
+++ b/init.lua
@@ -28,13 +28,19 @@ require("lazy").setup({
dependencies = { "neovim/nvim-lspconfig" },
config = function()
require("mason-lspconfig").setup({
- ensure_installed = { "jsonls" }, -- JSON LSPをインストール
+ ensure_installed = { "intelephense", "jsonls" },
})
-- LSPの設定
local lspconfig = require("lspconfig")
local capabilities = require("cmp_nvim_lsp").default_capabilities()
+ -- PHP LSPの設定
+ lspconfig.intelephense.setup({
+ capabilities = capabilities,
+ root_dir = require("lspconfig").util.root_pattern("composer.json", ".git", "."),
+ })
+
-- JSON LSPの設定
lspconfig.jsonls.setup({
capabilities = capabilities,
使ってみる
で、これは
root_dir = require("lspconfig").util.root_pattern("composer.json", ".git", "."),
ここにあるように
- composer.json
- .git
がrootに存在しないと発動しないので、適当に
$ mkdir test
$ cd test/
$ git init
などすると .git ができるので
$ nvim moge.php
などで起動してみる、すると
intelephense
のinstallが初まり、コンプリートした後
<?php
$db = new PDO();
このようなコードを書いてみると
こうなる
無視してつっこんでいって
<?php
$db = new PDO();
$db-> #(Ctrl + nとか押す)
とかすると
こうなるわけだ
もうちょい改良する
--- a/init.lua
+++ b/init.lua
@@ -35,15 +35,28 @@ require("lazy").setup({
local lspconfig = require("lspconfig")
local capabilities = require("cmp_nvim_lsp").default_capabilities()
+ -- 共通の on_attach 関数 (シグネチャヘルプ自動表示を含む)
+ local on_attach = function(client, bufnr)
+ -- キーマッピングでシグネチャヘルプを呼び出す
+ vim.api.nvim_buf_set_keymap(bufnr, "i", "<C-k>", "<cmd>lua vim.lsp.buf.signature_help()<CR>", { noremap = true, silent = true })
+
+ -- 自動でシグネチャヘルプを表示
+ vim.cmd([[
+ autocmd CursorHoldI * lua vim.lsp.buf.signature_help()
+ ]])
+ end
+
-- PHP LSPの設定
lspconfig.intelephense.setup({
capabilities = capabilities,
+ on_attach = on_attach,
root_dir = require("lspconfig").util.root_pattern("composer.json", ".git", "."),
})
-- JSON LSPの設定
lspconfig.jsonls.setup({
capabilities = capabilities,
+ on_attach = on_attach,
})
end,
},
@@ -69,6 +82,13 @@ require("lazy").setup({
mapping = cmp.mapping.preset.insert({
["<C-y>"] = cmp.mapping.confirm({ select = true }), -- Enterで補完確定
["<C-Space>"] = cmp.mapping.complete(), -- 手動補完
+ ["<C-k>"] = cmp.mapping(function(fallback)
+ if vim.fn.pumvisible() == 1 then
+ vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<C-n>", true, true, true), "n")
+ else
+ vim.lsp.buf.signature_help()
+ end
+ end, { "i", "s" }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
などすると
Ctrl-kでこれが出てくるようになる。キーマップは議論の余地を大いに残すが
またオブジェクトの補完が
このように自動になった。
たとえば
まあなんかゴリゴリにエクストリームプログラミングしてもわりと何かやっとるって感じになる。多分
laravelプロジェクトを開くと
頻出する問題ではあるけど、このようにlaravelプロジェクトを開くとエラーまみれになる。まあこれはある意味しゃーないところがあり、パスを解決できてないのでこうなっている。
composer require --dev barryvdh/laravel-ide-helper
php artisan ide-helper:generate
php artisan ide-helper:models
して
--- a/init.lua
+++ b/init.lua
@@ -51,6 +51,21 @@ require("lazy").setup({
capabilities = capabilities,
on_attach = on_attach,
root_dir = require("lspconfig").util.root_pattern("composer.json", ".git", "."),
+ settings = {
+ intelephense = {
+ -- Laravelの補完強化 (ide-helperファイルを含める)
+ files = {
+ maxSize = 5000000, -- 読み込むファイルの最大サイズを変更
+ associations = {
+ "*.php", -- PHPファイル全般
+ },
+ includePaths = {
+ "./_ide_helper.php", -- `ide-helper` ファイルを含める
+ "./_ide_helper_models.php", -- モデル補完ファイルを含める
+ },
+ },
+ },
+ },
})
-- JSON LSPの設定
このように変更する。すると
メソッドの説明がウインドウで提示されているのがわかるだろうか
とか
とか、また
何も使ってないとこんなんになったりとか
そのうち
xdebug
を使った記事でも再編するか...
ほしい人がいるとは思えないが
この記事のために書き起したlua
~/.config/nvim/init.lua
-- Lazy.nvimの初期化
vim.g.mapleader = " " -- Leaderキーをスペースに設定
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
-- Mason (LSPやツールのインストーラ)
{
"williamboman/mason.nvim",
config = function()
require("mason").setup()
end,
},
-- MasonとLSPconfigの連携
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "neovim/nvim-lspconfig" },
config = function()
require("mason-lspconfig").setup({
ensure_installed = { "intelephense", "jsonls" },
})
-- LSPの設定
local lspconfig = require("lspconfig")
local capabilities = require("cmp_nvim_lsp").default_capabilities()
-- 共通の on_attach 関数 (シグネチャヘルプ自動表示を含む)
local on_attach = function(client, bufnr)
-- キーマッピングでシグネチャヘルプを呼び出す
vim.api.nvim_buf_set_keymap(bufnr, "i", "<C-k>", "<cmd>lua vim.lsp.buf.signature_help()<CR>", { noremap = true, silent = true })
-- 自動でシグネチャヘルプを表示
vim.cmd([[
autocmd CursorHoldI * lua vim.lsp.buf.signature_help()
]])
end
-- PHP LSPの設定
lspconfig.intelephense.setup({
capabilities = capabilities,
on_attach = on_attach,
root_dir = require("lspconfig").util.root_pattern("composer.json", ".git", "."),
settings = {
intelephense = {
-- Laravelの補完強化 (ide-helperファイルを含める)
files = {
maxSize = 5000000, -- 読み込むファイルの最大サイズを変更
associations = {
"*.php", -- PHPファイル全般
},
includePaths = {
"./_ide_helper.php", -- `ide-helper` ファイルを含める
"./_ide_helper_models.php", -- モデル補完ファイルを含める
},
},
},
},
})
-- JSON LSPの設定
lspconfig.jsonls.setup({
capabilities = capabilities,
on_attach = on_attach,
})
end,
},
-- nvim-cmp (補完エンジン)
{
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp", -- LSP補完
"hrsh7th/cmp-buffer", -- バッファ補完
"hrsh7th/cmp-path", -- パス補完
"hrsh7th/cmp-vsnip", -- スニペット補完
"hrsh7th/vim-vsnip", -- スニペットエンジン
},
config = function()
local cmp = require("cmp")
cmp.setup({
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-y>"] = cmp.mapping.confirm({ select = true }), -- Enterで補完確定
["<C-Space>"] = cmp.mapping.complete(), -- 手動補完
["<C-k>"] = cmp.mapping(function(fallback)
if vim.fn.pumvisible() == 1 then
vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<C-n>", true, true, true), "n")
else
vim.lsp.buf.signature_help()
end
end, { "i", "s" }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "buffer" },
{ name = "path" },
}),
})
end,
},
-- JSONスキーマのサポート (オプション)
{
"b0o/schemastore.nvim",
},
})
Discussion