nvim im select remote 在远程机器上丝滑切换输入法

im-select.nvim 解决了在本地机器的终端上面丝滑切换中英文输入法。但是我回到家里,需要连接到公司的远程服务器,然后再登录 我的 tmux 回话,即可快速返回下班前的工作状态了。这时候如果需要在 tmux 使用 vim 进行中文输入,就 无法再使用 im-select 的切换功能了,因为其使用使用的是本地的输入法切换,在远程环境中,无法调用。

这时候我发现一个可以让 nvim 远程调用本地的输入法切换命令:

  • 一旦进入 insert 模式,就从远程发送一个命令给本地,要求切换到中文输入法
  • 一旦退出 insert 模式(即按下 Esc),再从远程发送一个命令给本地,要求切换到英文,这样就可以在 normal 模式下使用各种按键了。

自动切换中英文输入法

我安装的项目是 im-select-remote。一开始按照上面的配置安装,并没有成功。后来仔细研究了一下代码,发现这里面只是调用切换会英文输入法的命令,但是没有继续切换到中文输入法。里面的代码相对简单

在代码 ~/.config/nvim/lazy/im-select-remote.nvim/lua/im-select-remote.lua

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
M.IMSelectSocketEnable = function()
  vim.notify("IMSelectRemote: Socket enabled", vim.log.levels.INFO)
  vim.cmd([[
      augroup im_select_remote
        autocmd!
        autocmd BufEnter * lua require("im-select-remote").IMSelectBySocket()
        autocmd InsertLeave * lua require("im-select-remote").IMSelectBySocket()
      augroup END
    ]])
end

这里调用了 config.command 的操作,但是这个命令是一条固定的语句,

1
command = "fcitx-remote -c"

如果我们想要扩展,需要进行判断。于是可以修改城

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-- 添加两个命令
-- command_enter: fcitx-remote -o
-- command_leave: fcitx-remote -c
local M = {}
M.config = {
  osc = {
    secret = "",
  },
  socket = {
    port = 23333,
    max_retry_count = 3,
    command_enter = "fcitx-remote -o",
    command_leave = "fcitx-remote -c",
  },
}

--- IMSelectBySocket
-- @treturn int the exit code of the command
M.IMSelectBySocket = function(command)
  local function on_stdout() end
  local cmd = "echo "
    .. vim.fn.shellescape(command)
    .. " | nc localhost "
    .. M.config.socket.port
    .. " -q 0"
  vim.fn.jobstart(cmd, {
    on_stdout = on_stdout,
    on_stderr = on_stdout,
    on_exit = on_stdout,
    stdout_buffered = false,
    stderr_buffered = false,
  })
end
-- 进入 insert 模式
M.IMSelectBySocketEnter = function()
    -- M.IMSelectBySocket("fcitx-remote -o")
    M.IMSelectBySocket(M.config.socket.command_enter)
end
-- 退出 insert,进入 normal 模式
M.IMSelectBySocketLeave = function()
    -- M.IMSelectBySocket("fcitx-remote -c")
    M.IMSelectBySocket(M.config.socket.command_leave)
end

M.IMSelectSocketEnable = function()
  vim.notify("IMSelectRemote: Socket enabled", vim.log.levels.INFO)
  vim.cmd([[
      augroup im_select_remote
        autocmd!
        " autocmd BufEnter * lua require("im-select-remote").IMSelectBySocket()
        " autocmd InsertLeave * lua require("im-select-remote").IMSelectBySocket()
        autocmd InsertEnter * lua require("im-select-remote").IMSelectBySocketEnter()
        autocmd InsertLeave * lua require("im-select-remote").IMSelectBySocketLeave()
      augroup END
    ]])
end

完整的配置

安装插件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
return {
    "mkdir700/im-select-remote.nvim",
    lazy = true,
    event = 'BufRead',
    ft = {"markdown"},
    config = function()
        require('im-select-remote').setup({
            osc = {
                secret = "",
            },
            socket = {
                port = 23333,
                max_retry_count = 3,
                -- command_enter = "fcitx-remote -o",
                -- command_leave = "fcitx-remote -c",
            },
        })
    end
}

修改代码

按照如上进行修改 ~/.config/nvim/lazy/im-select-remote.nvim/lua/im-select-remote.lua

服务端配置

在服务端 ~/.ssh/config 添加

1
2
3
4
Host local
    HostName localhost
    Port 23333
    User william

本地配置

在本地 ~/.ssh/config 添加,其中 192.168.1.82 是服务端 ip 地址。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Host *
    ServerAliveInterval 60
    IdentitiesOnly=yes
    StrictHostKeyChecking=no
    ForwardAgent yes

Host william
    HostName 192.168.1.82
    User william
    Port 22
    # 用于端口转发
    RemoteForward 127.0.0.1:23333 127.0.0.1:23333
    ServerAliveInterval 240

启动服务接收命令

在本地执行

1
2
3
cd ~/.config/nvim/lazy/im-select-remote.nvim/server

bash ./im-server.sh

如此一来,我们就可以把服务端的命令从 23333 转发到本地,然后执行切换输入法的命令了。

happing hacking,完美解决中英文切换问题。

william 支付宝支付宝
william 微信微信
0%