这是indexloc提供的服务,不要输入任何密码
Skip to content

以词定字长句输入支持 #1251

@WantChane

Description

@WantChane

摘要

为以词定字功能提供长句输入支持,给出了一个粗糙的实现。

输入方案

小鹤双拼 double_pinyin_flypy

相关应用

Weasel 0.16.3

系统信息

Windows 11

详细说明

现在的以词定字功能不支持长句输入。

例如:目标输出“你好世(界)我爱你”,同时输入所有字符( ni hao shi jie wo ai ni ),我理想的情况下候选词和选定操作依次为“你好” -> 1 -> “世界” -> [ -> "我爱你" -> 1。

在rime-ice中,按下 [ 后会输出“世”,你好和 wo ai ni 全部被覆盖。

BlindingDark/rime-lua-select-character中,按下 [ 后会输出“你好世”。wo ai ni 会被覆盖。

个人觉得挺影响打字操作的,所以修改了一下WantChane/rime-ice

图片

但是感觉我的实现还有优化空间,比如说以词选字的时候,可以模仿数字符上屏的功能,数字上屏的时候并不会出现上述文字被覆盖的情况,以词选字只需要修改被上屏的字即可。在PR之前想看看大伙有没有思路,一起讨论一下。

自定义配置

-- 以词定字
-- 原脚本 https://github.com/BlindingDark/rime-lua-select-character
-- 可在 default.yaml → key_binder 下配置快捷键,默认为左右中括号 [ ]
-- 20230526195910 不再错误地获取commit_text,而是直接获取get_selected_candidate().text
-- 20240128141207 重写:将读取设置移动到 init 方法中;简化中文取字方法;预先判断候选存在与否,无候选取 input
-- 20240508111725 当候选字数为 1 时,快捷键使该字上屏
-- 20250515093039 以词定字支持长句输入

local select = {}

function select.init(env)
    local config = env.engine.schema.config
    env.first_key = config:get_string('key_binder/select_first_character')
    env.last_key = config:get_string('key_binder/select_last_character')
end

function select.func(key, env)
    local engine = env.engine
    local context = env.engine.context

    if
        not key:release()
        and (context:is_composing() or context:has_menu())
        and (env.first_key or env.last_key)
    then
        local candidate = context.input
        if context:get_selected_candidate() then
            candidate = context:get_selected_candidate().text
        end
        if utf8.len(candidate) > 1 then
            local selected = ""
            if (key:repr() == env.first_key) then
                selected = candidate:sub(1, utf8.offset(candidate, 2) - 1)
            elseif (key:repr() == env.last_key) then
                selected = candidate:sub(utf8.offset(candidate, -1))
            else
                return 2
            end
            local committed = context:get_commit_text()
            local start_pos, end_pos = committed:find(candidate)
            if start_pos and end_pos then
                local part1 = committed:sub(1, end_pos):gsub(candidate, selected)
                local part2 = committed:sub(end_pos + 1)
                engine:commit_text(part1)
                context:clear()
                if part2 ~= "" then
                    context:push_input(part2)
                end
                return 1
            else
                return 2
            end
        else
            if key:repr() == env.first_key or key:repr() == env.last_key then
                engine:commit_text(candidate)
                context:clear()
                return 1
            end
        end
    end
    return 2
end

return select

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions