lazyvim 折腾日记(2)
lazyvim 折腾日记(2)
前言
我的目标是争取在不使用 gui 的前提下完成开发,运维等工作
前一篇讲述的是 lazyvim 安装及基本概念,这一篇要讲的是如何在 lazyvim 中使用中文输入法
有这个想法是因为在 nvim 使用中文输入法非常的不便捷,但是又不可避免的有着写文档的需求,在这种情况下需要借助一些工具完善在 nvim 中的中文输入体验.
具体思路
完成中文输入的改进,基本需要以下几个步骤
- 完成 rime 与 本地 cmp 的结合
- 将本地搜索插件加入搜索中文的功能
- 增强 e b 等快捷键的功能,使得这些快捷键能够按词移动
以上的三个步骤分别依赖于 rime-ls hop hop-zh-by-flypy jieba.nvim 总共4个插件的安装与配置,下文将按照上述步骤进行安装调试
rime 语言服务器的安装
rime-ls 通过将 cmp 与 rime-ls 结合实现通过 cmp 候选框选择中文,其中的核心在于 rime-ls 的安装 以及 cmp 的配置
rime-ls 依赖 librime 这个 rime 的核心引擎,也就是说安装这个插件的前提是首先在本机上已经安装好 rime 在本机上使用的是 fcitx5-rime
直接编译 rime-ls 比较麻烦,需要提前安装好 clang 如果使用的是 arch 系列系统,可以直接从 aur 中进行安装,本机额外安装了 rust 以及 clang 对项目进行编译,这个过程不是本篇文章主题,按下不表
安装编译后的目录如下文所示
$> pwd
/home/soapsu/.local/bin/rime-ls
$> tree -L 1
├── Cargo.lock
├── Cargo.toml
├── CHANGELOG.md
├── doc
├── docker-compose.yaml
├── Dockerfile
├── LICENSE
├── README.md
├── src
└── target
4 directories, 7 files
$> tree -L 2 ./target # 其中 rime_ls 就是我们所编译好的文件
./target
├── CACHEDIR.TAG
└── release
├── build
├── deps
├── examples
├── incremental
├── librime_ls.d
├── librime_ls.rlib
├── rime_ls
└── rime_ls.d
6 directories, 5 files
将编译好的文件路径加入环境变量中
$> echo "export RIME_HOME="$HOME/.local/bin/rime-ls/" > ~/.zshrc
$> source ~/.zshrc
配置 lazyvim 文件
$> cd /home/soapsu/.config/nvim/lua/plugins
$> tree -L 1 ./
.
├── ai
├── catppuccin.lua
├── cmp.lua
├── dadbod
├── java
├── lualine.lua
├── nvim-treesitter.lua
├── rime.lua # 新增该文件
└── zh-input.lua
4 directories, 6 files
在新增文件中写入如下内容
local M = {}
function M.setup_rime()
-- global status
vim.g.rime_enabled = false
-- update lualine
local function rime_status()
if vim.g.rime_enabled then
return "ㄓ"
else
return ""
end
end
require("lualine").setup({
sections = {
lualine_x = { rime_status, "encoding", "fileformat", "filetype" },
},
})
-- add rime-ls to lspconfig as a custom server
-- see `:h lspconfig-new`
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
if not configs.rime_ls then
configs.rime_ls = {
default_config = {
name = "rime_ls",
cmd = { "rime_ls" },
-- cmd = vim.lsp.rpc.connect("127.0.0.1", 9257),
filetypes = { "*" },
single_file_support = true,
},
settings = {},
docs = {
description = [[
https://www.github.com/wlh320/rime-ls
A language server for librime
]],
},
}
end
local rime_on_attach = function(client, _)
local toggle_rime = function()
client.request("workspace/executeCommand", { command = "rime-ls.toggle-rime" }, function(_, result, ctx, _)
if ctx.client_id == client.id then
vim.g.rime_enabled = result
end
end)
end
-- keymaps for executing command
vim.keymap.set("i", "<C-x>", function()
toggle_rime()
end)
vim.keymap.set("n", "<leader>rs", function()
vim.lsp.buf.execute_command({ command = "rime-ls.sync-user-data" })
end)
end
-- nvim-cmp supports additional completion capabilities, so broadcast that to servers
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities)
lspconfig.rime_ls.setup({
init_options = {
enabled = vim.g.rime_enabled,
shared_data_dir = "/usr/share/rime-data",
user_data_dir = "~/.local/share/rime-ls",
log_dir = "~/.local/share/rime-ls",
max_candidates = 9,
trigger_characters = {},
schema_trigger_character = "&", -- [since v0.2.0] 当输入此字符串时请求补全会触发 “方案选单”
},
on_attach = rime_on_attach,
capabilities = capabilities,
})
end
local cmp = require("cmp")
local compare = require("cmp.config.compare")
cmp.setup({
sorting = {
priority_weight = 2,
comparators = {
compare.sort_text,
compare.offset,
compare.exact,
compare.score,
compare.recently_used,
compare.kind,
compare.length,
compare.order,
},
},
})
local rime_ls_filetypes = { "markdown", "vimwiki" }
local function is_rime_entry(entry)
return vim.tbl_get(entry, "source", "name") == "nvim_lsp"
and vim.tbl_get(entry, "source", "source", "client", "name") == "rime_ls"
end
local function auto_upload_rime()
if not cmp.visible() then
return
end
local entries = cmp.core.view:get_entries()
if entries == nil or #entries == 0 then
return
end
local first_entry = cmp.get_selected_entry()
if first_entry == nil then
first_entry = cmp.core.view:get_first_entry()
end
if first_entry ~= nil and is_rime_entry(first_entry) then
local rime_ls_entries_cnt = 0
for _, entry in ipairs(entries) do
if is_rime_entry(entry) then
rime_ls_entries_cnt = rime_ls_entries_cnt + 1
if rime_ls_entries_cnt == 2 then
break
end
end
end
if rime_ls_entries_cnt == 1 then
cmp.confirm({
behavior = cmp.ConfirmBehavior.Insert,
select = true,
})
end
end
end
vim.api.nvim_create_autocmd("FileType", {
pattern = rime_ls_filetypes,
callback = function()
for numkey = 1, 9 do
local numkey_str = tostring(numkey)
vim.api.nvim_buf_set_keymap(0, "i", numkey_str, "", {
noremap = true,
silent = false,
callback = function()
vim.fn.feedkeys(numkey_str, "n")
vim.schedule(auto_upload_rime)
end,
})
vim.api.nvim_buf_set_keymap(0, "s", numkey_str, "", {
noremap = true,
silent = false,
callback = function()
vim.fn.feedkeys(numkey_str, "n")
vim.schedule(auto_upload_rime)
end,
})
end
end,
})
return M
再在 init.lua 中加入以下内容
$> pwd
/home/soapsu/.config/nvim
$> tree -L
.
├── init.lua # 在这里加入以下内容
├── lazy-lock.json
├── lazyvim.json
├── LICENSE
├── lua
├── README.md
└── stylua.toml
2 directories, 6 files
$> echo "require("plugins.rime").setup_rime()"
重新启动 nvim rime 即可使用
对于上面的文件有必要做出如下解释
- 以上配置文件全都来源于 rime-ls 的配置文件以及 issue 里的用户配置片段
- 在上述的配置文件中, 总共设置了如下功能
- 在 lsp 中加入了 rime-ls 语言服务器的使用, 使得 cmp 候选框能够显示来自前者的候选项目
- 在 lualine 中设置了与 rime-ls 状态相关的图标, 使得用户能够从 lualine 状态栏中看到 rime-ls 的启动状态
- 设置了 rime-ls 的词库位置以及用户数据位置
- 设置了 cmp 候选框的排列顺序, 使得用户输入的中文能够在 cmp 候选框的前列并按数字顺序排序
- 设置了根据数字按键直接上屏, 具体原理为将 auto_upload_rime 与 nvim_create_autocmd 两个函数相结合实现前文所述功能
- 设置了启动 rime-ls 的按键, 为在 insert 模式下按下
键即可启动 rime-ls 服务器
搜索跳转插件的安装
在实际编辑中文文档的时候会高频词使用到搜索跳转功能, 但是现有的 nvim 自身的跳转功能只支持英文, 所以有必要安装中文跳转的插件
在本机使用 hop + hop-zh-by-flypy 实现搜索与跳转功能
hop 插件, hop 插件是 easyMotion 插件的重写, 旨在用于强化在 nvim 下的跳转搜索, 而 hop-zh-by-flypy 则是 hop 插件的一个中文拓展
首先在 plugins 文件夹下的 zh-input.lua 文件下加入以下内容
$> pwd
/home/soapsu/.config/nvim/lua/plugins
$> tree -L 1 ./
./
├── ai
├── catppuccin.lua
├── cmp.lua
├── dadbod
├── java
├── lualine.lua
├── nvim-treesitter.lua
├── rime.lua
└── zh-input.lua # 在该文件下新增内容
4 directories, 6 files
return {
{
"phaazon/hop.nvim",
branch = "v1",
config = function()
local hop = require("hop")
hop.setup({
keys = "etovxqpdygfblzhckisuran",
extensions = {
"hop-zh-by-flypy",
},
})
local directions = require("hop.hint").HintDirection
vim.keymap.set("", "f", function()
hop.hint_char1({ direction = directions.AFTER_CURSOR, current_line_only = true })
end, { remap = true })
vim.keymap.set("", "F", function()
hop.hint_char1({ direction = directions.BEFORE_CURSOR, current_line_only = true })
end, { remap = true })
vim.keymap.set("", "t", function()
hop.hint_char1({ direction = directions.AFTER_CURSOR, current_line_only = true, hint_offset = -1 })
end, { remap = true })
vim.keymap.set("", "T", function()
hop.hint_char1({ direction = directions.BEFORE_CURSOR, current_line_only = true, hint_offset = 1 })
end, { remap = true })
end,
},
{
"zzhirong/hop-zh-by-flypy",
dependencies = {
"phaazon/hop.nvim",
},
config = function()
local hop_flypy = require("hop-zh-by-flypy")
hop_flypy.setup({
set_default_mappings = false,
vim.keymap.set("n", "gf", "<cmd>HopFlypy1<CR>"),
vim.keymap.set("n", "gs", "<cmd>HopFlypy2<CR>"),
})
end,
},
按照上述配置, 重启 lazyvim 即可安装好以上两个模块
对于以上内容有必要做出如下解释
- hop-zh-by-flypy 依赖 hop 插件, 不可单独安装该插件
- 直接使用 hop-zh-by-flypy 插件的官方配置会与 lazyvim 自带的 flash 插件按键产生冲突, 所以不能使用默认配置, 需自行配置相关按键,
# f 与 s 按键绑定 flash 插件, 在本机中设置 gf 以及 gs 键绑定 HopFlypy1 以及 HopFlypy2 命令
1 15时17分26秒 msg_show map f o f * <Lua 554: ~/.local/share/nvim/lazy/flash.nvim/lua/flash/plugins/char.lua:118>
1 x f * <Lua 553: ~/.local/share/nvim/lazy/flash.nvim/lua/flash/plugins/char.lua:118>
2 n f * <Lua 548: ~/.local/share/nvim/lazy/flash.nvim/lua/flash/plugins/char.lua:118>
3 s f <Lua 321: ~/.config/nvim/lua/plugins/zh-input.lua:14>
4 15时18分01秒 msg_show 5 more lines
5 15时15分50秒 msg_showcmd :
6 15时18分38秒 msg_show map s n s * <Lua 227: ~/.local/share/nvim/lazy/LazyVim/lua/lazyvim/plugins/editor.lua:164>
7 Flash
8 x s * <Lua 226: ~/.local/share/nvim/lazy/LazyVim/lua/lazyvim/plugins/editor.lua:164>
- hop-zh-flypy 使用的是小鹤双拼编码, 具体使用方法为在 n 模式下敲入 gf 输入第一个音节, 按照排序选取中文, 同理敲入 gs 输入双拼完整编码按顺序选取中文
- 直接敲入 f 再敲入所需选取的英文, 再按 f 键向下选取
总结: 通过上述配置能够实现中英文的跳转
e w b ge 移动强化
在实际行内移动中, 通常使用 w e 按键实现单词与单词之间的跳转, 很明显 nvim 自身提供的 w e 键移动只针对英文, 所以有必要强化在中文下的单词间移动
在本机中使用 jieba.nvim 对以上两按键进行强化, 该模块使用 jieba 分词实现对中文词语的识别
在上文所提到的配置文件中加入以下内容
{
"noearc/jieba.nvim",
dependencies = { "noearc/jieba-lua" },
},
即可安装完毕, 优点在于不需要编译, 能够开箱即用
总结
本文通过配置上述插件以达到强化中文输入体验的目的

浙公网安备 33010602011771号