Skip to content

Instantly share code, notes, and snippets.

@lotem
Created July 9, 2012 12:23
Show Gist options
  • Save lotem/3076166 to your computer and use it in GitHub Desktop.
Save lotem/3076166 to your computer and use it in GitHub Desktop.
自動識別西文及數字組成的用戶名
# default.custom.yaml
# 全局範圍識別輸入串爲 rime + 任意數字序列,以及形如 rimeime-1.2.3 的常用西文短語
# 也可將本組 patch 寫入 <輸入方案ID>.custom.yaml 使這組規則僅在一款輸入方案中有效
#
# 第一例,輸入 rime 之後,再輸入任意一個數字,則立即識別爲西文輸入
# 再加上 default.yaml 原有的 email 規則,識別包含 @ 字符的郵箱,於是可以一氣呵成 [email protected]
# 第二例,輸入到 rimeime 時,立即識別爲西文輸入,並可跟隨任意位數字及指定的符號
patch:
recognizer/patterns/rime123: "^rime[0-9]+$"
recognizer/patterns/rimeime: "^rimeime[-_.0-9]*$"
@redleafnew
Copy link

好的, 你这个(同时存在半角和全角)确实无法做到双分号上屏, 因为这里有一个二元语义, 逻辑上冲突了, 第二个分号到底是要上屏备选2, 全角分号. 还是第二个分号只想做为一个顶格键直接上屏.

是用来上屏中文(全角)分号的,我没有用冒号和分号作为候选上屏的。用的以前极点的逻辑,1个分号临时英文,2个分号输入分号,有时输入中文时确实需要分号。

@gfgkmn
Copy link

gfgkmn commented Jan 22, 2024

搞定了. 对我这边是完美了. 不过不知道你适用不适用,
放出来供其他朋友参考.

参见上面的考虑.

最后的模式组

starts_with_semicolon: ';[;A-Za-z_<>\[\]\-+=~@.#?!%^&$*()\\]*$'

最后的函数

function append_original_filter(input, env)
    local envengine = env.engine
    local envcontext = envengine.context
    local composition = envcontext.composition
    local segmentation = composition:toSegmentation()
    local schema = envengine.schema

    if(not composition:empty()) then
        local seg = composition:back()
        if schema.schema_id == "easy_en" then
            yield(Candidate("string", seg.start, seg._end, segmentation.input, ""))
        elseif segmentation.input:sub(1, 1) == ";" and segmentation.input:len() > 1  then
            if segmentation.input:sub(2, 2) == ";" then
                envengine:commit_text(";")
                envcontext:clear()
                return
            else
                yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
            end
        end
    end
    for cand in input:iter() do
        yield(cand)
    end
end

这样就可以使用分号上屏分号了, 空格, 回车也同样上屏分号.

@redleafnew
Copy link

我的出不来,按分号就是上屏个分号。没有临时拼音出现了,改了rime.rua和方案中的
image

@YaoLiMuMu
Copy link

YaoLiMuMu commented Jan 23, 2024 via email

@redleafnew
Copy link

修改return键为commit_composition

editor:
bindings:
Return: commit_composition
这个主要是为了让回车上屏的时候, 同样上屏正常, 不会把前置的分号输出出来.
这样基本上就比较完美了.> 修改return键为commit_composition

大佬,正常输入的时候回车就上屏第一个候选了,能不能正常输入中文时,按回车时上屏的刚才输入的编码。同时实现分号的临时英文,回车时英文。如果这个 Return: commit_composition注释后,正常输入中文时回车为编码上屏,临时英文时,英文的前面会有一个分号。
2024-03-23_16-26-37

@redleafnew
Copy link

2024-03-23_16-28-48

@zwjzxh520
Copy link

作者大大,麻烦整理一下最终版?从最开始的评论依次跟着评论调整下来,效果还是差强人意。

@hoodlum1980
Copy link

hoodlum1980 commented Oct 10, 2024

这两天制作空明码并击方案时想要实现这个英文引导输入的功能,查了下最后实现了,放在这里供参考

engine:
  processors:
    - recognizer # 确保启用了recognizer
  segmentors:
    # 添加下面这项
    - affix_segmentor@temp_en

