Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[求助] 如何通过lua_processor插件发送退格键 #284

Open
Lantaio opened this issue Oct 22, 2023 · 8 comments
Open

[求助] 如何通过lua_processor插件发送退格键 #284

Lantaio opened this issue Oct 22, 2023 · 8 comments

Comments

@Lantaio
Copy link

Lantaio commented Oct 22, 2023

这两天学习了一下这个仓库的示例,折腾出下面这个放在Processor组件的函数。虽然输出和没有执行这个函数一样(也就是没有达到预期效果),但感觉离真理越来越接近了,还请各位大神帮忙看看问题出在哪里?想实现的功能是当满足条件时就发送一个退格键。函数代码如下:

local function del_period(key, env)
  local context = env.engine.context
  local history = context.commit_history
  -- 当按键是英文句号 并且 没有候选框 并且 最近上屏的文本是英文句号时
  if (key:repr() == 'period') and (not context:has_menu()) and (history:latest_text() == '.') then
    key_bs = KeyEvent('BackSpace')  -- BackSpace / \b
    p_bs = Component.Processor(env.engine, "", "express_editor"):process_key_event(key_bs)  -- ascii_composer / express_editor
  end
  return 2 -- kNoop
end
return del_period

if条件已经测试过应该是没有问题的,问题出在if语句体内。
这里有几个疑问:
1是Processor不是Component的方法吗?如果是方法的话,为什么是用'.'连接而不是用':'连接?不过我2种都试过,都不行。
2是KeyEvent里面的参数是'BackSpace'吗?我试过用'\b'也不行。
3是Processor方法的第3个参数可以用"ascii_composer"吗?还是要用"express_editor"来处理退格键?我的理解是"ascii_composer"处方也可以处理退格键的,我就当作是在英文模式下输入1个退格键,是由这个处方来处理的吧?不过也是2种都试过,都不行。
4是Component前面还有没有父对象?就好比如engine前面还有env
综上所述,还请各位大神帮忙看看问题出在哪里?感觉这个方向是对头的啊。求 @shewer @hchunhui 大神指点迷津,折腾了2个通宵了。
对了,Lua好像是大小写敏感的。那如果我的代码里面有大小写错误的问题,也请大神指出我的错误,感激不尽!

@Lantaio Lantaio changed the title [求助] 如何发送退格键? [求助] 如何在lua_processor插件发送退格键? Oct 22, 2023
@Lantaio Lantaio changed the title [求助] 如何在lua_processor插件发送退格键? [求助] 如何通过lua_processor插件发送退格键 Oct 23, 2023
@shewer
Copy link
Contributor

shewer commented Oct 23, 2023

你可以 搜一下 issue : commit_text ,查看歷史記錄
commit or commit_text 都是傳送 text 給前端, 沒有方法可以
只能試試 active app 是不能夠接受 多少 ascii 的控制碼 如terminal 可以用 ansi , xterm ....

Component 下的物件 只是提供 lua_component 委任 已經有 的功能 減少codeing 還有不好做的功能
建議 查看 rime wiki 和 librime source

librime engine 工作程序 key --> processors --> accepted --> Compose()

// Engine::Compose()
     segmentors  translators -- 產生  segmets
     for ( segment : segments) 
            translation  = translator (     ... segment) 
            for ( filter : filters) 
                 translation =  filter( translation) 
            end
     end

https://github.com/rime/librime/blob/bc589fd45eca349b7ca408f9b85a85474745abb0/src/rime/engine.cc#L198

@Lantaio
Copy link
Author

Lantaio commented Oct 23, 2023

@shewer 大神你好。你的意思是我在if语句体里面的思路或者说写法是不对的?但我是参考你放在这个仓库的component_test.lua示例代码而想到的啊。你的示例是用for循环去让按键事件遍历全部的Processor处方。莫非按键事件是不能在程序里面创建出来的?还是说我的创建方式不对?
至于你说的segmentor、translator和filter这些,因为我只是处理1个退格键,所以按我的理解是不需要这些后续处理的,我看了rime wiki的理解是,这个按键在processor阶段已经上屏并结束1个分析流程了。segmentor和translator这些只有在处理像拼音这种有候选框的输入情况时才会用到吧?不知道这样理解对不对。比如说如果按Shift键切换到英文模式的时候,这时按英文字母按键会由processor组件的第1个处方ascii_composer来处理并上屏,然后就结束分析流程了,不会往下走segmentor处理和translator处理,甚至连后面的processor处方都不会走了。
不过我刚测试过,将退格键改为一个小写英文字母,然后改为让ascii_composer去处理这个按键事件,也不行,没有得到预期的效果。那估计我这样写是不行的了。至于你说的commit_text已经试过,不理想,commit是上屏候选词用的,连参数都没有,更加不适用。我再搜索一下看看有没有新发现吧,多谢大神。

@shewer
Copy link
Contributor

shewer commented Oct 23, 2023

因爲做不到, 這 個方案 只能 用 "\b" 着手

if   not  context:is_composing() and key:repo() == "...."  then
     comment_text("\b")
     return accepted
end 

a -> engine --> lua_processor()
key = b -- 這個 b 只有作用在 sub_processor 中
sub_processor:processor_keyevent(key) -- b
return ?
end
前端的key 還是 a
processor noop 不理 accept 收下 reject 拒收
engine 在等 lua_processor 的return 而不是 sub_processor 的 結果

noop : a 往下個processor 送
accept : 處理 context ( push_input .....)
reject: 拒收 終止 前端 不 處理 a 直送 a 到 active app

@hchunhui
Copy link
Owner

指望通过 librime 发送按键是做不到的。按照架构分工 librime 只负责把按键翻译为一个字符串。至于翻译为 "\b",应用程序是否会理解为退格,这是无法保证的事。现有框架下只有看输入法前端部分或者什么外部工具是否提供接口让你发送退格。

@Lantaio
Copy link
Author

Lantaio commented Oct 23, 2023

感谢 @shewer 大神进一步的解释说明。你所说的处理原理和流程虽然我之前略懂,不过经你这么一说,觉得自己之前自己的考虑太片面了。我之前总是一心想着能发送退格键给Rime处理就行了,并不关心返回值是什么。现在觉得还是要仔细了解Rime的处理流程和原理。之前的理解是Rime应该在某个processor处理退格键,并返回kRejected不作处理让系统按默认方式处理退格键。现在想想即便是这样返回,正如你所说可能也只是返回到a这一层,没有最终退出处理来将退格键交给系统处理。而后面继续处理a的时候b已经丢失了。这样确实很棘手。

@Lantaio
Copy link
Author

Lantaio commented Oct 23, 2023

如果真如 @hchunhui 大神所说的话,那我想实现的功能就死翘翘了。本来还冒出个想法看看能否直接将key替换为退格键的,但又想到key参数好像是作为常量定义的,那就又碰壁了。

@Lantaio Lantaio closed this as not planned Won't fix, can't repro, duplicate, stale Oct 27, 2023
@Lantaio Lantaio reopened this Mar 9, 2024
@Lantaio
Copy link
Author

Lantaio commented Mar 9, 2024

最近想实现一些功能,还是得先实现发送退格键这个功能才行。虽然上面 @hchunhui 大神说的librime工作原理可能是这样,但好像也不尽然是这样,不是可以通过commit_text向系统发送任意数量的字符吗?所以说不仅仅是对按键做翻译工作啊。另外我还看到有个env.engine.process_key(keycode)方法,虽然之前折腾不成功,不过感觉有可能通过它来实现发送退格键的功能。
虽然我现在也在寻求AutoHotkey或者nircmd这些第三方工具来实现这个功能,但一来还没有折腾出来,二来就算折腾出来了,在发送退格键的时候也可能会有个黑色的cmd窗口闪一下,既不美观,也浪费系统资源。
我看看能否请 @lotem 大神解决这个问题,我还大神一个更懂大神的输入法!😁

@Lantaio
Copy link
Author

Lantaio commented May 10, 2024

最近2个月折腾AutoHotkey,给我折腾出想要实现的功能了,而且貌似比单用Rime来实现更好。所以不麻烦 @lotem 大神来折腾这个功能了。迟些等项目完成得差不多,开源的时候再告诉大家。再次感谢各位大神热心相助🤝

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants