https://github.com/beixiyo/vv-expand.nvim
Smart incremental selection: pair → LSP → treesitter → line. 智能增量选区(成对字符 → LSP → treesitter → 行)
https://github.com/beixiyo/vv-expand.nvim
lua neovim neovim-plugin nvim nvim-plugin selection treesitter wildfire
Last synced: 19 days ago
JSON representation
Smart incremental selection: pair → LSP → treesitter → line. 智能增量选区(成对字符 → LSP → treesitter → 行)
- Host: GitHub
- URL: https://github.com/beixiyo/vv-expand.nvim
- Owner: beixiyo
- License: mit
- Created: 2026-04-25T07:06:07.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-23T08:47:50.000Z (about 1 month ago)
- Last Synced: 2026-05-29T12:41:57.879Z (about 1 month ago)
- Topics: lua, neovim, neovim-plugin, nvim, nvim-plugin, selection, treesitter, wildfire
- Language: Lua
- Size: 15.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
vv-expand.nvim
智能增量选区 — 按 pair → LSP → treesitter → line 四层级联扩张
---
## 为什么要这个插件
[wildfire.nvim](https://github.com/SUSTech-data/wildfire.nvim) 只基于 treesitter 父节点扩张,**不理解行内视觉分隔符**:
- Markdown 里光标在 `` `user-picks.lua` `` 的 `user` 上 → 直接跳到整段 paragraph,不会先选 `` `user-picks.lua` ``
- `[pack/init.lua]` 内部光标 → 跳到整个 `inline_link` 节点,不会先选 `pack/init.lua`
vv-expand 先用**行内成对字符扫描**(括号 / 引号 / emphasis)做细粒度扩张,treesitter 只作为字符对失败后的补充层;LSP `selectionRange` 按语义结构扩张(标识符 → 表达式 → 语句 → 块),比纯 TS 粒度更贴近直觉。零运行时依赖,LSP / treesitter 缺失时自动降级
## 安装
```lua
{
'beixiyo/vv-expand.nvim',
event = { 'BufReadPost', 'BufNewFile' },
---@type ExpandConfig
opts = {
pairs = {
same = { '"', "'", '`', '*', '_', '-' }, -- 同字符配对
nested = { -- 嵌套括号对
{ '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' },
},
},
layers = { 'word', 'pair', 'lsp', 'treesitter', 'line' }, -- 扩张策略优先级
keymaps = {
init = '', -- normal 模式起手
expand = '', -- visual 模式扩张
shrink = '', -- visual 模式回缩
},
subword_delimiters = '-=+/:;|,.?\\!@#$%^&*~', -- 逐段扩张分隔符;nil 则禁用
filetype_exclude = { 'qf', 'help', 'dashboard', 'vv-explorer', 'vv-task-panel' },
lsp_timeout = 400, -- LSP selectionRange 超时(ms)
},
}
```
## 配置
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `pairs.same` | `string[]` | `'"', "'", '`', '*', '_', '-'` | 同字符配对列表(两侧同为字母数字时视为词内,不配对) |
| `pairs.nested` | `string[][]` | `() [] {} <>` | 嵌套括号对,基于栈匹配 |
| `layers` | `string[]` | `{ 'word', 'pair', 'lsp', 'treesitter', 'line' }` | 扩张策略优先级;想关掉某层从列表删除即可 |
| `keymaps.init` | `string` | `''` | normal 模式开始选区 |
| `keymaps.expand` | `string` | `''` | visual 模式向外扩一级 |
| `keymaps.shrink` | `string` | `''` | visual 模式向内缩一级 |
| `filetype_exclude` | `string[]` | `{ 'qf', 'help', ... }` | 排除的 filetype,不绑定按键 |
| `subword_delimiters` | `string?` | `'-=+/:;\|,.?\\!@#$%^&*~'` | 逐段扩张的分隔符字符集;`nil` 则禁用逐段扩张,直接 iw → iW |
| `lsp_timeout` | `integer` | `400` | LSP `selectionRange` 请求超时 ms |