Open Axure opened 8 years ago
顶一个,我也想了解。 @lotem @Prcuvu 求指教
现在都说什么大数据,机器学习 希望Rime可以像添雨跟打器一样,五笔,打字速度,统计平均码长,回退键次数。 还有QQ五笔,可以统计哪些词组词库里有,但是输入时单字输入
还可以看看这个 个人大数据时代的到来 - 简书
第一步是確定需求吧。有一些是可以從用戶詞典裏挖掘的,但是想要更多信息和更精細的控制,肯定要切入到輸入法引擎的內部。
Engine
大致就是所謂「輸入法引擎」。處理按鍵導致一系列內部狀態更新的事件,引擎監聽這些事件並完成相應的動作,如輸入碼變化則重新轉換,又如選詞、上屏、輸入法開關狀態變化等。
https://github.com/rime/librime/blob/develop/src/engine.cc#L71
需要寫一個用作統計的組件,在 Engine
加載時預先加載爲 processor
,但他並不響應任何按鍵,只是監聽以上各種事件,完成統計。
https://github.com/rime/librime/blob/develop/src/engine.cc#L287
現在 librime 公開的 API 並沒有暴露很多內部的實現。雖然支持寫插件(以動態鏈接庫形式提供新的組件定義),但尚不能暗中把某個輸入方案中未指明的組件注入到引擎,所以要動一動源碼。
谢谢@lotem 大大。还要您现场讲解代码。 等我把环境配好了,有问题再向您请教吧。
看起来忘记这茬子事了😅
其实这个功能做成一个单独的软件就足够了呀。不需要集成在软件里面。不过我纳闷的是为什么没有单独的这样的软件。令人感到很奇怪。
@ddkk3000 其实这个功能做成一个单独的软件就足够了呀。不需要集成在软件里面。不过我纳闷的是为什么没有单独的这样的软件。令人感到很奇怪。
因为涉及到隐私问题,独立软件如果不开源往往不值得信赖;而输入统计,我个人认为最合适的地方就是在输入法本身这一层来做。
七年过去了,这个议题好像还是没有动静,很希望能有这个功能模块(插件) 🥲
抛砖引玉,试用 Lua processor 做了一个 非常粗糙的 初步的实现,只能用来感受一下粗略的打字速度。因为没处理 Backspace,实际上会高估速度。
遗憾的是因为 os.time() 的精度只能到秒,所以不能在每个 key event 时进行统计,不然时间可能会被统计成 0。
目前做法是在每次 commit 时,把 commit 的字符数量和时间戳一并保存到一个全局列表中:
local Queue = {}
function Queue.new()
local ret = {first=1, last=0}
ret.CountCharsWithinSecs = function(self, secs)
local ret = 0
local now = os.time()
for _, entry in Queue.iter(self) do
if os.difftime(now, entry[1]) <= secs then
ret = ret + entry[2]
end
end
return ret
end
return ret
end
function Queue.push(q, value)
q[q.last+1] = value
q.last = q.last + 1
end
function Queue.empty(q)
return q.last < q.first
end
function Queue.len(q)
return q.last - q.first + 1
end
function Queue.pop(q)
if q.last < q.first then
return nil
else
local ret = q[q.first]
q[q.first] = nil
q.first = q.first + 1
return ret
end
end
function Queue.top(q)
if Queue.empty(q) then
return nil
else
return q[q.first]
end
end
function Queue.next(q, i)
if i <= q.last then
return i+1, q[i]
else
return nil
end
end
function Queue.iter(q)
return Queue.next, q, q.first
end
local Module = {}
global_stats = Queue.new()
function Module.init(env)
global_stats = Queue.new()
local function on_commit(ctx)
local commit_text = ctx:get_commit_text()
local now = os.time()
-- prune old entries.
while not Queue.empty(global_stats) and os.difftime(now, Queue.top(global_stats)[1]) > 3600 do
Queue.pop(global_stats)
end
if Queue.empty(global_stats) then
-- mitigate overflows.
global_stats = Queue.new()
end
Queue.push(global_stats, { now, utf8.len(commit_text) })
end
env.stat_commit_notifier = env.engine.context.commit_notifier:connect(on_commit, 0)
end
function Module.fini(env)
env.stat_commit_notifier:disconnect()
end
function Module.func(event, env)
return 2 -- kNoop
end
return Module
(使用了 connect
的 group 参数,依赖于该PR: https://github.com/hchunhui/librime-lua/pull/271 )
这个 processor 须放在 processor 列表较开头的位置。
在 translator 中,可以利用该 processor 记录的信息计算一段时间内的打字速度:
if global_stats and (input == "osd") then
yield(Candidate("stat", seg.start, seg._end, tostring(global_stats:CountCharsWithinSecs(60)) .. '字/min', '1分鐘'))
return
end
@ksqsf 最新版的鼠须管(0.16.2),似乎还不支持这个group参数?
@ksqsf 最新版的鼠须管(0.16.2),似乎还不支持这个group参数?
是的,需要自己编译。
24 年底了,不知道还会不会做这个功能,输入统计,我有时想看今天打了多少字,rime 累计打了多少字,打字速度等。
如果我要进行这方面的开发,应该从哪里入手呢?