Skip to content

Instantly share code, notes, and snippets.

@lotem
Created July 9, 2012 12:23
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • 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 規則,識別包含 @ 字符的郵箱,於是可以一氣呵成 rime123@company.com
# 第二例,輸入到 rimeime 時,立即識別爲西文輸入,並可跟隨任意位數字及指定的符號
patch:
recognizer/patterns/rime123: "^rime[0-9]+$"
recognizer/patterns/rimeime: "^rimeime[-_.0-9]*$"
@lanyun712
Copy link

lanyun712 commented Nov 22, 2020

楼上正解,完美解决了我用分号临时输入英文的需求,多谢,这里再简单说下
我用的是超强快码,也是形码,按楼上的改成分号:

patch:    
  "recognizer/patterns/veng": "^;.*$"
  "engine/segmentors/@before last": affix_segmentor@veng
  veng:
    tag: veng
    prefix: ";"
    tips: "英语输入"

然后在default.yaml和cqkm.schema.yaml这两个文件里把 ";": {commit: ";"}这行删除,每个文件里都有两行,都删除,再重新部署,大功告成!(五笔的话应该是wb.schema.yaml这个文件名吧,不知道,没用过五笔)

另外在fcitx5里附加组件设置里有个“快速输入”,可设置快捷键,也可以达到效果,但没这个分号爽

再次感谢!

@wzyboy
Copy link

wzyboy commented Dec 12, 2020

@jackielii @lanyun712 感谢两位的帮助!我试了一下两位的配置,分号引导临时英文的情况下依然不能输入空格,一旦输入空格就会上屏。请问是这样的吗?

@hicaicai
Copy link

hicaicai commented Sep 25, 2021

@jackielii @lanyun712 感谢两位的帮助!我试了一下两位的配置,分号引导临时英文的情况下依然不能输入空格,一旦输入空格就会上屏。请问是这样的吗?
是的,不知道有没有解决办法

@jiapeng123456
Copy link

@jackielii @lanyun712 我试了一,当我输入“;abc”时,分号也跟着一起上屏了。请问一下,上面的设置脚本的效果就是这样的吗?怎么能让分号不上屏,只是后面输入的英文上屏呢?

@YaoLiMuMu
Copy link

@lanyun712 你想直接使用分号的时候不会很麻烦吗?

@Igotit
Copy link

Igotit commented May 30, 2023

从「极点五笔」到 Fcitx,我一直习惯于用分号引导临时英文,不用按 Shift 来回切。最近正在切换到 Rime,标点等其他全部配成和原有习惯一致了,唯分号引导临时英文未能实现。看到 @lgotit 这 2012 年的留言,感慨万千……

@wzyboy 因为最新回复产生的邮件提醒,突然又看到了这条11年前的讨论。话说于是后来我就开发了「清歌输入法」。

@jackielii
Copy link

@wzyboy @hicaicai @jiapeng123456 哇,这时好久之前弄的了,说实话,我记得但是用了一段时间也没在用了。应该是在不同程序切换的时候还是没有办法达到我理想的效果。

我只记得我当时是看了部分代码,然后按照最基础的yaml一一试它们的功能,最后弄出来这个方案。如果想追求极致的话可以试试这个方向。

再后来我发现其实只是我只是有时候需要中文英文一起输,切换下就可以了。

再后来我有切换到了Mac,以前的配置也不用了, 直接用的雾凇拼音。 也懒得自己捣鼓了。

@rightester
Copy link

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

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

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

@jsonsuxing
Copy link

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

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

qhjia commented Nov 8, 2023

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

@qhjia
Copy link

qhjia commented Nov 8, 2023

@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
Copy link

gfgkmn commented Jan 4, 2024

前一段时间折腾了一下这个功能, 除了英文输入下因为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

前一段时间折腾了一下这个功能, 除了英文输入下因为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

engine:
  Processors:

这里面的P应该小写。

@gfgkmn
Copy link

gfgkmn commented Jan 22, 2024

engine:
  Processors:

这里面的P应该小写。

嗯, 这是个typo

@redleafnew
Copy link

@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
Copy link

gfgkmn commented Jan 22, 2024

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

@redleafnew
Copy link

redleafnew commented Jan 22, 2024

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

@gfgkmn
Copy link

gfgkmn commented Jan 22, 2024

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

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

@redleafnew
Copy link

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

@gfgkmn
Copy link

gfgkmn commented Jan 22, 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

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

@redleafnew
Copy link

redleafnew commented Jan 22, 2024

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

另外

schema_list:
    - schema: wubixinshiji
    - schema: easy_en  

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

@gfgkmn
Copy link

gfgkmn commented Jan 22, 2024

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

@gfgkmn
Copy link

gfgkmn commented Jan 22, 2024

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

@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

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