recognizer:
  patterns:
  # 添加一个标签
    starts_with_single_quote_tag: "^'.*$"
# 向recognizer指明 要匹配的模式和标注的tag名,tag可以为后面translator等指定作用分段范围
# 声明了一种标签的模式:由单引号打头

temp_en:
  tag: starts_with_single_quote_tag
  prefix: "'"
  #suffix: ";"
  tips: "〔 英文 〕"
# 定义了一个affix_segmentor,affix_segmentor可以指定多个实例(所以前面声明时使用了@来指明具体是哪个项)
# 声明使用的引导前缀(或后缀?)

好像是在贴吧看到的,帖子链接如下: 如何配置敲分号后进入临时英文?

这个方案模仿原来的搜狗输入法的 v 英文模式挺好。但是输入 @ 的时候会打断这个模式(估计是被 email 模式给打断了),然后就是按空格后,能不能让它自动在后面追加一个空格呢。不然得按两次空格,一次上屏一次是单词之间的空格。

@hoodlum1980
Copy link

hoodlum1980 commented Oct 10, 2024

我试了一下, 两个分号上屏我也没搞定, 应该有一个lua确认函数, 我现在不知道是啥, 不过输入分号, 目前可以输入一个分号, 然后使用空格或者回车来解决.

连续多个分号, 会有问题.

这里问题的核心是, 不能触发候选框, 不然分号的语义就成为了第二选词键而不是分号内容本身.

所以必须在lua函数中处理. 同时第二个分号后面的分号必须被所有模式组捕获. 理想情况是这样的.

starts_with_semicolon: ';[;A-Za-z_<>\[\]\-+=~@.#?!%^&$*()\\]*$'
function append_original_filter(input, env)
    local envengine = env.engine
    local composition = envengine.context.composition
    local segmentation = composition:toSegmentation()
    local schema = envengine.schema

    if(not composition:empty()) then
        local seg = composition:back()
        if schema.schema_id == "easy_en" then
            yield(Candidate("string", seg.start, seg._end, segmentation.input, ""))
        elseif segmentation.input:sub(1, 1) == ";" and segmentation.input:len() > 1  then
            if segmentation.input:sub(2, 2) == ";" then
                envengine:commit_text(";")
                return
            else
                yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
            end
            -- yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
        end
    end
    for cand in input:iter() do
        yield(cand)
    end
end

但是我试了一个, commit_text这个函数应该不是最终上屏键, 这样做的话, 输入序列会有一个分号被append_original_filter这个处理器后面的处理器处理. 于是出现输入冗余.

目前暂时只能用.

starts_with_semicolon: ';[A-Za-z_<>\[\]\-+=~@.#?!%^&$*()\\]*$'

同时

function append_original_filter(input, env)
    local envengine = env.engine
    local composition = envengine.context.composition
    local segmentation = composition:toSegmentation()
    local schema = envengine.schema

    if(not composition:empty()) then
        local seg = composition:back()
        if schema.schema_id == "easy_en" then
            yield(Candidate("string", seg.start, seg._end, segmentation.input, ""))
        elseif segmentation.input:sub(1, 1) == ";" and segmentation.input:len() > 1  then
            yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
        end
    end
    for cand in input:iter() do
        yield(cand)
    end
end

来搞. 如果要输入分号 就使用 分号+空格或分号加回车来输入

我参考了另一个常见问题,就是如何输入当前时间的,解决方法是提供了一个 lua 脚本来提供“时间”的候选词。我实验了以下,发现它也可以用来模拟原来搜狗输入法早期的 v 模式(临时输入英文模式,而非现在的大写数字输入的 v 模式)。可以在 rime.lua 中这样写:

