blade-nav.nvim
为 Neovim 中的 Laravel 项目提供强大的导航、补全和内联值显示功能。
使用 gf 在控制器、路由、配置文件、Blade 视图、组件、Inertia 页面和语言文件之间跳转。以虚拟文本形式查看已解析的配置、环境变量和翻译值。为所有 Laravel 结构提供智能补全。
演示
https://github.com/user-attachments/assets/1b0aa688-93fe-4d87-b6ee-a6dbb96391ed
功能
导航 (gf)
将光标置于任意引用处,然后按 gf:
| 上下文 | 支持的语法 |
|---|---|
| Blade 指令 | @include, @extends, @component, @each, @includeIf, @includeWhen, @includeUnless, @includeFirst |
| Blade 组件 | <x-button />, <x-input.date /> |
| Livewire | <livewire:name />, @livewire('name') |
| 路由 | route('name'), to_route('name') |
| 视图 | view('name'), View::make('name'), Route::view('url', 'name') |
| Inertia | inertia('Page/Name'), Inertia::render('Page/Name') |
| 配置 | config('app.key'), Config::get('key'), Config::set('key') |
| 环境变量 | env('APP_KEY') |
| 翻译 | __('messages.welcome'), trans('messages.welcome') |
| Vue 导入 | <MyComponent /> (从 .vue 文件中的 <script> 导入解析) |
对于无法识别的语法,回退到标准的 Neovim gf。
补全
针对 nvim-cmp、blink.cmp 和 coq.nvim 的智能补全项:
| 触发条件 | 补全内容 |
|---|---|
@include(', @extends(', @component(' | Blade 视图名称 |
<x- | 组件名称 |
<livewire:, @livewire(' | Livewire 组件名称 |
route(', to_route(' | 路由名称 |
view(', View::make(', Route::view(' | 视图名称 |
inertia(', Inertia::render(' | Inertia 页面名称 |
config(', Config::get(', Config::set(' | 配置键 |
env(' | 环境变量名称 |
__(', trans(' | 翻译键 |
注释 (内联值)
将 config()、env()、__()、trans()、Config::get() 和 Config::set() 的解析值作为虚拟文本显示在每个调用旁边。
适用于 PHP、Blade 以及嵌入式 JavaScript 上下文。
命令:
| 命令 | 描述 |
|---|---|
:BladeNavToggleShowValues | 切换虚拟文本注释的开启/关闭 |
:BladeNavClearCache | 清除所有缓存的配置、环境变量和翻译映射 |
键位映射 (当 annotations.create_keymaps = true 时,默认):
| 键 | 操作 |
|---|---|
K | 在浮动窗口中显示解析后的值(带 LSP 回退) |
<leader>bv | 切换注释 |
<leader>bcc | 清除缓存 |
对于 __() 和 trans() 调用,K 会打开一个浮动窗口,显示所有语言环境的翻译。
安装
需要 Neovim >= 0.11 以及带有 php、blade、vue 和 html 解析器的 nvim-treesitter。
lazy.nvim
{
'ricardoramirezr/blade-nav.nvim',
dependencies = { -- optional, for nvim-cmp integration
'hrsh7th/nvim-cmp',
},
ft = { 'blade', 'php' },
opts = {},
}
对于 blink.cmp 用户,无需依赖项。请参阅下方 blink.cmp 配置。
vim-plug
call plug#begin()
Plug 'hrsh7th/nvim-cmp' " optional
Plug 'ricardoramirezr/blade-nav.nvim', { 'for': ['blade', 'php'] }
call plug#end()
lua require("blade-nav").setup()
packer.nvim
use {
'ricardoramirezr/blade-nav.nvim',
requires = {
'hrsh7th/nvim-cmp', -- optional
},
ft = { 'blade', 'php' },
config = function()
require('blade-nav').setup()
end,
}
配置
开箱即用。所有选项及其默认值:
require('blade-nav').setup({
-- Master switch. Auto-disabled outside Laravel unless force_enable = true.
enable = true,
force_enable = false,
cache_timeout = 50000, -- Cache TTL in ms
debug = false,
-- Completion behavior (applies to nvim-cmp, blink.cmp, and coq.nvim)
close_tag_on_complete = true,
include_routes_in_cmp = true,
-- Inertia
inertia_pages_path = nil, -- nil = "Pages" (default)
inertia_extensions = { 'vue', 'tsx', 'jsx', 'ts', 'js' },
-- Vue
jsconfig_path = './jsconfig.json',
-- Extra directories for <x-component> resolution
laravel_components_paths = {},
-- Navigation targets (gf)
handlers = {
directive = true,
view = true,
livewire = true,
route = true,
config = true,
component = true,
inertia = true,
vue = true,
lang = true,
},
-- Completion/integration sources
integrations = {
gf = true,
cmp = true,
coq = true,
},
-- Inline value annotations
annotations = {
show = false, -- Start with annotations visible
hl = 'Comment', -- Highlight group for virtual text
prefix = ' ⟶ ', -- Prefix before each value
max_len = 160, -- Max display length before truncation
debounce_ms = 120, -- Debounce for re-rendering on edits
show_on_load = true, -- Render annotations when a buffer loads
create_keymaps = true, -- Create K, <leader>bv, <leader>bcc maps
},
})
Laravel 检测
如果满足以下任一条件,则项目被检测为 Laravel:
artisan文件存在routes/web.php存在resources/views/目录存在composer.json需要laravel/framework或laravel/lumen-framework
设置 force_enable = true 以跳过检测。
自定义
nvim-cmp
local kind_icons = {
BladeNav = "",
}
require('cmp').setup({
formatting = {
format = function(entry, item)
if kind_icons[item.kind] then
item.kind = string.format('%s %s', kind_icons[item.kind], item.kind)
end
return item
end,
},
})
blink.cmp
在您的 blink.cmp 配置中将 blade-nav 注册为源提供者:
require('blink.cmp').setup({
sources = {
default = { 'lsp', 'blade-nav', 'snippets', 'path', 'buffer' },
providers = {
['blade-nav'] = {
name = 'blade-nav',
module = 'blade-nav.integrations.blink',
},
},
},
})
要自定义图标:
completion = {
menu = {
draw = {
components = {
kind_icon = {
text = function(ctx)
if ctx.source_name == 'blade-nav' then
return ' '
end
return ctx.kind_icon
end,
highlight = function(ctx)
if ctx.source_name == 'blade-nav' then
return 'BlinkCmpKindBladeNav'
end
return 'BlinkCmpKind' .. ctx.kind
end,
},
},
},
},
}
额外组件路径
require('blade-nav').setup({
laravel_components_paths = {
'app/View/Components/',
'resources/views/common',
},
})
使用 autopairs
如果你的 autopairs 插件会自动闭合标签:
require('blade-nav').setup({
close_tag_on_complete = false,
})
命令
| 命令 | 描述 |
|---|---|
:BladeNavToggleShowValues | 切换内联配置/环境变量/翻译注释 |
:BladeNavClearCache | 清除所有缓存(配置、环境变量、翻译、路由、视图) |
:BladeNavInstallArtisanCommand | 将 BladeNav artisan 命令安装到您的 Laravel 项目中 |
:checkhealth blade-nav | 诊断配置问题 |
健康检查
运行 :checkhealth blade-nav 以验证:
- Treesitter 解析器已安装
- 检测到 Laravel 项目
- PHP 和 artisan 可用
- 集成状态(cmp、blink、coq)
- 处理器配置
贡献
欢迎在 GitHub 提交 Issue 和 Pull Request。
许可证
MIT。参见 LICENSE。