vim交互

2025-09-09 00:00    #nvim  

Interaction

https://neovim.io/doc/user/lua.html#vim.ui.input()

当然有!这是一个非常好的问题,也是 Neovim 区别于传统 Vim 的一大优势。Neovim 提供了多种创建和管理“对话框”或交互式 UI 的方式,从简单的命令行输入到功能强大的浮动窗口应有尽有。

由于 Neovim 是一个终端应用(TUI),它的“对话框”通常以浮动窗口命令行提示的形式出现。

下面我将为你介绍三种由浅入深、最主流的实现方式:

  1. 标准 API (vim.ui): 最简单、最标准的交互方式。
  2. 美化插件 (dressing.nvim): 让标准 API 的对话框变得非常漂亮。
  3. UI 库 (nui.nvim): 完全从零开始构建你自己的、复杂的对话框。

方式一:使用标准 vim.ui API

Neovim 提供了一套标准的、可被插件覆盖的 UI 接口:vim.ui.input()vim.ui.select()。这是编写交互功能的首选方式,因为它具有最好的兼容性。

1. vim.ui.input() - 获取用户文本输入

这个函数会弹出一个提示,让用户输入一段文本。

示例: 创建一个命令,询问你的名字,然后打印欢迎信息。

 1-- 你可以把这个函数放在你的任意配置文件中
 2function AskNameAndGreet()
 3  vim.ui.input({ prompt = "What is your name? " }, function(name)
 4    if name then
 5      vim.notify("Hello, " .. name .. "!", vim.log.levels.INFO)
 6    else
 7      vim.notify("Greeting cancelled.", vim.log.levels.WARN)
 8    end
 9  end)
10end
11
12-- 创建一个用户命令来调用这个函数
13vim.api.nvim_create_user_command("Greet", AskNameAndGreet, {})

如何使用:

  1. 将上述代码添加到你的配置中(例如 init.lua)。
  2. 重启 Neovim。
  3. 在命令模式下输入 :Greet 并回车。

默认情况下,这会在命令行显示一个简单的输入提示。

2. vim.ui.select() - 让用户从列表中选择

这个函数会显示一个列表,让用户选择其中一项。

示例: 创建一个命令,让你选择一个编程语言,然后告诉你你的选择。

 1function ChooseLanguage()
 2  local items = { "C++", "Rust", "Lua", "TypeScript" }
 3  vim.ui.select(items, { prompt = "Choose your favorite language:" }, function(choice)
 4    if choice then
 5      vim.notify("You chose: " .. choice)
 6    else
 7      vim.notify("Selection cancelled.")
 8    end
 9  end)
10end
11
12vim.api.nvim_create_user_command("ChooseLang", ChooseLanguage, {})

如何使用:

  1. 将代码加入配置并重启。
  2. 输入 :ChooseLang 并回车。

默认情况下,这会在命令行显示带编号的选项列表。

重点vim.ui 的美妙之处在于,它的外观是可以被其他插件“美化”的。接下来我们看如何做到。


方式二:使用 dressing.nvim 升级对话框外观

dressing.nvim 是一个“胶水”插件,它的唯一作用就是将 vim.ui.inputvim.ui.select 的请求,转发给其他更美观的 UI 插件,比如 Telescopefzf-lua 或者它自己内置的漂亮浮动窗口。

这是实现漂亮对话框最简单、最推荐的方式。

配置 (lazy.nvim):

 1-- lua/plugins/dressing.lua
 2return {
 3  "stevearc/dressing.nvim",
 4  event = "VeryLazy",
 5  opts = {
 6    -- backend = { "telescope", "fzf_lua", "fzf", "builtin", "nui" }, -- 你可以指定后端的优先级
 7    input = {
 8      -- 使用内置的漂亮浮动窗口作为输入框
 9      backend = "builtin",
10    },
11    select = {
12      -- 使用内置的浮动窗口作为选择器
13      backend = "builtin",
14      -- 如果你更喜欢 Telescope,可以这样设置:
15      -- backend = "telescope",
16    },
17  },
18}

效果: 安装并配置好 dressing.nvim 后,你不需要修改任何代码。再次运行 :Greet:ChooseLang 命令,你会发现原来的命令行提示变成了一个居中的、带边框的漂亮浮动窗口!

Dressing.nvim
Example


方式三:使用 nui.nvim 构建完全自定义的对话框

当你需要构建一个非标准的、布局复杂的对话框时(例如,一个包含多个输入框和按钮的窗口),nui.nvim 就是你的终极武器。它是一个底层的 UI 组件库,让你像拼乐高一样组合出任意界面。

dressing.nvimbuiltin 后端就是基于 nui.nvim 构建的。

示例: 创建一个简单的带边框和标题的浮动窗口。

这是一个更底层的 API,代码会相对复杂一些。

 1function ShowCustomDialog()
 2  local nui = require("nui")
 3  local Popup = nui.require("nui.popup")
 4
 5  local popup = Popup({
 6    enter = true,        -- 创建后立即进入
 7    focusable = true,    -- 可聚焦
 8    border = {
 9      style = "rounded", -- 圆角边框
10      text = {
11        top = " My Custom Dialog ",
12        top_align = "center",
13      },
14    },
15    position = "50%",    -- 水平居中
16    size = {
17      width = "80%",
18      height = "60%",
19    },
20  })
21
22  -- 挂载 UI 组件,使其显示出来
23  popup:mount()
24
25  -- 当窗口关闭时,卸载它以释放资源
26  popup:on("BufLeave", function()
27    popup:unmount()
28  end)
29end
30
31vim.api.nvim_create_user_command("CustomDialog", ShowCustomDialog, {})

如何使用:

  1. 确保你已安装 nui.nvim (dressing.nvim 会自动安装它作为依赖)。
  2. 将代码加入配置并重启。
  3. 输入 :CustomDialog 即可看到一个空的、自定义样式的浮动窗口。你可以在此基础上添加更多组件。

总结与推荐

方法优点缺点适用场景
vim.ui API标准、可移植、简单默认外观简陋编写所有交互逻辑的首选。
dressing.nvim配置简单、效果立竿见影依赖其他插件vim.ui 变漂亮的“一劳永逸”方案。
nui.nvim极其灵活,完全控制 UIAPI 相对复杂,代码量大编写插件,或需要高度自定义的复杂对话框。

我的建议是:

始终使用 vim.ui.inputvim.ui.select 来编写你的交互功能。然后,安装 dressing.nvim 来美化它们。这样你的代码既标准又能在任何配置了 dressing.nvim 的 Neovim 上获得漂亮的 UI。只有在 dressing.nvim 无法满足你复杂的布局需求时,才考虑直接使用 nui.nvim

解放双手:snacks.nvim input模块语音输入全指南