function time_translator(input, seg)
   if (input == "date" or input == "rq") then
        --[[ 用 `yield` 产生一个候选项
           候选项的构造函数是 `Candidate`,它有五个参数:
            - type: 字符串,表示候选项的类型
            - start: 候选项对应的输入串的起始位置
            - _end:  候选项对应的输入串的结束位置
            - text:  候选项的文本
            - comment: 候选项的注释
        --]]
        local cand = Candidate("date", seg.start, seg._end, os.date("%Y-%m-%d"), "(iso)")
        cand.quality = 1
        yield(cand)

        local cand2 = Candidate("date", seg.start, seg._end, os.date("%Y 年 %m 月 %d 日"), "")
        cand2.quality = 2
        yield(cand2)
    elseif (input == "now" or input == "sj") then
        local cand = Candidate("time", seg.start, seg._end, os.date("%Y-%m-%d %H:%M:%S"), "(iso)")
        cand.quality = 1
        yield(cand)

        local cand2 = Candidate("time", seg.start, seg._end, os.date("%Y 年 %m 月 %d 日 %H:%M:%S"), "")
        cand2.quality = 2
        yield(cand2)

        local cand3 = Candidate("time", seg.start, seg._end, os.date("%H:%M:%S"), "")
        cand3.quality = 3
        yield(cand3)
    --[[ V 模式输入英文 --]]
    elseif (string.len(input) > 1 and string.sub(input, 1, 1) == "v") then
        local cand = Candidate("string", seg.start, seg._end, string.sub(input, 2), "[EN]")
        cand.quality = 1
        yield(cand)
    --[[ "d" 的首个候选词为 "=" --]]
    elseif (input == "d") then
        local cand = Candidate("string", seg.start, seg._end, "=", "<跳转到原帖>")
        cand.quality = 1
        yield(cand)
    end
end

然后把这个脚本中的函数加入到 <schema_name>.custom.yaml 中,再重新部署,就可以在输入 v 以后进入临时输入英文的状态了:

  __merge:
    engine:
      translators/+:                  
        - lua_translator@time_translator

但是一旦输入空格,就会使得输入字符上屏,因为空格键已经被定义成上屏了。所以在 v 模式里连续输入英文句子目前还是不行的。

@huo-feng-ding
Copy link

function append_original_filter(input, env)
    local envengine = env.engine
    local envcontext = envengine.context
    local composition = envcontext.composition
    local segmentation = composition:toSegmentation()
    local schema = envengine.schema

    if(not composition:empty()) then
        local seg = composition:back()
        if schema.schema_id == "easy_en" then
            yield(Candidate("string", seg.start, seg._end, segmentation.input, ""))
        elseif segmentation.input:sub(1, 1) == ";" and segmentation.input:len() > 1  then
            if segmentation.input:sub(segmentation.input:len(), segmentation.input:len()) == ";" then
                envengine:commit_text(string.sub(segmentation.input, 2))
                -- envengine:commit_text(";")
                envcontext:clear()
                return
            else
                yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
            end
        end
    end
    for cand in input:iter() do
        yield(cand)
    end
end


return append_original_filter

我把函数改了一行,可以按分号后将前边输入的英文也顶屏了。
@gfgkmn 大牛厉害,完美解决,谢谢。

@redleafnew
Copy link

输入带点的会重复,如输入 分号data.doc上屏的会是datadata.data.doc

@huo-feng-ding
Copy link

输入带点的会重复,如输入 分号data.doc上屏的会是datadata.data.doc

-- 原始字符串输出,用来实现分号临时英文,再输入分号顶屏上字

function append_original_filter(input, env)
    local envengine = env.engine
    local envcontext = envengine.context
    local composition = envcontext.composition
    local segmentation = composition:toSegmentation()
    local schema = envengine.schema

    if(not composition:empty()) then
        local seg = composition:back()
        if schema.schema_id == "easy_en" then
            yield(Candidate("string", seg.start, seg._end, segmentation.input, ""))
        elseif segmentation.input:sub(1, 1) == ";" and segmentation.input:len() > 1  then
            if segmentation.input:sub(segmentation.input:len(), segmentation.input:len()) == ";" then
                envengine:commit_text(string.sub(segmentation.input, 2))
                -- envengine:commit_text(";")
                envcontext:clear()
                return
            -- else
                -- yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
            end
        end
    end
    for cand in input:iter() do
        yield(cand)
    end
end


return append_original_filter

对lua不熟悉,暂时改成这样先用着了。

@redleafnew
Copy link

谢谢。可能是我设置的问题,这次不出现点了,直接上屏的是句号。

@redleafnew
Copy link

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