7
28
2024
2

fcitx5 码表同步方案

本文来自依云's Blog,转载请注明。

自从用上了 fcitx5-android,我便面临一个问题:我有多份 fcitx5 实例在运行,也导致我有多份码表文件。于是时常遇到一个词明明我添加到码表里了,但用的时候却发现它并不在的情况。一开始我只是以电脑上的为准,时不时把手机上的码表文件覆盖一下以保存同步。但情况随着我又买了台式电脑而更加严重起来,盲目地覆盖势必会丢失更多前不久刚添加的新词。是时候弄个新的方案了。

新方案的主旨就是「合并」:如果我在一个实例里添加了某词,那么在其它实例上也添加;删除同理。于是来到了 git 的模型——先指定一个共同的基准,合并的双方都与之比较,多起来的就添加到另一方、少了的就从另一方删除。至于基准的选择也很好决定:指定一个已知同步了的 btrfs 快照里的码表就好了,然后每隔一段时间更新到最近同步过的快照。

接下来就是实现了。fcitx5 的码表格式比较复杂,不过它有提供 libime_tabledict 命令,可以把码表数据转换成纯文本格式。至于对比之后的修改,倒不用再用这个命令转回来,因为我已经有 fcitx5-tabledict 这个编辑工具了。编辑好之后需要重新加载码表。以前我都是先退出 fcitx5,编辑完再启动的。现在 Wayfire 有 bug,重启输入法程序有概率导致它崩溃,查了很久都没能查明原因,就只好想办法绕过了。于是在群里问到了重新加载码表的 D-Bus 接口。Android 那边就用 adb 重启应用吧。

对比的程序也是用 Rust 写的,毕竟效率高、还不容易写出问题来。项目放 GitHub 上了,叫 fcitx5-dictsync。至于最上层完成所有操作的脚本,因为有太多具体环境相关的信息,用 zsh 脚本写就好啦。下边是我两台电脑同步的脚本:

#!/bin/zsh -e

base_snap=2024-07-28-11-auto

dir=$(mktemp -d -t dictsync.XXXXXX)

cleanup () {
  rm -rf $dir
}

trap cleanup EXIT INT TERM

cd $dir
scp lilyforest:.local/share/fcitx5/table/lilywb.'*'.dict .
fcitx5-dictsync /run/ssd/snapshots/home-lilydjwg/$base_snap/.local/share/fcitx5/table/lilywb.main.dict ~/.local/share/fcitx5/table/lilywb.main.dict lilywb.main.dict a.change b.change

if [[ -s a.change ]]; then
  fcitx5-tabledict < a.change
  dbus-send --print-reply=literal --dest=org.fcitx.Fcitx5 /controller org.fcitx.Fcitx.Controller1.SetConfig string:fcitx://config/addon/table/reloaddict variant:string:""
fi

if [[ -s b.change ]]; then
  scp b.change lilyforest:tmpfs
  ssh -T lilyforest <<SH
fcitx5-tabledict < ~/tmpfs/b.change
dbus-send --print-reply=literal --dest=org.fcitx.Fcitx5 /controller org.fcitx.Fcitx.Controller1.SetConfig string:fcitx://config/addon/table/reloaddict variant:string:""
rm ~/tmpfs/b.change
SH
fi

和 fcitx5-android 同步的脚本,长得挺像的。但因为 Android 上经常多出来一些奇奇怪怪的自动造的词,所以添加了编辑操作。听说新版 Android 已经不能访问应用自己的目录了,但我还没用上,所以我先不管啦。

#!/bin/zsh -e

base_snap=2024-07-28-11-auto

adb connect phone_xz2c:5555

dir=$(mktemp -d -t dictsync.XXXXXX)

cleanup () {
  rm -rf $dir
}

trap cleanup EXIT INT TERM

cd $dir
scp phone_xz2c:/sdcard/Android/data/org.fcitx.fcitx5.android/files/data/table/lilywb.'*'.dict .
fcitx5-dictsync /run/ssd/snapshots/home-lilydjwg/$base_snap/.local/share/fcitx5/table/lilywb.main.dict ~/.local/share/fcitx5/table/lilywb.main.dict lilywb.main.dict a.change b.change

if [[ -s a.change ]]; then
  vim a.change
  if [[ -s a.change ]]; then
    fcitx5-tabledict < a.change
    dbus-send --print-reply=literal --dest=org.fcitx.Fcitx5 /controller org.fcitx.Fcitx.Controller1.SetConfig string:fcitx://config/addon/table/reloaddict variant:string:""
  fi
fi

if [[ -s b.change ]]; then
  fcitx5-tabledict lilywb.main.dict lilywb.user.dict < b.change
  scp lilywb.user.dict phone_xz2c:/sdcard/Android/data/org.fcitx.fcitx5.android/files/data/table/
  adb -s phone_xz2c:5555 shell am force-stop org.fcitx.fcitx5.android
fi

哦对了,Windows 上虽然还没有 fcitx5,但是托 WubiLex 的福,微软五笔的码表位置和格式都弄清楚了。我还没写生成 .lex 文件的程序啦。先在虚拟机里用 WubiLex 生成了一份自己的码表。虽然词的顺序有很大的问题,但反正我也很少用 Windows,先凑合用着吧,懒得处理了。码表文件要放到 C:\Windows\InputMethod\CHS\ChsWubi.lex。这个文件只有「TrustedInstaller」用户才有权限修改,不过用管理员权限就可以更改文件的所有者,然后就有权限给自己修改权限,就可以修改它了。Windows 真神奇啊。

Category: 中文支持 | Tags: fcitx 中文支持 linux | Read Count: 3393
Ke 说:
Jul 29, 2024 11:41:24 PM

这个能不能直接用syncthing 之类的同步?

Avatar_small
依云 说:
Jul 30, 2024 10:08:28 AM

直接同步文件有两个问题:会相互覆盖修改;同步完成时无法通知 fcitx5 重新加载。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com