Neovim键盘布局联动光标颜色优化:事件选择与多进程通知问询
针对Neovim键盘布局光标颜色脚本的优化方案
问题1:替换CursorMoved为更合适的触发方式
当前脚本每次光标移动都执行检测,效率低下,可通过以下几种方式优化:
1. 基于临时文件的文件监听
创建后台脚本监听键盘布局变化,仅在布局实际改变时更新临时文件;Neovim监听该文件变化,触发颜色调整逻辑。
步骤1:编写布局监听脚本(kb_layout_watcher.sh)
#!/bin/bash prev_layout="" layout_file="/tmp/nvim_kb_layout" # 初始化写入当前布局 xkblayout-state print %n > "$layout_file" prev_layout=$(cat "$layout_file") while true; do current_layout=$(xkblayout-state print %n) if [ "$current_layout" != "$prev_layout" ]; then echo "$current_layout" > "$layout_file" prev_layout="$current_layout" fi sleep 0.5 done
执行chmod +x kb_layout_watcher.sh赋予可执行权限,再将脚本添加到系统开机自启(如GNOME环境下添加到启动应用列表)。
步骤2:修改Neovim配置
local function set_cursor_color() local layout = vim.system({"xkblayout-state", "print", "%n"}, { text = true }):wait() if layout.stdout == "English" then vim.cmd([[highlight CursorLine cterm=NONE ctermbg=DarkGray guibg=#373944]]) else vim.cmd([[highlight CursorLine cterm=NONE ctermbg=DarkGray guibg=#44373f]]) end end -- 初始化时设置一次颜色 set_cursor_color() -- 监听临时文件变化 local layout_file = "/tmp/nvim_kb_layout" local watcher = vim.loop.new_fs_event() watcher:start(layout_file, {}, function() -- 确保在Neovim主线程执行更新逻辑 vim.schedule(set_cursor_color) end) -- 退出Neovim时清理监听器 vim.api.nvim_create_autocmd("VimLeave", { callback = function() watcher:stop() end })
2. 定时低频率检查
如果不想依赖外部脚本,可使用Neovim定时器,每隔固定时间(如500ms)检查一次布局,远低于光标移动的触发频率:
local function set_cursor_color() local layout = vim.system({"xkblayout-state", "print", "%n"}, { text = true }):wait() if layout.stdout == "English" then vim.cmd([[highlight CursorLine cterm=NONE ctermbg=DarkGray guibg=#373944]]) else vim.cmd([[highlight CursorLine cterm=NONE ctermbg=DarkGray guibg=#44373f]]) end end -- 初始化设置 set_cursor_color() -- 每500ms检查一次布局 local timer = vim.loop.new_timer() timer:start(0, 500, vim.schedule_wrap(set_cursor_color)) -- 退出时停止定时器 vim.api.nvim_create_autocmd("VimLeave", { callback = function() timer:stop() end })
问题2:通知所有运行中的Neovim进程更新布局
利用Neovim的远程调用功能,通过外部脚本遍历所有Neovim进程的socket,发送更新命令:
步骤1:全局暴露更新函数
修改Neovim配置,将set_cursor_color挂载到全局表,确保远程调用能找到该函数:
_G.set_cursor_color = function() local layout = vim.system({"xkblayout-state", "print", "%n"}, { text = true }):wait() if layout.stdout == "English" then vim.cmd([[highlight CursorLine cterm=NONE ctermbg=DarkGray guibg=#373944]]) else vim.cmd([[highlight CursorLine cterm=NONE ctermbg=DarkGray guibg=#44373f]]) end end -- 初始化设置 _G.set_cursor_color()
步骤2:编写全局通知脚本(kb_layout_notify_all.sh)
#!/bin/bash prev_layout="" while true; do current_layout=$(xkblayout-state print %n) if [ "$current_layout" != "$prev_layout" ]; then # 遍历所有Neovim的socket文件 for sock in /tmp/nvim.*; do if [ -S "$sock" ]; then # 发送远程命令调用全局更新函数 nvim --server "$sock" --remote-send "<Cmd>lua set_cursor_color()<CR>" fi done prev_layout="$current_layout" fi sleep 0.5 done
同样赋予脚本可执行权限并添加到开机自启,布局变化时所有运行的Neovim进程都会自动更新光标行颜色。
内容的提问来源于stack exchange,提问作者Vlad Sheryshev
相关产品推荐
相关产品推荐

