lazyvim折腾日记(6)

lazyvim 折腾日记(6)

前言

由于 lazyvim 在 14.x 版本移除了 nvim-cmp 的支持,详见官方 what's new

以前在 nvim-cmp 下的配置都无用了,需要基于 blink-cmprime-ls 进行配置

本文的目标为:基于 blink-cmp 配置 rime-ls

实施步骤

本文主要参考页面为

  1. 用数字选词以后还需要一次空格才能上屏幕
  2. cmp-lsp-rimels
  3. nvim+blink.cmp 配置示例

首先是安装安装 cmp-lsp-rimels

-- ~/.config/nvim/lua/plugins/lsp/init.lua
...
{
  "liubianshi/cmp-lsp-rimels",
  keys = { { "<localleader>f", mode = "i" } },
  branch = "blink.cmp",  -- 注意是 blink.cmp 分支而不是主分支
    config = function()
    vim.opt.iskeyword = "_,49-57,A-Z,a-z"
    vim.system({ "rime_ls", "--listen", "127.0.0.1:9257" }, { detach = true })
    require("rimels").setup({
      cmd = vim.lsp.rpc.connect("127.0.0.1", 9257),
      shared_data_dir = "/Library/Input Methods/Squirrel.app/Contents/SharedSupport", -- 本文使用 Mac 所以是该地址
    -- 在实际实践中还需要配置 *rime_user_dir* , 在本机中的安装地址与默认地址相同(~/.local/share/rime-ls/),所以不做额外配置
    })
  end,
},
...

其次是参考 链接1 复制代码

-- ~/.config/nvim/lua/plugins/lsp/init.lua
...
{
    "neovim/nvim-lspconfig",
    dependencies = {
      "williamboman/mason.nvim",
      "williamboman/mason-lspconfig.nvim",
      "saghen/blink.cmp",
    },
    config = function()
      local lsp_capabilities = vim.lsp.protocol.make_client_capabilities()
      lsp_capabilities = require("blink.cmp").get_lsp_capabilities(lsp_capabilities)
      local lspconfig = require("lspconfig")
      lspconfig.lua_ls.setup({
        capabilities = lsp_capabilities,
      })
      -- 下文来源于 * 链接1* 目的是为了数字键直接上屏
      require("blink.cmp.completion.list").show_emitter:on(function(event)
        -- if last char is number, and the only completion item is provided by rime-ls, accept it
        local items = event.items
        local line = event.context.line
        local col = vim.fn.col(".") - 1
        if #items ~= 1 then
          return
        end
        if line:sub(col - 1, col):match("%a%d") == nil then
          return
        end
        local item = items[1]
        local client = vim.lsp.get_client_by_id(item.client_id)
        if (not client) or client.name ~= "rime_ls" then
          return
        end
        require("blink.cmp").accept({ index = 1 })
      end)
    end,
  }
...

参考 链接3 针对 blink-cmp 进行配置

-- ~/.config/nvim/lua/plugins/lsp/init.lua
...
{
    "saghen/blink.cmp",
    dependencies = {
      "L3MON4D3/LuaSnip",
      "mikavilpas/blink-ripgrep.nvim",
      "Kaiser-Yang/blink-cmp-dictionary",
      {
        "Kaiser-Yang/blink-cmp-git",
        dependencies = { "nvim-lua/plenary.nvim" },
      },
    },
    -- 下文来源 *链接3*
    opts = {
      sources = {
        providers = {
          lsp = {
            transform_items = function(_, items)
              for _, item in ipairs(items) do
                if item.kind == require("blink.cmp.types").CompletionItemKind.Snippet then
                  item.score_offset = item.score_offset - 3
                end
              end
              return items
            end,
          },
        },
      },
    },
  }
...

到目前为止,基本上可以正常使用了,但是要着重注意 链接2readme 中的思路章节,对该插件是如何切换输入法的很有作用

配置代码解释

首先是 cmp-lsp-rimsls 是用户封装的 rime_ls 配置插件,对我这种新手来讲比较友好,所以选用该插件

但是该插件的 数字键上屏功能 在我的 nobara linuxmac 上都无法正常使用,所以直接偷书 链接3 , 曲线实现了 数字键上屏功能

其次是现有配置适用于哪种文件

根据 cmp-lsp-rimsls 的源文件,我们可以看到这个拓展是如何实现的

-- ~/.local/share/nvim/lazy/cmp-lsp-rimels/lua/rimels/english_environment_detectors.lua
...
function M.with_treesitter.norg(info)
  info = info or vim.inspect_pos()
  local trees = info.treesitter
  local extmarks = info.extmarks
  local englist_env = false
  for _, ts in ipairs(trees) do
    if
      ts.capture == "neorg.markup.variable" or
      ts.capture == "neorg.markup.verbatim" or
      ts.capture == "neorg.markup.inline_math"
    then
      return true
    elseif ts.capture == "comment" then
      return false
    end
  end
  for _,ext in ipairs(extmarks) do
    if
      ext.opts and
      ext.opts.hl_group == "@neorg.tags.ranged_verbatim.code_block"
    then
      return true
    end
  end
  return englist_env
end

function M.with_treesitter.markdown(info)
  info = info or vim.inspect_pos()
  local trees = info.treesitter
  local englist_env = false
  for _, ts in ipairs(trees) do
    if
      ts.capture == "markup.math" or
      ts.capture == "markup.raw"
    then
      return true
    elseif ts.capture == "markup.raw.block" then
      englist_env = true
    elseif ts.capture == "comment" then
      return false
    end
  end
  return englist_env
end
...

首先是定义了两个函数 with_treesitter.markdown 以及 with_treesitter.norg

基本上可以得出 cmp-lsp-rimslsmarkdownnorg 两种文件类型中会启用 这一结论

其次是为了契合 blink-cmp 的设置,cmp-lsp-rimels 中做出了如下配置

-- ~/.local/share/nvim/lazy/cmp-lsp-rimels/lua/rimels/utils.lua
...
  lspconfig.rime_ls.setup {
    init_options = {
      enabled = M.global_rime_enabled(),
      shared_data_dir = opts.shared_data_dir,
      user_data_dir = opts.user_data_dir or opts.rime_user_dir,
      log_dir = opts.rime_user_dir .. "/log",
      max_candidates = opts.max_candidates,
      long_filter_text = M.blink() and true or opts.long_filter_text, -- 于此中开启 long_filter_text
      trigger_characters = opts.trigger_characters,
      schema_trigger_character = opts.schema_trigger_character,
      always_incomplete = opts.always_incomplete,
      paging_characters = opts.paging_characters,
    },
    on_attach = rime_on_attach,
    capabilities = M.generate_capabilities(),
  }
...

接下来,我们来分析 cmp-lsp-rimsls 的工程结构

❯ pwd
/Users/soapsu/.local/share/nvim/lazy/cmp-lsp-rimels
❯ tree -C -L 3
.
├── LICENSE
├── README.md
├── lua
│   └── rimels
│       ├── cmp_keymaps.lua
│       ├── config.lua
│       ├── default_opts.lua
│       ├── english_environment_detectors.lua
│       ├── init.lua
│       ├── probes.lua
│       └── utils.lua
└── stylua.toml

3 directories, 10 files

各文件之间的依赖关系如下图所示

classDiagram class init class cmp_keymaps class config class default_opts class english_environment_detectors class probes class utils init ..> utils init ..> cmp_keymaps init ..> config utils ..> default_opts config ..> english_environment_detectors config ..> probes

下面详细对各文件的所有进行解释

init.lua

其类图为

classDiagram class init { +setup(opts) -has_setup -opts -keymaps } class config { +update_option(opts) } class utils { +launch_lsp_server(opts) +start_rime_ls() } class cmp_keymaps class vim { +keymap +lsp } init ..> config : Uses in setup() init ..> utils : Uses in setup() init ..> cmp_keymaps : Uses in setup() init ..> vim : Uses keymap and lsp note for init "In setup(): 1. 使用了 config.update_option() 2. 使用了 utils.launch_lsp_server() 3. 使用了 vim.keymap.set() 4. 通过 cmp_keymaps 模块 初始化 vim.cmp_keymaps 5. 当 nvim 进入 insert 模式的时候使用 utils.start_rime_ls" note for config "提供模块默认配置" note for utils "提供 rime 以及 lsp server 的功能函数"

如图所示,utils 的核心函数为 launch_lsp_server start_rime_ls

该工程加载了 vimlspkeymap 模块,并在 config 模块中加载默认配置

总结

综上所述,cmp-lsp-rimsls 解决了 rimelsblink-cmp 下的使用问题

posted @ 2025-02-05 21:29  五花肉炒河粉  阅读(521)  评论(0)    收藏  举报