如果你曾經想用 Neovim 來進行 PHP 和 Laravel 的開發,這篇指南應該可以幫助你入門。如果你使用 VSCode,那麼可以看看這篇 文章。
在這篇文章中,我將使用 Neovim 搭配 LazyVim。LazyVim 是一個很棒的 Neovim 設定,開箱即用,擁有許多功能和工具。我花了比我願意承認的更多時間來配置 Vim 和 Neovim,而 LazyVim 幾乎省去了所有這些時間。當你開始熟悉 LazyVim 的配置後,你可以考慮從頭開始創建自己的配置。
安裝
這篇文章假設你正在使用最新版本的 Neovim(發布時是 v0.10.0)。如果你需要安裝它,可以在這裡為你的操作系統下載 這裡。
一旦你安裝好 Neovim,我們將使用 LazyVim。如果你不想使用 LazyVim 而想使用你自己的配置,也可以,但對於這篇文章來說,那樣的設置會更加複雜。
要安裝 LazyVim,你需要將倉庫克隆下來並移動到你的 Neovim 配置文件夾中(在 MacOS/Linux 系統上是 ~/.config/nvim
)。
git clone https://github.com/LazyVim/starter ~/.config/nvim
克隆完成後,你可以刪除 .git
文件夾,因為你現在不需要它,並且你可能會想對你的配置更改進行版本控制。
rm -rf ~/.config/nvim/.git
如果你使用的是 Windows,可以按照安裝說明 這裡 進行操作。
完成後,你可以運行 Neovim,它會下載所有 LazyVim 的插件和依賴項。
LazyVim 開箱即用,提供了方便的菜單以便你需要時進行導航。
LazyVim PHP 附加功能
LazyVim 最近添加了一個更新,可以快速添加 PHP 支援。你只需從主畫面點擊 x
進入附加功能菜單或輸入 :LazyExtras
。
在菜單中,你可以先輸入斜線然後輸入 php
來搜尋 PHP,即 /php
。斜線 /
開始在 Neovim 中搜尋。
將光標放在 lang.php
行,按 x
以切換附加功能。然後重新啟動 Neovim。現在,Neovim 將支援 PHP 語法並安裝 Phpactor LSP。
為了測試 LSP,我使用 Laravel Breeze 創建了一個新的 Laravel 項目。從項目目錄中,打開 Neovim,並使用 <leader>ff
打開 ProfileController
。在 Neovim 中,許多鍵盤命令都以 <leader>
鍵為前綴,預設為 space
。因此,要查找文件,輸入 space + f + f
。接著,你可以使用模糊搜尋器進行搜尋。
當第一次加載控制器時,Phpactor 會開始索引你的代碼庫,通常從項目的 Git 根目錄開始。
你還會看到許多錯誤和其他診斷信息。這些都是由 LSP 提供的,還包括代碼補全、跳轉定義、重構和許多其他功能。
如果你想修改基本控制器,你可以導航到 Controller
並點擊 gd
進行跳轉定義。
在跳轉定義後,你可以回到類定義並點擊 gr
進行跳轉到 Controller
類的引用。接下來,你可以使用 ctrl+o
跳回到之前的位置。
如果 Phpactor 對你有效,請不要猶豫繼續使用它。雖然它在處理 Laravel 的一些魔法和缺失類型方面有困難,但它完全免費且開源。你可以使用像 Laravel IDE Helper 的工具來改善這一點,該工具為模型、外觀和其他框架功能生成存根,以提供更好的自動補全。
就我個人而言,我使用 Intelephense LSP 的體驗更好,如果你來自 VSCode,你可能會對此比較熟悉。不幸的是,如果沒有 Intelephense 的高級版本,你會錯過 Phpactor 的一些功能,所以我建議如果你使用 Intelephense 的話,還是購買高級版。一個許可證可以用於 VSCode、Neovim 和任何其他支持 LSP 的編輯器。
要設置 Intelephense,你需要修改 LazyVim 配置。在 ~/.config/nvim
文件夾中,打開 options.lua
並添加以下行:
vim.g.lazyvim_php_lsp = "intelephense"
這告訴 LazyVim 設置 Intelephense。不過,你可能需要移除 Phpactor。要做到這一點,你可以輸入 <leader>cm
,這會打開 Mason。Mason 是一個用於安裝各種格式化工具、代碼檢查器和 LSP 的工具。在 Mason 菜單中,找到 Phpactor,然後使用 X
進行卸載。
設置 Laravel Pint 格式化
由於我們安裝了 Lazy Extras for PHP,因此 Laravel Pint 和 PHP-CS-Fixer 已經安裝好了。然而,PHP-CS-Fixer 被設置為默認工具。要更改這一點,我們可以在 Neovim 配置中創建一個新文件:~/.config/nvim/lua/plugins/php.lua
。你可以為這個文件命名任何你想要的名稱,但在這篇文章中,我們將使用它來進行所有與 PHP/Laravel 相關的配置。
在文件中,你可以包括以下內容:
return {
{
"stevearc/conform.nvim",
optional = true,
opts = {
formatters_by_ft = {
php = { { "pint", "php_cs_fixer" } },
},
},
},
}
這樣會將 Pint 設置為默認格式化工具,如果未找到它,則會退回到 PHP-CS-Fixer。通過這個更改,我可以回到 ProfileController
並添加一個未使用的導入並搞亂縮進,保存時會觸發格式化。
你可以進行的另一個可選更改是移除 phpcs 如果你不使用它。在 php.lua
文件中,只需添加另一個區塊,如下所示:
return {
{
-- 將 Laravel Pint 設置為默認 PHP 格式化工具,並將 PHP CS Fixer 設置為備用工具。
"stevearc/conform.nvim",
optional = true,
opts = {
formatters_by_ft = {
php = { { "pint", "php_cs_fixer" } },
},
},
},
{
-- 移除 phpcs 代碼檢查器。
"mfussenegger/nvim-lint",
optional = true,
opts = {
linters_by_ft = {
php = {},
},
},
},
}
我從 LazyVim 文檔 獲取這些配置。
測試
接下來,我們將設置 Neatest,以便可以直接在 Neovim 中運行測試。這是另一個可以通過輸入 :LazyExtras
,然後搜索「test.core」並用 X
切換的 LazyVim 附加功能。
然後,我們需要安裝 Neotest Pest 插件。將以下區塊添加到 php.lua
配置中。
return {
{
...
},
{
-- 添加 neotest-pest 插件以運行 PHP 測試。
-- 如果需要,還可以使用 PHPUnit 的包。
"nvim-neotest/neotest",
dependencies = { "V13Axel/neotest-pest" },
opts = { adapters = { "neotest-pest" } },
}
}
配置好測試後,打開一個測試文件,您可以使用 <leader>tr
運行單個測試,或使用 <leader>tt
運行整個文件。
使用 <leader>to
切換測試結果的摘要。
Blade 語法
添加對 Laravel Blade 的支持稍微複雜一些。LazyVim 已經設置了 Treesitter 來支持大多數語言的語法高亮。然而,Blade 預設未安裝,因此我們需要手動添加。
return {
{
...
},
{
-- 添加一個 Treesitter 解析器以提供 Blade 語法高亮。
"nvim-treesitter/nvim-treesitter",
opts = function(_, opts)
vim.list_extend(opts.ensure_installed, {
"blade",
"php_only",
})
end,
config = function(_, opts)
vim.filetype.add({
pattern = {
[".*%.blade%.php"] = "blade",
},
})
require("nvim-treesitter.configs").setup(opts)
local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
parser_config.blade = {
install_info = {
url = "https://github.com/EmranMR/tree-sitter-blade",
files = { "src/parser.c" },
branch = "main",
},
filetype = "blade",
}
end,
},
}
我們擴展默認的 Treesitter 配置來設置一個新的文件類型並下載 Blade 解析器。
重啟 Neovim 後,您可以運行 :TSInstall blade
來下載解析器。
接下來,我們需要添加一些 Treesitter 查詢以獲得更好的代碼支持。為此,我們需要在 Neovim 中創建一些新文件。
Blade 插件
輸入 :TSEditQuery injections blade
並添加以下內容:
((text) @injection.content
(#not-has-ancestor? @injection.content "envoy")
(#set! injection.combined)
(#set! injection.language php))
; tree-sitter-comment injection
; if available
((comment) @injection.content
(#set! injection.language "comment"))
; could be bash or zsh
; or whatever tree-sitter grammar you have.
((text) @injection.content
(#has-ancestor? @injection.content "envoy")
(#set! injection.combined)
(#set! injection.language bash))
((php_only) @injection.content
(#set! injection.language php_only))
((parameter) @injection.content
(#set! injection.include-children) ; You may need this, depending on your editor e.g Helix
(#set! injection.language "php-only"))
Blade 高亮
輸入 :TSEditQuery highlights blade
並新增:
(directive) @tag
(directive_start) @tag
(directive_end) @tag
(comment) @comment
Blade 摺疊
輸入 :TSEditQuery folds blade
並新增:
((directive_start) @start
(directive_end) @end.after
(#set! role block))
((bracket_start) @start
(bracket_end) @end
(#set! role block))
HTML 注入
最後,我們將為 Alpine 支援添加一些注入查詢。輸入 :TSEditQuery
並新增:
;; extends
; AlpineJS attributes
(attribute
(attribute_name) @_attr
(#lua-match? @_attr "^x%-%l")
(quoted_attribute_value
(attribute_value) @injection.content)
(#set! injection.language "javascript"))
; Blade escaped JS attributes
; <x-foo ::bar="baz" />
(element
(_
(tag_name) @_tag
(#lua-match? @_tag "^x%-%l")
(attribute
(attribute_name) @_attr
(#lua-match? @_attr "^::%l")
(quoted_attribute_value
(attribute_value) @injection.content)
(#set! injection.language "javascript"))))
; Blade PHP attributes
; <x-foo :bar="$baz" />
(element
(_
(tag_name) @_tag
(#lua-match? @_tag "^x%-%l")
(attribute
(attribute_name) @_attr
(#lua-match? @_attr "^:%l")
(quoted_attribute_value
(attribute_value) @injection.content)
(#set! injection.language "php_only"))))
現在,添加完所有內容後,保存並重新啟動,您應該能夠看到 Blade 文件的語法高亮顯示!
欲了解更多資訊和安裝說明,請訪問 repo 以獲取 Blade Treesitter 解析器。
片段
LazyVim 內建一個插件,可以輕鬆創建片段。要創建 PHP 片段,您可以創建一個新文件: ~/.config/nvim/snippets/php.json
,格式類似於以下範例:
{
"strict types": {
"prefix": "strict",
"description": "Add strict types declaration",
"body": [
"declare(strict_types=1);"
]
},
"inv": {
"prefix": "inv",
"description": "Create PHP __invoke method",
"body": [
"public function __invoke(${1}): ${2:void}",
"{",
" ${3}",
"}",
""
]
},
"public method": {
"prefix": "pubf",
"description": "Create a public method",
"body": [
"public function ${1}(${2}): ${3:void}",
"{",
" ${0}",
"}",
""
]
},
"protected method": {
"prefix": "prof",
"description": "Create a protected method",
"body": [
"protected function ${1}(${2}): ${3:void}",
"{",
" ${0}",
"}",
""
]
},
"private method": {
"prefix": "prif",
"description": "Create a private method",
"body": [
"private function ${1}(${2}): ${3:void}",
"{",
" ${0}",
"}",
""
]
},
"public static method": {
"prefix": "pubsf",
"description": "Create a public static method",
"body": [
"public static function ${1}(${2}): ${3:void}",
"{",
" ${0}",
"}",
""
]
},
"pest test (it) method": {
"prefix": "it",
"description": "Create a pest test",
"body": [
"it('${1}', function () {",
" // Arrange",
" ${0}",
"",
" // Act",
"",
" // Assert",
"",
"});"
]
}
}
您可以將任何其他片段添加到此文件中,或為其他語言創建文件以添加片段。
附加插件
Laravel.nvim
此插件可用於通過 <leader>la
以出色的搜索功能快速運行 Artisan 命令。或者,您可以使用 <leader>lr
列出應用程式中的所有路由。
return {
{
...
},
{
-- 添加 Laravel.nvim 插件,提供從 Neovim 運行 Artisan 命令的功能
--。
"adalessa/laravel.nvim",
dependencies = {
"nvim-telescope/telescope.nvim",
"tpope/vim-dotenv",
"MunifTanjim/nui.nvim",
"nvimtools/none-ls.nvim",
},
cmd = { "Sail", "Artisan", "Composer", "Npm", "Yarn", "Laravel" },
keys = {
{ "la", ":Laravel artisan" },
{ "lr", ":Laravel routes" },
{ "lm", ":Laravel related" },
},
event = { "VeryLazy" },
config = true,
opts = {
lsp_server = "intelephense",
features = { null_ls = { enable = false } },
},
},
}
Blade-Nav.nvim
新增了在 Blade 視圖上使用 Goto File 的功能,通過 gf
可以跳轉到組件和其他視圖。
return {
{
...
},
{
-- 添加了 blade-nav.nvim 插件,提供 Blade 文件的 Goto File 功能。
--
"ricardoramirezr/blade-nav.nvim",
dependencies = {
"hrsh7th/nvim-cmp",
},
ft = { "blade", "php" },
},
}
附加提示
LazyVim 的一個巨大優勢是文檔。如果你在 VSCode 中習慣做某些事情並希望在 Neovim 中實現,LazyVim 可能已經內置了這些功能。我建議你逐一查看 LazyVim 的每個部分來了解更多信息。
最重要的部分之一可能是鍵位映射。LazyVim 使用 which-key.nvim 幫助你記住配置的按鍵,但若要查看完整列表,請點擊 這裡。
想要 Git 支援嗎?LazyVim 已經提供了 LazyGit,這是一個非常好用的 Git 終端 UI。使用 <leader>gg
打開它。你甚至可以 直接安裝 LazyGit,例如通過 Homebrew 在命令行上運行 lazygit
。
需要額外的工具,如 PHPStan 或 Psalm 嗎?使用 <leader>cm
或 :Mason
打開 Mason 菜單並搜索你需要的工具。它有許多流行的 linter 和 formatter 可供安裝。
附加資源
LazyVim 文檔
如我前面提到的,LazyVim 提供了極好的文檔,絕對值得一讀。
Neovim 作為 PHP 和 JavaScript IDE
Jess Archer 在 Laracasts 上提供了一個出色的 課程,介紹如何設置 Neovim。如果你沒有訂閱 Laracasts,我非常推薦。自 2017 年以來,我一直是終身用戶。如果你對此感興趣,請使用我的 推薦連結。
Omakub
DHH(Ruby on Rails 的創建者)創建了 Omakub 套件,作為在 Ubuntu Linux 上快速設置開發環境的方法。即使你不使用 Ubuntu,Omakub 的倉庫仍然值得查看,因為它擁有許多優秀的配置和工具,其中之一是帶有 LazyVim 的 Neovim。
Kickstart.nvim
如果你想要比 LazyVim 更簡約的配置,Kickstart.nvim 是一個不錯的起點。你可以觀看這段由 TJ DeVries 製作的視頻,了解如何開始使用。即使你想繼續使用 LazyVim,這仍然是了解 Neovim 配置的寶貴資源。
總結
希望這能幫助你開始使用 Neovim。它是一個功能強大的編輯器,具有無限的可配置性。雖然不像 PhpStorm 那麼強大,但它幾乎可以免費達到相似的效果,並且佔用的 CPU 資源更少。
即使你不打算將 Neovim 作為主要的編輯器,我認為學習其快捷鍵仍然是有益的。我通常會在 Neovim 和 PhpStorm 之間分配時間,並嘗試使我的快捷鍵儘可能保持一致。幸運的是,JetBrains 的 IdeaVim 插件使這變得簡單。
供你參考,我創建了一個 repo,其中包含了我們在這篇文章中創建的所有文件。
如果你對設置或我可能遺漏的其他功能有任何疑問,請告訴我。
感謝你的閱讀!