iDvel / rime-ice

Rime 配置:雾凇拼音 | 长期维护的简体词库
https://dvel.me/posts/rime-ice/
GNU General Public License v3.0
9.56k stars 637 forks source link

feature request: 用 lua_filter 固定字词的顺序 #586

Closed Anber55 closed 9 months ago

Anber55 commented 10 months ago

大佬,想请教2个问题:

1、例如在雾凇拼音里,与和于的自重分别是: 于 yu 3614992 与 yu 2104552 如果以我的习惯来说,让「与」出现在候选的前面,「于」出现在候选的后面 我暂时想到的有2种调整方法: ①在custom_phrase.txt里调整,在但大佬写的备注里面看到,只能固定非完整编码,这样的话只有打「y」才会固定它俩的位置,打「yu」却不能 ②在cn_dicts里面新建一个buchong.dict.yaml文件,放在rime_ice.dict.yaml的最前面,里面放上自己设置的补充字词,例如: 于 yu 3614992 与 yu 3704552 但是不知道这样做是否会有其他的一些不好的影响

2、写入custom_phrase.txt的字词,例如[哪里 nl 9],是不是输入nl或nali都不能进入自造词

感谢大佬

iDvel commented 10 months ago

custom_phrase.txt 翻译器不和拼音翻译器互相造句,所以不建议写完整编码,不然包含此完整编码的字无法参与造词了。

插入一个新词库的方式其实也没用,因为「yu 于 与……」是参与调频的,不能保证每次都是某一个在前面。

Rime 本身没有这种配置,如果需要固定字词的顺序,且不影响造词,需要用一个 lua_filter 调整顺序。

iDvel commented 10 months ago

我也不会 Lua,都是问 ChatGPT 的,和目前的长词优先的逻辑应该差不多的,有空我研究研究啊,或者谁会可以帮写一个。

Anber55 commented 9 months ago

是的,主要在于custom_phrase.txt影响造词,不然就利用它来控制了

iDvel commented 9 months ago

想到了一个不太完美的简单 workaround

https://github.com/mirtlecn/rime-ice-fork/blob/workaroud_586/lua/custom_phrase_filter.lua#L1C1-L16C28

在造词的时候禁用 custom_phrase 候选,就能在 custom_phrase 内输入全码调整字频,并且不影响造词。

不完美的地方是,custom_phrase 内的字频调整无法在造词的时候作用(其实目前的设置下,custom_phrase 内的简码字频调整也不能影响造词时的第一个汉字)

卧槽,竟然这么简单吗。。。

Anber55 commented 9 months ago

大佬整合一下我还没想到具体咋整

iDvel commented 9 months ago

试试 lua_filter,ChatGPT 都问秃噜皮儿了,急得挠头 😮‍💨

patch:
  engine/filters:
    # ……
    - lua_filter@*pin_cand_filter
    - uniquifier

  pin_cand_filter:
    # 格式:编码<Tab>字词1<Space>字词2……
    - 'l    了 啦'
    - 'le   了'
    - 'la   啦'
    - 'ta   他 她 它'
    - 'ni hao   你好 拟好'

不知道为什么不能正确 yield 啊。 pin_cand_filter.lua

-- 置顶候选项

local function isInList(list, str)
    for i, v in ipairs(list) do
        if v == str then
            return true, i
        end
    end
    return false, 0
end

local M = {}

function M.init(env)
    local config = env.engine.schema.config
    env.name_space = env.name_space:gsub("^*", "")
    -- 遍历要置顶的候选项列表,将其转换为 table 存储到 M.pin_cands
    -- 'ta  他 她 它' → M.pin_cands["ta"] = {"他", "她", "它"},
    -- 'ni hao  你好 拟好' → M.pin_cands["ni hao"] = {"你好", "拟好"}
    local list = config:get_list(env.name_space)
    M.pin_cands = {}
    for i = 0, list.size - 1 do
        local code, texts = list:get_value_at(i).value:match("([^\t]+)\t(.+)")
        if code and texts then
            M.pin_cands[code] = {}
            for text in texts:gmatch("%S+") do
                table.insert(M.pin_cands[code], text)
            end
        end
    end
end

