Open AlienKevin opened 2 years ago
报错含义就是 Engine 里面没有 apply_schema 方法。 大概因为 librime-lua 插件不是最新的?
感谢答复,我是今天用东风破安装的librime-lua,不确定东风破安装的是不是最新版?我手动检查了位于package/hchunhui/librime-lua/src/
的types.cc
文件,发现里面有apply_schema
的定义:
static void apply_schema(T *engine, the<Schema> &schema) {
engine->ApplySchema(schema.release());
}
用 engine:apply_schema( env.engine.schema) 很容易 出問題的 commit: 日 schema: cangjie5 / 倉頡五代 status: (not composing) {F9} double free or corruption (out) -- [1] 1065960 IOT instruction (core dumped) ./rime_api_console
查詢一下 isuue 有個 檢查 librime-lua 版本的function
Rime fcitx-rime 5.0.14 (id:f802202b-a976-4d1a-b171-7fba1e1d29f4) Ver: librime 1.7.3 librime-lua 185 lua Lua 5.4
我运行了检查版本的log,结果报错:
E0930 20:13:41.337082 44123520 lua_gears.cc:44] Lua error:(2): /Users/kevin/Library/Rime/lua/page_size_processor.lua:3: attempt to call a nil value (field 'get_distribution_name')
这是我的版本打印程序:
local function init(env)
log.info("===================== init page_size_processor =====================")
log.info(rime_api.get_distribution_name())
log.info(rime_api.get_distribution_version())
log.info(rime_api.get_distribution_code_name())
log.info(rime_api.get_user_id())
end
我使用的是macOS Monterey (M1),今天新装了squirrel的最新commit,会不会造成报错?我发现新版本的squirrel会在系统输入法那里注册简体和繁体两个选项。我可以试试删除新版本的squirrel然后在老版本从新测试。
我本机之前从来没有装过lua,不过这样能排除lua版本的问题吗?
Update: 我退到稳定版本的squirrel后有同样的版本报错。
把產生出來的 string 看是要作成 lua_translator 中的字典 或是 lua_processor 的 commit_text
-- processor
function proc.func(key,env)
......
if context.input == "/ver" or key:eq("EventKey('F12") ) then
context:clear()
env.engine:commit_text( ver func)
return Accepted -- 1
end
end
-- lua_translator
function tran.func(inp,seg,env)
if inp== "/ver" then
yield( Candidate("ver", seg.start, seg._end, Ver_info() , ""))
end
end
function Version()
local ver
if rime_api.get_distribution_name then
return 185
elseif LevelDb then
return 177
elseif Opencc then
return 147
elseif KeySequence and KeySequence().repr then
return 139
elseif ConfigMap and ConfigMap().keys then
return 127
elseif Projection then
return 102
elseif KeyEvent then
return 100
elseif Memory then
return 80
elseif rime_api.get_user_data_dir then
return 9
elseif log then
return 9
else
return 0
end
end
function Ver_info()
local msg1 = rime_api.get_user_id and string.format(" %s %s %s (id:%s) ",
rime_api.get_distribution_name(),
rime_api.get_distribution_code_name(),
rime_api.get_distribution_version(),
rime_api.get_user_id()) or ""
local msg2 = string.format(" Ver: librime %s librime-lua %s lua %s",
rime_api.get_rime_version() , Version() ,_VERSION )
return msg1 .. msg2
end
感谢🙏,我把你的script放到了rime.lua
里面,然后luna_pinyin.schema.yaml
里面加了两行调用processor和translator。
成功获取了版本号! Ver: librime 1.7.3 librime-lua 9 lua Lua 5.4
調換一下順序 ( proc tran 擇一即可 ) Version() Ver_info() -- call Version
module function -- call Ver_info() https://github.com/hchunhui/librime-lua/suites/8448091896/artifacts/374612908
问题1:这个是我改过之后的rime.lua
,我把Ver_info放到了Version前面。想确认一下调换顺序就是指把Version和Ver_info两个函数的位置调换吗?
rime.lua
问题2: 直接用你发的版本来代替Squirrel.app/Content里面的这三个executable就可以了吗?其他的executable会不会出现不兼容现象?
不曉得 , window 是這樣的 ,把 rime.dll 替換即可
Ok, 我查了下dylib在macOS和dll等同。我尝试用你的librime.1.dylib替换了我的,不过architecture不吻合,所以Squirrel报错:
Library not loaded: '@rpath/librime.1.dylib' ... mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e)))
有什么办法我可以自己build librime或者哪里可以找到arm版的build?
UPDATE: 我看到你发的版本里面librime是1.7.3,这和我之前用的版本一致,可能问题不在librime?
我从librime github release那里下载了librime 1.7.3然后放到了Squirrel里面,现在出现了新的报错:
E0930 22:54:10.376711 14419328 engine.cc:312] error creating processor: 'lua_processor'
E0930 22:54:10.377452 14419328 engine.cc:346] error creating translator: 'lua_translator'
我目前用的都是最新的 librime + librime-lua 其他 plugin bsd (osx) and linux 自行編譯應該蠻容易的
git clone https://github.com/rime/librime
cd librime
# clone to ./plugins/
./install-plugin.sh hchunhui/librime-lua
./install-plugins.sh rime/librime-charcode
./install-plugins.sh lotem/librime-octagram
./install-plugins.sh lotem/librime-proto
mkdir build && cd build
cmake .. && cmake --build .
我从librime github release那里下载了librime 1.7.3然后放到了Squirrel里面,现在出现了新的报错:
E0930 22:54:10.376711 14419328 engine.cc:312] error creating processor: 'lua_processor' E0930 22:54:10.377452 14419328 engine.cc:346] error creating translator: 'lua_translator'
沒有 plugins librime-lua
好的🙏,我大概明白了,一会儿试试看
终于build好了!Version输出185应该没问题了。不过env.engine.apply_schema(env.engine.schema.schema_id)
这一行直接把preedit里面的东西删了,然后候选字数没有变化,而且似乎还把我的squirrel factory reset了(皮肤和自己下载的输入法插件都没了)。我尝试重新sync user data然后deploy,但是任然无法将任何设置恢复,只有log out然后重新登录才能恢复。请问有什么安全有效的方法去改变menu/page_size?或者可以让translator不添加candidate,但是按空格仍然可以lookup词典输出正确的词。
我查了 librime source 關於 page_size 都是參照 sechema.page_size() 簡單的方式是 scheam.h 增加 set_page_size(int) & types.cc SchemaReg::vars_set[] 增加 page_size; 是 可行的且穩定 ,你`可以試試 https://github.com/rime/librime/pull/572 不知道這PR是否會通過
//librime/src/rime/schema.h
class Schema{
void set_page_size(int page_size) { page_size_ = page_size; }
}
//-----
//plugins/lua/src/types.cc
SchemaReg
luaL_Reg vars_set[]{
{"page_size" , WRAPMEM(T::set_page_size)}, // <<---- added
}
reload 自身方案 容易出現 memory 錯誤( engine:apply_schema( Schema) : 別的 方案OK )
这个方法好,我试试看
我fork了librime-lua然后加上了你上面提到的那一行到types.cc。之后,我用你的patch-1分支,plugin-install了我的fork版本的librime-lua,然后编译librime成功。不过,当我替换了Squirrel里面的librime.dylib
文件,并且重启Squirrel后,在启动时报错:
kevin@Kevins-MacBook-Pro T % /Library/Input\ Methods/Squirrel.app/Contents/MacOS/Squirrel --quit; /Library/Input\ Methods/Squirrel.app/Contents/MacOS/Squirrel
2022-10-01 22:17:09.876 Squirrel[90815:955332] Initializing la rime...
2022-10-01 22:17:09.883 Squirrel[90815:955332] Squirrel reporting!
2022-10-01 22:17:11.561 Squirrel[90815:955332] createSession: com.apple.Spotlight
2022-10-01 22:17:11.843 Squirrel[90815:955332] set app option: ascii_mode = 1
zsh: segmentation fault /Library/Input\ Methods/Squirrel.app/Contents/MacOS/Squirrel
当我切换回原先build的librime.dylib
,Squirrel又可以正常运行。
RimeSetPageSize 是給前端用的,應該不影響 我在 rime_api_console 運作正常 還有 page_size 設定 0 會錯誤 跳離app 預設是 5
明白了,那有什么办法可以隐藏候选字?
這邊有個思路,無奈功力不夠,lua 寫不出來 這邊韓文使用 2set 鍵位
放棄用express_editor,使用 fluency_editor,使得有半上屏狀態,會有完全隱藏候選項的時候, 再靠 lua 每打一個字母都 confirm 一次,只是這樣只有單音,還需修正XD
engine:
processors:
- fluency_editor
以下還待改善,目前只有單音,無法組字 思路是:如果可以把游標弄到起始位,再回復到末位,再 context:confirm_current_selection(),可能就可以組字?! shift+[QWERTOP] 目前也有問題 另外還須 if 去避掉快捷鍵等因素干擾
local function isintable(value,tb)
for k,v in pairs(tb) do
if v == value then
return true
end
end
return false
end
local function kr1_p(key, env)
local engine = env.engine
local context = engine.context
local arr = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"}
if (isintable(key:repr(),arr)) then
context.input = context.input .. key:repr()
key.keycode = 0
context:confirm_current_selection()
return 1 -- kAccepted
end
return 2 -- kNoop
end
這邊有個思路,無奈功力不夠,lua 寫不出來 這邊韓文使用 2set 鍵位
放棄用express_editor,使用 fluency_editor,使得有半上屏狀態,會有完全隱藏候選項的時候, 再靠 lua 每打一個字母都 confirm 一次,只是這樣只有單音,還需修正XD
engine: processors: - fluency_editor
以下還待改善,目前只有單音,無法組字 思路是:如果可以把游標弄到起始位,再回復到末位,再 context:confirm_current_selection(),可能就可以組字?! shift+[QWERTOP] 目前也有問題 另外還須 if 去避掉快捷鍵等因素干擾
local function isintable(value,tb) for k,v in pairs(tb) do if v == value then return true end end return false end local function kr1_p(key, env) local engine = env.engine local context = engine.context local arr = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"} if (isintable(key:repr(),arr)) then context.input = context.input .. key:repr() key.keycode = 0 context:confirm_current_selection() return 1 -- kAccepted end return 2 -- kNoop end
local set_char=Set {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"} --> {a=true,b=true...}
function proc.func(key,env)
local context = env.engine.context
if set_char[key:repr()] then
context.input:push( key:repr())
context:confirm_current_selection()
return 1
end
return 2
end
-- test
function test(func,msg, time)
local t1=os.clock()
for i=1,time do func() end
print(msg,os.clock() - t1)
end
function Set(tab)
local rtab = {}
for i,v in ipairs(tab) do rtab[v]=true end
return rtab
end
ktab={"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"}
key= Set(ktab)
function t1()
local tab = Set{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"}
return tab['p']
end
function t2()
return key['p']
end
function t3()
return ('p'):match('^[a-zQWERTOP]$') and true
end
function chk(chr, tab)
for i,v in ipairs(tab) do
if chr == v then return true end
end
end
function t4()
local ktab={"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"}
return chk('p', ktab)
end
function t5()
return chk('p',ktab)
end
n=10000
test(t1,'init Set in t1 func', n)
test(t2, 'init Set out of t2 func ', n)
test(t3, ' string.match ',n)
test(t4, ' loop chk, init arr in func' , n)
test(t5, ' loop chk init arr out of func' ,n )
init Set in t1 func 0.058258 init Set out of t2 func 0.00049999999999994 --- best string.match 0.001692 loop chk, init arr in func 0.014537 loop chk init arr out of func 0.0089570000000001
這邊有個思路,無奈功力不夠,lua 寫不出來 這邊韓文使用 2set 鍵位
放棄用express_editor,使用 fluency_editor,使得有半上屏狀態,會有完全隱藏候選項的時候, 再靠 lua 每打一個字母都 confirm 一次,只是這樣只有單音,還需修正XD
以下還待改善,目前只有單音,無法組字 思路是:如果可以把游標弄到起始位,再回復到末位,再 context:confirm_current_selection(),可能就可以組字?! shift+[QWERTOP] 目前也有問題 另外還須 if 去避掉快捷鍵等因素干擾
覺得象是 segment 的工作
@ shewer 感謝😄 好像是,沒碰過 librime-lua 的 segment 功能,感覺有得研究了!
我写了一个lua translator可以不用词典转换韩文,不过问题是我要把转换好的结果加到一个Candidate里面,所以输入的时候一直会有一个候选字在底下。如果不是完美主义的话问题不大。
韩文我是基于rime-hangyl做的,用的是HNC Romaja,加了一点小改动:f键aliased to ᆼ,double consonant只支持大写字母,如G -> ᆩ,不支持gg。
只有一個候選項,之前這邊是用 filter 過濾
context.input:push( key:repr()) 我這邊不知哪邊搞錯,無效且影響後面的 context:confirm_current_selection() 這幾天再繼續研究
怎麼不用Projection 呢
有點感覺 , commit preedit 就可以 不用candidate
translator 加上 opencc 韓文-->漢語 如果有產生candidate
function init(env)
local config= env.engine.schema.config
lacal pat=config:get_list("hnc_hanja_mod/preedit_format")
env.pp= Projection()
env.pp:load(pat)
end
function func(inp,seg,env)
local text = env.pp:apply(inp) -- ascii 輸出 韓文
...
end
只有一個候選項,之前這邊是用 filter 過濾
context.input:push( key:repr()) 我這邊不知哪邊搞錯,無效且影響後面的 context:confirm_current_selection() 這幾天再繼續研究
我對 https://github.com/hchunhui/librime-lua/blob/01c61b1d12ff5fb31711b150ad075422e1d7106d/src/types.cc#L52-L60 不了解 , 形碼很少 處理 segment
confirm_current_selection() 是上一次的 ,當 processor accepted 後 又再一次 compose() 如果 input 變更 大有機會 會影響 candidates 排序
試出來了!🥳 [a-z]+可以視覺上等同 menu (page_size = 0),零選項 BackSpace 可返回有選單項狀態 如果要直接刪字 shift + BackSpace fluency_editor 因素,數字標點等無法直接上屏,用 commit 解決
ps: 再修改增韓文 2set 會用到的 Shift+[QWERTOP]
engine:
processors:
- fluency_editor
local set_char = Set {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" } --> {a=true,b=true...}
local function proc.func(key,env)
local engine = env.engine
local context = engine.context
local ascii_m = context:get_option("ascii_mode")
local function check_qwertop()
if key:eq(KeyEvent("Shift+Q")) then
return true
elseif key:eq(KeyEvent("Shift+W")) then
return true
elseif key:eq(KeyEvent("Shift+E")) then
return true
elseif key:eq(KeyEvent("Shift+R")) then
return true
elseif key:eq(KeyEvent("Shift+T")) then
return true
elseif key:eq(KeyEvent("Shift+O")) then
return true
elseif key:eq(KeyEvent("Shift+P")) then
return true
else
return false
end
end
local check_prefix = string.find(context.input, '=[a-z]*$') --使反查鍵可展示全部選項
if (not ascii_m) and set_char[key:repr()] and (not check_prefix) or (not ascii_m) and check_qwertop() and (not check_prefix) then
local addend = string.gsub(key:repr(), 'Shift%+', '')
context:reopen_previous_segment()
context.input = context.input .. addend
context:confirm_current_selection()
return 1
end
return 2
end
試出來了!partying_face [a-z]+可以視覺上等同 menu (page_size = 0),零選項 BackSpace 可返回有選單項狀態 如果要直接刪字 shift + BackSpace fluency_editor 因素,數字標點等無法直接上屏,用 commit 解決
engine: processors: - fluency_editor
~~local function Set(tab) local rtab = {} for i,v in ipairs(tab) do rtab[v]=true end return rtab end~~ Set + Set Set * Set Set -Set
a=Set{'a','b','c'} b=Set{'c','d','e'} a - b --> {'a','b'} a * b --> {'c'} a + b --> { 'a','b','c','d','e'}
-- librime-lua 內含 Set local set_char = Set {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"} --> {a=true,b=true...} local function proc.func(key,env) local engine = env.engine local context = engine.context local ascii_m = context:get_option("ascii_mode") if set_char[key:repr()] and (not ascii_m) then -- key:repr() match[a-z QWERTOP] local addend = key:repr():match("^[a-z]$") or '' -- if (not addend_c) then -- 不是很懂 這段 (QWERTOP] append = "" ; return ? -- addend='' -- return 2 --- must be return 0-2 -- end context:reopen_previous_segment() context.input = context.input .. addend context:confirm_current_selection() return 1 end return 2 end
弄得差不多了,可以 page_size = 0 零選項了
由於韓文(諺文)2set 較單一,故沒有選字和排序問題, 但套用到拼音或是韓文對映漢字,也可以, 但展開選單後,左右切分再選字會有操作上瑕疵, 須不使用切分,從第一個字(或已有的詞)逐步選。 且選好後必須完全上屏, 否則後續鍵入會改變前面已選過字彙。
以下效果
local set_char = Set {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" , "Q", "W", "E", "R", "T" ,"O" ,"P"}
local function proc.func(key,env)
local engine = env.engine
local context = engine.context
-- pass release ctrl alt super
if key:release() or key:ctrl() or key:alt() or key:super() then
return 2
end
-- pass ascii_mode check_prefix
if context:get_option('ascii_mode') then return 2 end
if context.find('=[a-z*$') then return 2 end --使反查鍵可展示全部選項
-- accpted ascii as set_char
local ascii = string.char(key.keycode)
if set_char[ascii] hen
context:reopen_previous_segment()
context.input = context.input .. ascii
context:confirm_current_selection()
return 1
end
return 2
end
這是我截下的keyevent
Shift_L --> Shift+T --> Shift+Release+T --> Shift+Release+Shift_L
t --> Release+t
a --> Release+a
g --> Release+g
Shift_L --> Shift+H --> Shift+Release+H --> Shift+Release+Shift_L
Shift_L --> Shift+H --> Shift+Release+H --> Shift+Release+Shift_L
一般 rime 是小寫輸入 ,大寫時 按Shift 字母 relelease....
從此邏輯看 只要不是 alt super ctrl releace 可以不用理會 Shift+H
取出 keycode 就是目標 ascii 了
參照 librime soruce 有許多 事前預處理 release() ctrl) alt() ...
如果要收 ascii key 會排除 release() ctrl super alt 即可
processor function 只要區分 功能鍵 或是 可見 ascii 一般鍵 兩種鍵分開處理
只有一個候選項,之前這邊是用 filter 過濾
context.input:push( key:repr()) 我這邊不知哪邊搞錯,無效且影響後面的 context:confirm_current_selection() 這幾天再繼續研究
my bad
context:push_input( string)
好精簡的寫法呀!🤩👍🏻 真厲害! 理解並掛載實測了一番,good!
E20221005 18:04:41.625133 440163776 lua_gears.cc:193] LuaProcessor::ProcessKeyEvent of kr_2set_0m_choice error(2): ../Library/Rime/lua/processor_kr_2set_0m_choice.lua:54: bad argument #1 to 'char' (value out of range)
功能都正常,但打字中會不斷報錯: 'char' (value out of range) 好似是 string.char(key.keycode) 出問題 怎樣的寫法可避免超出範圍? 這邊有限的功力,只想到 if 判斷 XD 還是換回舊寫法?
string.char range 0~255 1byte 可能是有些 KEY 沒㯗下吧 在 string.char( key.keycode ) 前 插入
if 又沒見不得人 ,只是覺得怪 ,還有什麼KEY 沒㯗下的
if key.keycode >255 then
log.error( key:repr() , key.keycode , key.modifier )
return 2
end
-- return char(0x20~0x7f) or ""
local function ascii(key,pat)
local pat = pat and ('^[%s]$'):format(pat) or "^.$"
local code = key.keycode
return key.modifier <=1 and
code >=0x20 and code <=0x7f and
string.char(code):match(pat) or ""
end
ascii(key, 'a-zQWERTOP')
@ shewer 感謝!
我在开发一个韩文输入法,目标是平常输入韩文的时候不显示menu (page_size = 0),menu只在反查汉字的时候显示。基于PR135,我写了一个简单版本的processor,当按下F10键时会改变朙月拼音的page_size。不过
env.engine.apply_schema
报错说attempt to call a nil value (field 'apply_schema'),env.engine:apply_schema
也有类似报错。报错message:
processor代码如下:
版本
squirrel master branch最新commit