Skip to content

Instantly share code, notes, and snippets.

@lotem
Created July 9, 2012 12:23
    Show Gist options
    • Select an option

    • Save lotem/3076166 to your computer and use it in GitHub Desktop.

    Select an option

    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 規則,識別包含 @ 字符的郵箱,於是可以一氣呵成 rime123@company.com
    # 第二例,輸入到 rimeime 時,立即識別爲西文輸入,並可跟隨任意位數字及指定的符號
    patch:
    recognizer/patterns/rime123: "^rime[0-9]+$"
    recognizer/patterns/rimeime: "^rimeime[-_.0-9]*$"
    @jsonsuxing

    Copy link
    Copy Markdown

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

    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可以指定多个实例(所以前面声明时使用了@来指明具体是哪个项)
    # 声明使用的引导前缀(或后缀?)

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

    有一个注意事项:engine/segmentors 里把 affix_segmentor@temp_en 放在 punct_segmentor 前面,这样才会有效果

    @qhjia

    qhjia commented Nov 8, 2023

    Copy link
    Copy Markdown

    有没有什么方法能把z键反查和临时英文结合起来呢,最理想的情况是我按完z键输入英文后按回车(退而求其次别的键也行),就可以自动把z去掉留下英文。再不济可以在候选栏中专门留个位置给英文。有可能实现这个功能吗?

    @qhjia

    qhjia commented Nov 8, 2023

    Copy link
    Copy Markdown

    @jiapeng123456 新加的segmentor要在matcher后面punct_segmentor前面,按一下分号出现tips里的提示才是真的改好了。你部属完可以到build/xxx.schema.yaml里看一眼有没有搞对。给你我的patch设置

      "recognizer/patterns/quickeng": "^;.*$"   
      "engine/segmentors/@before 2": affix_segmentor@temp_en
      temp_en:
        tag: quickeng
        prefix: ";"
        tips: "〔英文〕"
    

    @gfgkmn

    gfgkmn commented Jan 4, 2024

    Copy link
    Copy Markdown

    前一段时间折腾了一下这个功能, 除了英文输入下因为easy_en辞典问题带来的一些问题之外(主要是英文输入下单引号作为省略符与作为选词键的冲突, 不过基本与本贴问题无关), 认为已经比较完美的重现了之前极点五笔的临时英文功能.

    把配置分享一下.

    engine:
      Processors:
        - ascii_composer
        - key_binder
        - recognizer
        - speller
        - punctuator
        - selector
        - navigator
        - express_editor
      segmentors:
        - ascii_segmentor
        - matcher
        - abc_segmentor
        - affix_segmentor@temp_en
        - punct_segmentor
        - fallback_segmentor
      translators:
        - punct_translator
        - reverse_lookup_translator
        - table_translator
        - lua_translator@date_translator  # 自定义系统变量输出
        - lua_translator@calculator       # 计算器:二元运算,coco 开头,如 coco56*34 coco24/1024
        - table_translator@temp_en
      filters:
        - simplifier@tradition
        - lua_filter@append_original_filter # append original text
        - uniquifier
    
    
    key_binder:
      import_preset: default
      bindings:
        - { when: always, accept: Control+period, toggle: full_shape }  # control+. switch中英标点
        - { when: has_menu, accept: semicolon, send: 2 }                # 候选2 用分号
        - { when: has_menu, accept: apostrophe, send: 3 }               # 候选3 用单引号
    
    editor:
      bindings:
        Return: commit_composition
    

    以上配置中, 修改了几个地方.

    1. 调整了key_binder和recognizer的顺序这个是因为我使用主流五笔输入法的分号键进行临时英文引导, 同时也使用分号键进行第二个备选词的选择. 所以需要让选词的key_binder的优先词比recogizer更高, 否则的话, 选词时的分号会被识别为分隔符. 从而无法使用分号选词.

    2. 如前面各位所述, 分别添加了
      segmentor

      • affix_segmentor@temp_en

      translators

      • table_translator@temp_en

      filters

      • lua_filter@append_original_filter # append original text

      其中引用的temp_en定义如下

      temp_en:
        tag: starts_with_semicolon
        dictionary: easy_en
        enable_completion: true
        prefix: ";"
        tips: "[EN]"
        # 定义了一个affix_segmentor,affix_segmentor可以指定多个实例(所以前面声明时使用了@来指明具体是哪个项)
        # 声明使用的引导前缀(或后缀?)
      

      这里添加了easy_en做为临时英文的外挂词库, 使用分号键引导, 其中的tag指定了 recognizer 所识别的模式如下

      recognizer:
        import_preset: default
        patterns:
          # punct: "^/([0-9]+[a-z]*|[a-z]+)$" # 注意前方需要有4个空格,跟下面对齐
          calculator: "^coco.*$"          # 计算器
          reverse_lookup: "^z[a-z]*$"   # 反查词条的正则
          starts_with_semicolon: ';[A-Za-z_<>\[\]\-\\]*$'
      

      这里的 starts_with_semicolon定义的正则表达式对输入序列进行识别, 如果以分号开始的时候, 就会进入临时英文. 注意该临时英文中同时支持下划线, 尖括号, 方括号, 短线, 反斜杠等等不同的字符, 如果不需要的话可以根据自己的需要来删减.

    3. 支持挂载英文词库中不存在输入词的情况.

      function append_original_filter(input, env)
        local composition = env.engine.context.composition
        local segmentation = composition:toSegmentation()
        local schema = env.engine.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) == ";" 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
      

      在rime.lua中添加以上函数. 因为我这个方案挂载了easy_en的这个词库, 那么在临时英文中进行输入的时候, 如果输入的是一个新单词, 那么挂载词库中没有该新词, 备选中不会出现, 这样就无法使用空格键进行上屏, 因此添加这个函数在备选列表中增加了了一个与输入串完全一致的备选. 同时因为输入序列实际上是以分号开始的, 所以需要路过第一个位置, 也就是下面两行.

      elseif segmentation.input:sub(1, 1) == ";" then
        yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
      

      这两行, 这两行判断当输入的序列以分号开头(临时英文)的时候, 生成的候选把分号去掉.

    4. 修改return键为commit_composition

      editor:
      bindings:
          Return: commit_composition
      

      这个主要是为了让回车上屏的时候, 同样上屏正常, 不会把前置的分号输出出来.

      这样基本上就比较完美了.

    @redleafnew

    Copy link
    Copy Markdown

    前一段时间折腾了一下这个功能, 除了英文输入下因为easy_en辞典问题带来的一些问题之外(主要是英文输入下单引号作为省略符与作为选词键的冲突, 不过基本与本贴问题无关), 认为已经比较完美的重现了之前极点五笔的临时英文功能.

    把配置分享一下.

    engine:
      Processors:
        - ascii_composer
        - key_binder
        - recognizer
        - speller
        - punctuator
        - selector
        - navigator
        - express_editor
      segmentors:
        - ascii_segmentor
        - matcher
        - abc_segmentor
        - affix_segmentor@temp_en
        - punct_segmentor
        - fallback_segmentor
      translators:
        - punct_translator
        - reverse_lookup_translator
        - table_translator
        - lua_translator@date_translator  # 自定义系统变量输出
        - lua_translator@calculator       # 计算器:二元运算,coco 开头,如 coco56*34 coco24/1024
        - table_translator@temp_en
      filters:
        - simplifier@tradition
        - lua_filter@append_original_filter # append original text
        - uniquifier
    
    
    key_binder:
      import_preset: default
      bindings:
        - { when: always, accept: Control+period, toggle: full_shape }  # control+. switch中英标点
        - { when: has_menu, accept: semicolon, send: 2 }                # 候选2 用分号
        - { when: has_menu, accept: apostrophe, send: 3 }               # 候选3 用单引号
    
    editor:
      bindings:
        Return: commit_composition
    

    以上配置中, 修改了几个地方.

    1. 调整了key_binder和recognizer的顺序这个是因为我使用主流五笔输入法的分号键进行临时英文引导, 同时也使用分号键进行第二个备选词的选择. 所以需要让选词的key_binder的优先词比recogizer更高, 否则的话, 选词时的分号会被识别为分隔符. 从而无法使用分号选词.

    2. 如前面各位所述, 分别添加了
      segmentor

      • affix_segmentor@temp_en

      translators

      • table_translator@temp_en

      filters

      • lua_filter@append_original_filter # append original text

      其中引用的temp_en定义如下

      temp_en:
        tag: starts_with_semicolon
        dictionary: easy_en
        enable_completion: true
        prefix: ";"
        tips: "[EN]"
        # 定义了一个affix_segmentor,affix_segmentor可以指定多个实例(所以前面声明时使用了@来指明具体是哪个项)
        # 声明使用的引导前缀(或后缀?)
      

      这里添加了easy_en做为临时英文的外挂词库, 使用分号键引导, 其中的tag指定了 recognizer 所识别的模式如下

      recognizer:
        import_preset: default
        patterns:
          # punct: "^/([0-9]+[a-z]*|[a-z]+)$" # 注意前方需要有4个空格,跟下面对齐
          calculator: "^coco.*$"          # 计算器
          reverse_lookup: "^z[a-z]*$"   # 反查词条的正则
          starts_with_semicolon: ';[A-Za-z_<>\[\]\-\\]*$'
      

      这里的 starts_with_semicolon定义的正则表达式对输入序列进行识别, 如果以分号开始的时候, 就会进入临时英文. 注意该临时英文中同时支持下划线, 尖括号, 方括号, 短线, 反斜杠等等不同的字符, 如果不需要的话可以根据自己的需要来删减.

    3. 支持挂载英文词库中不存在输入词的情况.

      function append_original_filter(input, env)
        local composition = env.engine.context.composition
        local segmentation = composition:toSegmentation()
        local schema = env.engine.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) == ";" 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
      

      在rime.lua中添加以上函数. 因为我这个方案挂载了easy_en的这个词库, 那么在临时英文中进行输入的时候, 如果输入的是一个新单词, 那么挂载词库中没有该新词, 备选中不会出现, 这样就无法使用空格键进行上屏, 因此添加这个函数在备选列表中增加了了一个与输入串完全一致的备选. 同时因为输入序列实际上是以分号开始的, 所以需要路过第一个位置, 也就是下面两行.

      elseif segmentation.input:sub(1, 1) == ";" then
        yield(Candidate("space", seg.start, seg._end, string.sub(segmentation.input, 2), ""))
      

      这两行, 这两行判断当输入的序列以分号开头(临时英文)的时候, 生成的候选把分号去掉.

    4. 修改return键为commit_composition

      editor:
      bindings:
          Return: commit_composition
      

      这个主要是为了让回车上屏的时候, 同样上屏正常, 不会把前置的分号输出出来.
      这样基本上就比较完美了.

    确实比较完美实现了临时英文,但是如果确实需要分号时怎么办呢?极点和qq五笔中印象中是如果需要分号了,就按两个分号,上屏一个分号。

    @redleafnew

    Copy link
    Copy Markdown
    engine:
      Processors:
    

    这里面的P应该小写。

    @gfgkmn

    gfgkmn commented Jan 22, 2024

    Copy link
    Copy Markdown
    engine:
      Processors:
    

    这里面的P应该小写。

    嗯, 这是个typo

    @redleafnew

    Copy link
    Copy Markdown

    @redleafnew 感谢反馈, 之前没有注意到, 对, 这里有一个bug. 修改了一下.

    把上面的rime.lua中的函数, 中间的做一个修改. 改为下面的函数.

    function append_original_filter(input, env)
        local composition = env.engine.context.composition
        local segmentation = composition:toSegmentation()
        local schema = env.engine.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

    这样就可以实现, 双击分号输入分号了.

    其它地方需要修改吗?好像不行啊,用原来的代码,我把\定义为分号了,也定义了自定义短语,zf输出为分号。

    2024_01_22-14_49_08

    @gfgkmn

    gfgkmn commented Jan 22, 2024

    Copy link
    Copy Markdown

    @redleafnew 具体不很确定, 看起来你的符号字义和我不一样, 我这边按下分号键, 就算不使用这一套字义, 应该也只有一个备选, 你这个还有个全角的备选在. 猜是因为这个.

    @redleafnew

    redleafnew commented Jan 22, 2024

    Copy link
    Copy Markdown

    哪个配置中可以看到吗?我基本上用得这个配置:https://github.com/KyleBing/rime-wubi86-jidian
    挂载的这个码表:https://github.com/GuoBinyong/wubixinshiji

    @gfgkmn

    gfgkmn commented Jan 22, 2024

    Copy link
    Copy Markdown

    我只用了jidian五笔的配置, 你查下. 应该是在default.custom.yaml中, 把分号相关的行注掉.

    就是这种 ";" : { commit: ";" }

    @redleafnew

    Copy link
    Copy Markdown

    2024_01_22-15_09_54
    倒是只出现一个了,但按两个没有上屏一个,而且也没有原来eassy_en中的词了。

    @gfgkmn

    gfgkmn commented Jan 22, 2024

    Copy link
    Copy Markdown

    我试了一下, 两个分号上屏我也没搞定, 应该有一个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

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

    @redleafnew

    redleafnew commented Jan 22, 2024

    Copy link
    Copy Markdown

    谢谢。我退回到以前的了,这样如果确实想输入分号就选2,临时英文就接着输入也不错。
    image

    另外

    schema_list:
        - schema: wubixinshiji
        - schema: easy_en  
    

    如果加载一次easy_en,后面如果有英文单词就会匹配,哪怕后面是再注释了,也可以。
    完美了。多谢。

    @gfgkmn

    gfgkmn commented Jan 22, 2024

    Copy link
    Copy Markdown

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

    @gfgkmn

    gfgkmn commented Jan 22, 2024

    Copy link
    Copy Markdown

    感谢反馈, 这样我也修复了一个自己使用的bug.

    @redleafnew

    Copy link
    Copy Markdown

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

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

    @gfgkmn

    gfgkmn commented Jan 22, 2024

    Copy link
    Copy Markdown

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

    参见上面的考虑.

    最后的模式组

    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
    Copy Markdown

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

    @YaoLiMuMu

    YaoLiMuMu commented Jan 23, 2024 via email

    Copy link
    Copy Markdown

    @redleafnew

    Copy link
    Copy Markdown

    修改return键为commit_composition

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

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

    @redleafnew

    Copy link
    Copy Markdown

    2024-03-23_16-28-48

    @zwjzxh520

    Copy link
    Copy Markdown

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

    @hoodlum1980

    hoodlum1980 commented Oct 10, 2024

    Copy link
    Copy Markdown

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

    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

    hoodlum1980 commented Oct 10, 2024

    Copy link
    Copy Markdown

    我试了一下, 两个分号上屏我也没搞定, 应该有一个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
    Copy Markdown
    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
    Copy Markdown

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

    @huo-feng-ding

    Copy link
    Copy Markdown

    输入带点的会重复,如输入 分号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
    Copy Markdown

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

    @redleafnew

    Copy link
    Copy Markdown

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