function M.func(input)
    -- 要置顶的放到 pined 中,其余的放到 others
    local pined = {}
    local others = {}
    local pined_count = 0
    local others_is_empty = true
    for cand in input:iter() do
        local pins = M.pin_cands[cand.preedit]
        if pins then
            for _ = 1, #pins do
                table.insert(pined, '')
            end
            local ok, idx = isInList(pins, cand.text)
            if ok then
                pined[idx] = cand
                pined_count = pined_count + 1
            else
                table.insert(others, cand)
                others_is_empty = false
            end
        else
            yield(cand)
        end
        if (pins and pined_count == #pins) or (others and #others > 50) then
            break
        end
    end
    -- yield pined others 及后续的候选项
    if pined_count > 0 then
        for _, cand in ipairs(pined) do
            yield(cand)
        end
    end
    if not others_is_empty then
        for _, cand in ipairs(others) do
            yield(cand)
        end
    end
    for cand in input:iter() do
        yield(cand)
    end
end

return M
iDvel commented 9 months ago

push 上来了,默认没启用,先试一阵子,双拼还没测试。

用 lua_filter 固定字词的顺序,将需要的候选项提到前面来,可以造词。

全拼补丁示例 rime_ice.custom.yaml

patch:
  engine/filters:
    - lua_filter@corrector
    - simplifier@emoji
    - simplifier@traditionalize
    - lua_filter@v_filter
    - lua_filter@autocap_filter
    - lua_filter@reduce_english_filter
    - lua_filter@pin_cand_filter  # 增加 pin_cand_filter
    - uniquifier

  # 配置要置顶的字词
  # 请确定这个编码会产生对应的字词,如 l →「了 啦」、le → 「了」,la → 「啦」
  # 'le 哈' 这种输入 le 无法得到「哈」的非正确拼音编码,不会生效且影响程序查找效率。
  # 如果 custom_phrase 里也写了 `了    le`,会顶替拼音翻译器的「了」,仍然不能造词。
  # 建议这里放常规的要置顶的字词,custom_phrase 里放非拼音编码的。
  # 格式:编码<Tab>字词1<Space>字词2……
  pin_cand_filter:
    - 'l    了 啦'
    - 'le   了'
    - 'la   啦'
    - 'ta   他 她 它'
    - 'ni hao   你好 👋 拟好'
iDvel commented 9 months ago

我改成了下面这样子,我觉得还行 🤔 晚上再改改 push 上来。

lue_filter 比 custom_phrase 的优点是 filter 只是单纯提高候选项的顺序,不是另一个翻译器,可以造词,所以可以固定完整拼音。

# Lua 配置: 置顶候选项
# 符合左边的 cand.preedit 时,按顺序置顶右边的候选项。只是提升已有候选项的顺序,没有自创编码的功能。
# (对简繁转换无效,除非简繁文字一致 😰)
#
# preedit 是经过 translator/preedit_format 处理后的编码,如果是词语则包含空格。
# ⚠️ 注意方案的 preedit_format 设定,如果 v 显示为 ü,那么左边也要写 ü
# ⚠️ 双拼 ⚠️ 显示为全拼拼写就要写全拼,如 'shuang pin',显示为双拼拼写就要写双拼,如 'ul pb' 😰
#
# 脚本自动额外生成 preedit 中最后一个空格后面的首字母和 zh ch sh,
# 如 'ni hao' 会自动生成 'ni h'、'ni hao'
# 如 'bu hao chi' 会自动生成 'bu hao c'、'bu hao ch'、'bu hao chi'
# 如果同时写了 da zhuan 和 da zhong,输入 da z 时,排在前面的的优先,除非明确指定 'da z'。
pin_cand_filter:
  # 格式:编码<Tab>字词1<Space>字词2……
  # 示例:
  # - 'le   了'         # 输入 le 时,置顶「了」
  # - 'la   啦'         # 输入 la 时,置顶「啦」
  # - 'ta   他 她 它'    # 可以置顶多个字,按顺序排列
  # - 'ta   啊'         # ❌ 编码不会产生的字词,不会生效且影响查找效率。自创编码的字词句可以写到 custom_phrase 中。
  # - 'l    了 啦'      # 支持单编码或输入到一半的编码,输入 l 时,置顶「了、啦」
  # - 's m  什么'       # 支持简拼,要和输入框的行为一致,有空格加空格
  # - 'w s m    为什么' # 支持简拼,要和输入框的行为一致,有空格加空格
  # - 'ni hao   你好 👋 拟好'  # 如果 emoji 被分割开了,可以任意调整 emoji 的位置
  # # 以下两行,会额外生成 'da z' 'da zh' 的置顶,前两个候选项是「大专、大众」,先写的排在前面
  # - da zhuang 大专
  # - da zhong  大众
  # # 如果明确定义了简码形式,则完全使用简码形式
  # - da z  打字
  # - da zh 打仗
  #
  # ⚙️ 以下是个人习惯,仅供参考,可以打个补丁来覆盖。
  # 单编码
  - q   去 千
  - w   我 万 往
  - e   呃
  - r   让 人
  - t   他 她 它 祂
  - y   与 于
  # - u 在 custom_phrase 置顶
  # - i 在 custom_phrase 置顶
  - o   哦
  - p   片 篇
  - a   啊
  - s   是 时 使 式
  - d   的 地 得
  - f   发 放 分
  - g   个 各
  - h   和 或
  - j   及 将 即 既 继
  - k   可
  - l   了 啦 喽 嘞
  - z   在 再 自
  - x   想 像 向
  - c   才 从
  # - v
  - b   吧 把 呗 百
  - n   那 哪 拿 呐
  - m   吗 嘛 呣
  # 单字
  - de  的 地 得
  - na  那 哪 拿
  - ta  他 她 它 祂
  - er  而 儿 二
  - ma  吗 嘛 妈
  - zhe 这 着
  - hai 还
  - you 有 🈶 又 由
  - mei 没
  - bing    并
  - tong    同
  - yu  与 于
  - he  和
  - ji  及 即 既
  - shi 是 时
  - la  啦 拉
  - xing    行
  - dian    点
  - yao 要
  - kan 看
  - bei 被
  - zuo 做
  - dao 到 倒
  - xiang   想 像 向
  # ta、na
  - ta de   他的 她的 它的
  - 'tad    他的 她的 它的'  # 英文单词 tad 造成 preedit 为 tad,从而让 ta d 的置顶未生效,需要明确再写上 tad
  - ta men  他们 她们 它们
  - ta men de   他们的 她们的 它们的
  - na er   那儿 哪儿
  - na ge   那个 哪个
  - na xie  那些 哪些
  - na li   那里 哪里
  - na bian 那边 哪边
  - na bian er  那边儿 哪边儿
  - na wei  那位 哪位
  # 简码
  - zh  这
  - d d 等等
  - 'dd 等等'  # 覆盖英文单词 D&D
  - d d d d 等等等等
  - g g 刚刚
  - c g g   才刚刚
  - z d 知道
  - b z d   不知道
  - w w 往往
  - h h 哈哈
  - k k 看看
  - c c 常常
  - x x 想想 🤔 想象
  - y w 因为
  - s m 什么
  - w s m   为什么
  - s b s   是不是
  - m s m   没什么
  - s m d   什么的
  - s m s   什么是
  - 'sms    什么是'  # 覆盖英文单词 SMS
  - s m a   什么啊
  - 'sma    什么啊'  # 覆盖英文单词 S码
iDvel commented 9 months ago

经过 simplify 繁简转化处理过的候选判断其原候选,然后在结尾转化回 shadowcandidate 应当就能处理

没搞明白怎么写,我 push 上来了,你可以看一下嘛。

另外发现一个诡异的问题,我只给全拼写了一些,双拼的 pin_cand_filter: 配置都留空了,结果切换几次方案后会串台,给全拼写的置顶双拼用了,切几次后全拼的置顶没了。全部都不留空的话倒没问题。

Anber55 commented 9 months ago

请问这个lua是不是不能输入实际打不出来的词,例如我的仓输入法用的是雾凇方案,ee打不出来嗯嗯,用这个lua也无法置顶这个词,所以来问一下~

iDvel commented 9 months ago

请问这个lua是不是不能输入实际打不出来的词,例如我的仓输入法用的是雾凇方案,ee打不出来嗯嗯,用这个lua也无法置顶这个词,所以来问一下~

是的,只是对已有候选项做个排序。

Anber55 commented 9 months ago

请问有没有办法实现这个功能,就是对不在候选的词做排序,或者嗯嗯如何通过ee打出来

iDvel commented 9 months ago

加上了 7ff9e64 创建 custom_phrase_t9.txt 写入:

嗯嗯  33
Anber55 commented 9 months ago

谢谢,我试了一下,使用这个lua,英文也不能置顶,只有可以打出的中文才可以置顶,这个lua能不能实现类似custom_phrase.txt的功能而且可以造词

iDvel commented 9 months ago

这个 lua 就是单纯做排序。 英文也可以排序,比如 - chrome ChromeOS。 要自定义短语就写到 custom_phrase 里,还要能造词就写到拼音词库里。

Anber55 commented 9 months ago

大佬,我添加了以下英文,但是排序不起作用:

  - OK  ok
  - and and

还需要其他设置吗?这些单词都在英文词典里面

iDvel commented 9 months ago

左侧是 preedit 就是输入框显示的那个,你是要将小写 ok 排在大写 OK 前面,那应该这么写:

- ok    ok

and 本来就在第一个候选项,如果你用另一个 Lua 降低了,如果非要又降低又提升,可能要这么写:

  - an d    and
  - and and
Anber55 commented 9 months ago

大佬,再请教一个问题,我这样设置后,打出的结果是下面图片的样子,而不只Mac在前 IMG_0225 IMG_0226

Anber55 commented 9 months ago

还有就是我通常是用每个字的首字母打字,但是在lua里设置首字母置顶好像不行,例如:

  - bs  不是
iDvel commented 9 months ago

你先不要折腾太多了,我晚上得改一改这个逻辑,有点问题,可能写法会变。

Anber55 commented 9 months ago

好的,感谢大佬,等大佬写好了我再测试

Anber55 commented 9 months ago

大佬,已经更新了,现在没啥大问题,就是一个小问题,如果一个英文单词带有空格,没办法调整词序,例如Quantumult X,我试了"Quantumult X"也不行

iDvel commented 9 months ago

如果一个英文单词带有空格,没办法调整词序

词汇有空格的用 " > " 分割,示例:

- google    Google Maps > Google > Google Calendar

2024-02-03-002420

不过这只针对单一编码的情况,否则需要写好几份。英文还有补全的,纯英文之间调频直接在英文词库里用权重固定比较好。

zhjh0521 commented 9 months ago

现在啥情况?更新了以后,在新版里面,custom_phrase之前我自己定义的权重都不起作用了。比如之前我定义的“谢谢 xx 3”,以前我输入xx,第一个就会出现“谢谢”,然后是“想想 想象”。但现在无论我怎么改权重,“谢谢”只会出现在“想想 想象”后面

iDvel commented 9 months ago

用现在这个,自己定义一些。 把 custom_phrase 里面编码一致的删了,否则仍然不能参与造词。

patch:
  pin_cand_filter:
    - xx    谢谢 🙏 想想 🤔 想象

你的 custom_phrase 其实起作用了,但最后又被这个 filter 调整顺序了。 删除或屏蔽这个功能:在 engine/filters 删掉 lua_filter@pin_cand_filter,或者只置顶一个不冲突的:

patch:
  pin_cand_filter: [ "d 的" ]
zhjh0521 commented 9 months ago

用现在这个,自己定义一些。 把 custom_phrase 里面编码一致的删了,否则仍然不能参与造词。

patch:
  pin_cand_filter:
    - xx  谢谢 🙏 想想 🤔 想象

你的 custom_phrase 其实起作用了,但最后又被这个 filter 调整顺序了。 删除或屏蔽这个功能:在 engine/filters 删掉 lua_filter@pin_cand_filter,或者只置顶一个不冲突的:

patch:
  pin_cand_filter: [ "d   的" ]

不好意思,没太理解你说得。我把这个置顶功能删了,是可以解决这个问题的。你说得另外把编码一致的删了,是什么意思?在custom_phrase里面,没有编码一致的。

patch:
  pin_cand_filter:
    - xx    谢谢 🙏 想想 🤔 想象

这个代码是加在哪里的?

iDvel commented 9 months ago

custom_phrase 置顶,你在 custom_phrase 里写了 的 de,输入 de 时「的」排在了候选项最前面; 接着经过去重,让拼音翻译器本身的「的」没了,只保留了 custom_phrase 的「的」。 由于两个翻译器之间无法造词,所以「的」这个字失去了造词效果,因此之前建议只写非完整拼音的编码,如 的 d

现在由 pin_cand_filter 置顶,这个 Lua 仅仅是调整候选项的顺序(没有创造词汇编码的功能),你的「的」仍然是拼音翻译器本身的「的」,可以造词,可以写完整拼音,更好了些。

「把编码一致的删了」是说如果你在 pin_cand_filter 置顶了 - d 的 地 得 🉐, 那就把 custom_phrase 里的 的 d 给删了,不然置顶上来的不是拼音翻译器自己的。

pin_cand_filter 的配置在方案里如 rime_ice.schema.yaml,补丁就是你用的方案的补丁如 rime_ice.custom.yaml。 双拼就是对应的双拼。

书写方法我晚些补上,双拼有些不一样。

zhjh0521 commented 9 months ago

custom_phrase 置顶,你在 custom_phrase 里写了 的 de,输入 de 时「的」排在了候选项最前面; 接着经过去重,让拼音翻译器本身的「的」没了,只保留了 custom_phrase 的「的」。 由于两个翻译器之间无法造词,所以「的」这个字失去了造词效果,因此之前建议只写非完整拼音的编码,如 的 d

现在由 pin_cand_filter 置顶,这个 Lua 仅仅是调整候选项的顺序(没有创造词汇编码的功能),你的「的」仍然是拼音翻译器本身的「的」,可以造词,可以写完整拼音,更好了些。

「把编码一致的删了」是说如果你在 pin_cand_filter 置顶了 - d 的 地 得 🉐, 那就把 custom_phrase 里的 的 d 给删了,不然置顶上来的不是拼音翻译器自己的。

pin_cand_filter 的配置在方案里如 rime_ice.schema.yaml,补丁就是你用的方案的补丁如 rime_ice.custom.yaml。 双拼就是对应的双拼。

书写方法我晚些补上,双拼有些不一样。

懂了,谢谢