---
title: Neovim：中文输入、远程剪贴板与窗口协作
url: https://doc.liz6.com/tools/nvim/06-remote-input
locale: zh
area: tools
tags:
- Neovim
- 开发工具
date: 2026-09-15
modified: 2026-09-15
description: 分别处理输入法切换、OSC52 复制和 Zellij 方向导航，说明两侧配置、协议条件与排错路径。
---

# Neovim：中文输入、远程剪贴板与窗口协作

中文编辑与远程工作涉及多个进程：桌面输入法、终端、复用器和 Neovim。某个动作在本地有效，经过 SSH 或 Zellij 后失效，通常需要沿着这条路径逐层检查。

## 普通模式与输入法

普通模式中的 `j` 是移动命令。若输入法仍在组合中文，按键可能先进入候选框，Neovim 收不到原本的字符。因此，模式切换时恢复拉丁输入法可以减少误操作。

在使用 Fcitx5 的 Linux 桌面上，先单独查询当前输入法：

```bash
fcitx5-remote -n
```

确认 `keyboard-us` 已加入可用输入法后，手动测试：

```bash
fcitx5-remote -s keyboard-us
```

命令行切换正常后，再在 `lua/plugins/input.lua` 配置插件：

```lua
return {
  {
    "keaising/im-select.nvim",
    event = "VeryLazy",
    opts = {
      default_im_select = "keyboard-us",
      default_command = "fcitx5-remote",
      set_previous_events = { "InsertEnter" },
    },
  },
}
```

退出插入模式时检查是否恢复键盘输入，再进入插入模式检查是否恢复之前的输入法。macOS、Windows 和 IBus 的命令不同，不能复制这份 Fcitx5 配置后期待跨平台自动成立。[im-select.nvim](https://github.com/keaising/im-select.nvim)

SSH 远端运行的 Neovim 通常无法直接控制本地桌面的 Fcitx5。远端安装同名命令不会让它跨越 SSH 自动操作本地会话；此时可使用本地终端/输入法的切换策略。

## 剪贴板与寄存器

Neovim 的内部寄存器不依赖桌面。`"+y` 则请求通过 clipboard provider 把内容交给系统剪贴板。Wayland 本地常用 `wl-copy` / `wl-paste`，SSH 场景可以让 OSC52 序列沿终端连接返回本地终端。

先查看 `:checkhealth vim.provider`，再分别测试普通 `y` 和 `"+y`。只有设置了 `clipboard=unnamedplus` 等选项，普通复制才会自动连接到相应剪贴板寄存器。

OSC52 的复制与读取是两种能力。终端允许写剪贴板，不代表允许读取；多路复用器也可能影响转发和自动检测。[Neovim clipboard](https://neovim.io/doc/user/provider/#clipboard-osc52)

## 只发送 OSC52，粘贴保留本次复制缓存

下面放入 `lua/config/options.lua`，适用于提供 `vim.ui.clipboard.osc52` 的 Neovim 版本。它把复制发送到终端，读取时只返回本 Neovim 进程最近复制的内容：

```lua
local osc52 = require("vim.ui.clipboard.osc52")
local clipboard_cache = { { "" }, "v" }

local function copy_to(register)
  local send = osc52.copy(register)
  return function(lines, regtype)
    clipboard_cache = { vim.deepcopy(lines), regtype }
    send(lines, regtype)
  end
end

local function paste_cached()
  return vim.deepcopy(clipboard_cache)
end

vim.g.clipboard = {
  name = "OSC52 with local cache",
  copy = { ["+"] = copy_to("+"), ["*"] = copy_to("*") },
  paste = { ["+"] = paste_cached, ["*"] = paste_cached },
}
vim.opt.clipboard = "unnamedplus"
```

这是有意选择的行为：从浏览器复制的新内容不会自动出现在这个缓存中。外部内容可通过本地终端的粘贴动作送进插入模式；如果需要 `"+p` 真正读取系统剪贴板，应使用支持读取的 provider 并验证终端权限。

验证顺序是：本地无复用器 → 本地 Zellij → SSH 无复用器 → SSH 内 Zellij。每次复制一段不同的标记文字，检查本地桌面得到哪一段；这样可以定位在哪一层丢失。

## Neovim 一侧的方向导航

在 `lua/plugins/navigation.lua` 中加入：

```lua
return {
  {
    "mrjones2014/smart-splits.nvim",
    opts = { at_edge = "stop", zellij_move_focus_or_tab = false },
    keys = {
      { "<C-h>", function() require("smart-splits").move_cursor_left() end, desc = "Move left" },
      { "<C-j>", function() require("smart-splits").move_cursor_down() end, desc = "Move down" },
      { "<C-k>", function() require("smart-splits").move_cursor_up() end, desc = "Move up" },
      { "<C-l>", function() require("smart-splits").move_cursor_right() end, desc = "Move right" },
    },
  },
}
```

这里选择到整个可移动区域边缘时停止，且不跨 Zellij 标签。先在两个 Neovim 窗口之间测试，再验证越过编辑器边界的动作。[smart-splits](https://github.com/mrjones2014/smart-splits.nvim)

## Zellij 一侧的配合

从 [vim-zellij-navigator 发布页](https://github.com/hiasr/vim-zellij-navigator/releases)取得兼容版本的 WASM 插件，保存在自己的插件目录。下面四条绑定加入现有 `keybinds` 下的 `locked` 模式；将四处 `/absolute/path/` 改成实际绝对路径：

```kdl
locked {
    bind "Ctrl h" {
        MessagePlugin "file:/absolute/path/vim-zellij-navigator.wasm" {
            name "move_focus"; payload "left"; move_mod "ctrl";
        }
    }
    bind "Ctrl j" {
        MessagePlugin "file:/absolute/path/vim-zellij-navigator.wasm" {
            name "move_focus"; payload "down"; move_mod "ctrl";
        }
    }
    bind "Ctrl k" {
        MessagePlugin "file:/absolute/path/vim-zellij-navigator.wasm" {
            name "move_focus"; payload "up"; move_mod "ctrl";
        }
    }
    bind "Ctrl l" {
        MessagePlugin "file:/absolute/path/vim-zellij-navigator.wasm" {
            name "move_focus"; payload "right"; move_mod "ctrl";
        }
    }
}
```

这是 `keybinds` 内部的片段，应与已有 `Ctrl+g` 模式切换合并，不应覆盖整个文件。插件首次请求权限时，核对插件来源与用途。若使用其他常驻模式，将绑定放到实际使用的模式，避免 locked 模式下的键位根本没有生效。

在左侧面板打开有两个窗口的 Neovim，右侧放普通 Shell。依次验证编辑器内向右、越过边界向右、从 Shell 向左返回，以及最外侧无目标时停止。若失败，先看 `:verbose nmap <C-l>`，再查 Zellij 模式、插件加载和终端映射。

旧环境的内部函数覆盖属于版本相关补丁。新配置先使用公开选项，只有能复现具体缺陷时才考虑临时适配，并记录移除条件。
