Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

完善 Rime Vim Mode:支持 Linux & 自动切换回中文模式 #85

Open
lei4519 opened this issue May 13, 2024 · 7 comments
Open

完善 Rime Vim Mode:支持 Linux & 自动切换回中文模式 #85

lei4519 opened this issue May 13, 2024 · 7 comments

Comments

@lei4519
Copy link
Owner

lei4519 commented May 13, 2024

2024-05-13

TL;DR

借助 lua_processor,自行实现 vim_mode 的中英文切换逻辑,使其支持:

  • Linux 系统
  • 重新进入 insert mode 时自动切换回中文模式(如果离开时是处于中文模式的话)

这并不是一个完美的解决方案,可能达不到 100% 的使用效果,但是在普通的情况下已经足以使用

使用方法

可以参考此 feat: vim_modeI

引入 vim_mode.lua 文件

首先将 vim_mode.lua 文件放入自己的 lua 文件夹中,并在 rime.lua 中进行导出

vim_mode = require("vim_mode")  

加入 lua_processor

在自己的中文输入方案中,加入 lua_processor

比如我使用的是小鹤双拼,所以我修改 double_pinyin_flypy.custom.yaml,加入如下逻辑

patch:  
  # 加入 lua_processor  
  engine/processors/@before 0: lua_processor@vim_mode  
  # 默认关闭 vmode,只在对应的 app 中打开  
  switches/+:  
    - name: vmode  
      reset: 0  

配置 app_options

在对应平台的 .custom.yaml 中配置在什么应用下启用 vmode

比如 macOS 的 squirrel.custom.yaml

patch:  
  app_options:  
    org.alacritty:  
      ascii_mode: true  
      vmode: true  
    net.kovidgoyal.kitty:  
      ascii_mode: true  
      vmode: true  

实现思路与原因

起因

我觉得 vim_mode 的确是一个非常好的功能,尤其是我这种既要用 Obsidian,又要用 Terminal,偶尔还要用 VSCode 的人

虽然这些软件中都有类似 im-select 之类的切换插件,但是每个软件中都需要单独安装,且不同的操作系统,配置还可能不一样(比如我自己就在 macOS 和 Linux 下频繁切换)

所以如果能有一个 IM 级别的 vim_mode 切换解决方案,那真是再好不过了

可是目前的 vim_mode 有两个问题:

  1. 由前端实现,Linux 中不支持此功能
  2. 在中文模式下,切换到 normal mode,再进入 insert mode,会保持 ascii mode,而不会自动切换会中文模式
    • im-select 就会自动切换回中文模式

思路

搜索之后发现并没有一个现成的解决方案,但是却有大佬写过类似的逻辑,比如

稍微组合一下,就有了本文的解决方案


通过 switches 配置 vmode,再通过 app_options 配置在相应应用下打开 vmode ,即可实现原生的 vim_mode 在指定应用下开启的效果

利用 lua_processor 对按键输入进行处理,如果当前应用处于 vmode 下,就进行相关的逻辑处理

有考虑加入win端和macos端的vim mode · Issue #84 · fcitx/fcitx5-rime · GitHub 中所说,rime 是无法感知应用处于什么模式的(vim)
同样我们也无法知道应用处于什么模式,只能是根据 vim 的常规操作逻辑去大致的处理一下

思路如下:

在开启了 vmode 的应用中

  • 如果按下了 esc 键,就认为要切换到 normal mode
    • 如果此时处于中文模式,就自动切换到英文模式,并记录中文状态
  • 如果处于 normal mode,并且按下了 i/a/o/c 等会进入插入模式的按键
    • 如果之前是中文状态,就自动切换回中文状态

Ref

@lei4519
Copy link
Owner Author

lei4519 commented Jul 8, 2024

@lei4519 问题已解决,ubuntu的包名就是apt或命令行用的包名,我把上面的配置放到对应输入方案下的配置文件中就可以生效了,ubuntu下squirrel.custom.yaml好像不能用?

linux 的配置文件要写在 fcitx5.custom.yaml 中(如果用的是 fcitx5)

不过 linux 中我遇到一个问题还没解决,就是 vim_mode.lua 这个 lua_processor 是配置在中文拼音里的,所以 esc 从中文切换到 ascii 是正常的,但在 ascii mode 中按 i/a/c/o 并不会重新进入中文模式

看起来是因为 Fcitx5 rime 的 ascii mode 根本不会执行配置在中文拼音中的 lua_processor 导致的,但是 macos 里就没有这个问题

如果可以给 ascii mode 也配置 lua_processor 就可以解决这个问题,不过一直也没时间去看

@IC-killer
Copy link

@lei4519 ubuntu ibus 下,app_options不生效,好像没有支持?rime/ibus-rime#96
你的可以识别应用吗,我的好像不行

@IC-killer
Copy link

默认英文,先删除vmode变量全局使用了。。

@lei4519
Copy link
Owner Author

lei4519 commented Jul 8, 2024

@IC-killer 没有试过 ibus,Fcitx5 里是可以的

@IC-killer
Copy link

全局使用esc回到英文,只保留以下脚本就可以,这似乎对我来说已经足够了,app_options是锦上添花

local function vim_mode(key, env)
	if key.keycode == 65307 then
		env.engine.context:set_option("ascii_mode", true)
	end
	return 2
end
return vim_mode

如果我想实现按下jk回到ascii_mode应该怎么做,,
发现这个脚本似乎只有在esc alt shift这些按键按下时才会触发,按下普通的字母键,比如i a,会优先弹出候选框,而这个脚本我只能通过+加载,不清楚是否是加载顺序必须要在最前面的@before 0,但是before 0又会出错。。。

@IC-killer
Copy link

可以通过@before 0正常加载了,是写法错误,,
engine/processors/https://github.com/before 0: lua_processor@*vim_mode

@lei4519
Copy link
Owner Author

lei4519 commented Jul 12, 2024

全局使用esc回到英文,只保留以下脚本就可以,这似乎对我来说已经足够了,app_options是锦上添花

local function vim_mode(key, env)
	if key.keycode == 65307 then
		env.engine.context:set_option("ascii_mode", true)
	end
	return 2
end
return vim_mode

如果我想实现按下jk回到ascii_mode应该怎么做,, 发现这个脚本似乎只有在esc alt shift这些按键按下时才会触发,按下普通的字母键,比如i a,会优先弹出候选框,而这个脚本我只能通过+加载,不清楚是否是加载顺序必须要在最前面的@before 0,但是before 0又会出错。。。

+ 等于 push, 会放在 processors 的末尾才会被执行到,如果想一开始就执行,只能用 before 0,语法报错的话把 rime 升级到最新的试试呢

全局 esc 切英文可以直接配置 ascii_composer.switch_key 实现吧,相当于把 esc 映射成 shift?

jk 切换可以试试 key:repr() == "j+k" 行不行

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants