hchunhui / librime-lua

Extending RIME with Lua scripts
BSD 3-Clause "New" or "Revised" License
310 stars 43 forks source link

能否做到删除任意词库中任意词组 #93

Open blackhole889 opened 3 years ago

blackhole889 commented 3 years ago

rime是一个很好的输入法程序,但也存在一些较大的不足。其中一个就是词库的建立和精选。 提高词库的效率有两个两个方法,我需要的在里面,我不需要的不在里面。只关注其一,如加大词库数量无法提高词库的效率。 现在rime似乎无法删除一些已有词库里的词(其宣称的ctr+del,shift+del,ctr+k可以删除自造词,无法删除一些词库里的词,甚止降低已有词库权重也难以做到。降低已有词库权重偶而可以做到,很不稳定)。有些词一般用户用不到,如果从词库删除可以加大输入效率。能否对原有程序进行修改,使得可以删除任意词库中任意词组。

shewer commented 3 years ago

詞庫早在 deploy 時 就寫入 table.bin prism.bin reverse.bin 所以 要減少詞庫量 是不容易的 建議 還是 手動刪除詞庫 lua_process 可以協助把不要的詞存入檔方便刪詞

用 librime-lua 只是可以動態排除不要的詞組 0 建立 filter_table ( 從檔案 讀取)
1 lua_processor 建立 keyevent
將刪除項寫入 檔案 且 push filter_table 2 lua_filter 排除 filter_table

blackhole889 commented 3 years ago

感谢回复。能否给出所有文件,我试试。如果暂时可以这样解决也算不错。拼音加加可以删除词组,不清楚是什么原理。

shewer commented 3 years ago

我只在 rime_api_console 測試 OK -- 使用方式 當目錄出現時 選擇刪除字 按下 C-Del

如果是 window os , init.lua load_word append_word function 內的 filename 要修正 local filename= path .. "/" .. "rm_word.txt" <--- "/" 改 "\"

  1. new $user_dir/lua/remove_dict/rm_dict.txt 新增一個檔案 刪除字會加入到此檔 , 無此檔時會新增 空檔

  2. create $user_dict/lua/remove_dict/init.lua

  3. modify $user_dict/rime.lua local rmdict= require("remove_dict")() rm_word_processor=rmdict.processor rm_word_filter=rmdict.filter

  4. modify $user_dict/ .....schema.yaml engine/processors/lua_processor@rm_word_processor engine/filter/lua_filter@rm_word_filter

--  user_dir/lual/remove_dict/init.lua
#! /usr/bin/env lua
--
-- main_init.lua
-- Copyright (C) 2020 Shewer Lu <shewer@gmail.com>
--
-- Distributed under terms of the MIT license.
--
--------------------------------------------

--  lua_init(argv) argv 自定義
--local Notifier=require ('tools/notifier') -- 建立 notifier obj   減化 notifier connect and disconnect() 
-- 取得 librime 狀態 tab { always=true ....}

local function append_word(word)
    local path=string.gsub(debug.getinfo(1).source,"^@(.+/)[^/]+$", "%1")
    local filename= path .. "/" .. "rm_word.txt"
    local fn=io.open(filename,"a+")
    fn:write( word .. "\n")
    fn:close()

end 

local function load_word()

    local path=string.gsub(debug.getinfo(1).source,"^@(.+/)[^/]+$", "%1")
    local filename= path .. "/" .. "rm_word.txt"
    local fn= io.open(filename, "r") or io.open(filename,"w+")
    local tab={}
        for word in fn:lines() do
        tab[word] =true
    end
         fn:close() 
    return tab
end 

local function status(ctx)
    local stat=metatable()
    local comp= ctx.composition
    stat.always=true
    stat.composing= ctx:is_composing()
    stat.empty= not stat.composing
    stat.has_menu= ctx:has_menu()
    stat.paging= not comp:empty() and comp:back():has_tag("paging")
    return stat
end
local function lua_init(...)

    local args={...} 
    rm_tab= load_word() 

    local function processor_func(key,env) -- key:KeyEvent,env_
        local Rejected, Accepted, Noop = 0,1,2 
        local engine=env.engine
        local context=engine.context
        local s= status(context) 

        if s.empty then end 
        if s.always then end 
        if s.has_menu then
            if key:repr() == "Control+Delete" then 
                local cand=context:get_selected_candidate()
                rm_tab[cand.text]=true
                append_word(cand.text) 
                context:refresh_non_confirmed_composition()
                return Accepted
            end 

        end 
        if s.composing then end 
        if s.paging then end 

        return Noop  
    end 

    local function processor_init_func(env)
        env.connect=Notifier(env) -- 提供 7種notifier commit update select delete option_update property_update unhandle_key
        --env.connect:commit( func)
        --env.connect:update( func)

    end 

    local function processor_fini_func(env) 
        env.connect:disconnect() -- 將所有 connection  disconnect() 
    end 

    -- segmentor 
    local function segmentor_func(segs ,env) -- segmetation:Segmentation,env_

    -- 終止 後面 segmentor   打tag  
    -- return  true next segmentor check
        return true 
    end 
    local function segmentor_init_func(env)
    end 
    local function segmentor_fini_func(env)
    end 

    -- translator 
    local function translator_func(input,seg,env)  -- input:string, seg:Segment, env_

        -- yield( Candidate( type , seg.start,seg._end, data , comment )
    end 
    local function translator_init_func(env)
    end 
    local function translator_fini_func(env)
    end 

    --- filter  
    local function filter_func(input,seg,env)   -- pass filter 
        for cand in input:iter() do 
            if not rm_tab[cand.text] then 
                yield(cand)
            end 
        end 
    end 
    local function filter_init_func(env)
    end 
    local function filter_fini_func(env)
    end 

    local _tab= { 
        processor= { func=processor_func, init=processor_init_func, fini=processor_fini_func} , 
        --segmentor= { func= segmentor_func, init=segmentor_init_func , fini=segmentor_fini_func} , 
        --translator={ func=translator_func, init=translator_init_func,fini=translator_fini_func} , 
        filter=    { func=filter_func, init=filter_init_func,    fini=filter_fini_func } ,   
        --filter1=    { func=filter_func1, init=filter_init_func1,    fini=filter_fini_func1 } ,   
    }
    return _tab
end 

return lua_init    
shewer commented 3 years ago

另一版本 ,使用 delete_notifier 可以隔離 rm_tab 只在filter env環境內.


function procesor_func(key,env)
      -- .....
       if s.has_menu then 
            if key:repr() =="Control+Delete" then 
                    context:delete_current_selection()
                     return Accepted
              end
        end
         -- .......
end

local function filter_func(input,env)
    for cand in input:iter() do
       if not env.rm_tab[ cand.text ]  then
                yield(cand)
        end
      end
end
local function filter_init_func(env)
     env.rm_tab=load_word()
     env.connection= env.engine.context.delete_notifier:connect( function (ctx)
           local word= ctx:get_selected_candidate().text
           env.rm_tab[word] = true
           append_word(word)
           ctx:refresh_non_confirmed_composition()
       end )
end
local function filter_fini_func(env)
         env.rm_tab=nil
         env.connection:disconnect()
end
blackhole889 commented 3 years ago

非常感谢您的帮助,我试试看。这个功能很重要,很多输入法都有删除功能,不清楚rime为什么没有。

blackhole889 commented 3 years ago

试了代码,没有成功。rm_dict.txt 新增一個檔案,程序里是local filename= path .. "/" .. "rm_word.txt"。这两个txt文件名称不一样,有问题吗?另外 local _tab= { processor= { func=processor_func, init=processor_init_func, fini=processor_fini_func} , --segmentor= { func= segmentor_func, init=segmentor_init_func , fini=segmentor_fini_func} , --translator={ func=translator_func, init=translator_init_func,fini=translator_fini_func} , filter= { func=filter_func, init=filter_init_func, fini=filter_fini_func } ,
--filter1= { func=filter_func1, init=filter_init_func1, fini=filter_fini_func1 } ,
}

}上一行结尾是“,”,这样语法正确吗?

qq420100523 commented 1 year ago

另一版本 ,使用 delete_notifier 可以隔離 rm_tab 只在filter env環境內.

function procesor_func(key,env)
      -- .....
       if s.has_menu then 
            if key:repr() =="Control+Delete" then 
                    context:delete_current_selection()
                     return Accepted
              end
        end
         -- .......
end

local function filter_func(input,env)
    for cand in input:iter() do
       if not env.rm_tab[ cand.text ]  then
                yield(cand)
        end
      end
end
local function filter_init_func(env)
     env.rm_tab=load_word()
     env.connection= env.engine.context.delete_notifier:connect( function (ctx)
           local word= ctx:get_selected_candidate().text
           env.rm_tab[word] = true
           append_word(word)
           ctx:refresh_non_confirmed_composition()
       end )
end
local function filter_fini_func(env)
         env.rm_tab=nil
         env.connection:disconnect()
end

您提供的第一种写法无效,第二种写法存在一个bug:当触发Control+Delete后,会自动刷新候选栏,然后在filter_init_func方法里get_selected_candidate()得到的总是默认第一个候选词,结果删除的总是第一个候选词。

shewer commented 1 year ago

發現 delete_notifier 刪詞(user_dict) connect 先於 filter 所以會有種錯誤 editor/delete_candidate 是屬於 processor : [express_editor|fluid_editor|chor_composer] lua_processor 可能還是要在前面截下才行

qq420100523 commented 1 year ago

發現 delete_notifier 刪詞(user_dict) connect 先於 filter 所以會有種錯誤 editor/delete_candidate 是屬於 processor : [express_editor|fluid_editor|chor_composer] lua_processor 可能還是要在前面截下才行

我发现第二种写法,即filter方法,可以不需要processor(我用第二种写法,再注释了lua_processor,也生效的)。是不是delete_notifier事件是先被express_editor处理,然后再到filter方法里的delete_notifier监听处理,没经过lua_processor

shewer commented 1 year ago

https://github.com/rime/librime/blob/a94739f1dc7d6328153b43e6a903e78afdf67fef/src/rime/gear/memory.cc#L122-L136 前面說法 有點出入 抱歉 , 向 delete_notifire 註冊 的是 engine/translators:[table_translator script_translator ] 而 OnDelete 只會在 user_dict 調整時起到 delete_candidate (刪除user_dict candidate)

你覺得正常是因爲 排在前面的OnDelete() 沒有真的 delete_candidate 如果 選中的candidate 是user_dict 就會執行 --> user_dict update --> refrash non.... --> lua_filter( delete_notifier) , 多執行一次 ,且此時 index =0 所以 lua_filter 增加屏蔽一個錯誤的詞

你的系統是?? librime & librime-lua 版本是??

qq420100523 commented 1 year ago

https://github.com/rime/librime/blob/a94739f1dc7d6328153b43e6a903e78afdf67fef/src/rime/gear/memory.cc#L122-L136 前面說法 有點出入 抱歉 , 向 delete_notifire 註冊 的是 engine/translators:[table_translator script_translator ] 而 OnDelete 只會在 user_dict 調整時起到 delete_candidate (刪除user_dict candidate)

你覺得正常是因爲 排在前面的OnDelete() 沒有真的 delete_candidate 如果 選中的candidate 是user_dict 就會執行 --> user_dict update --> refrash non.... --> lua_filter( delete_notifier) , 多執行一次 ,且此時 index =0 所以 lua_filter 增加屏蔽一個錯誤的詞

你的系統是?? librime & librime-lua 版本是??

我的系统是macos Ventura 13.2,使用https://github.com/LEOYoon-Tsaw/squirrel LEOYoon的美化版,刚发现有更新,我先更新再试试你的第一个写法

shewer commented 1 year ago

把下面 local function 放入 rime.lua ,可以檢查 log log 可以得到類似 以下訊息 Rime fcitx-rime 5.0.15 (id:f802202b-a976-4d1a-b171-7fba1e1d29f4) Ver: librime 1.7.3 librime-lua 200 lua Lua 5.4

https://github.com/shewer/librime-lua-script/blob/020fb77c4f6f0e2334b6efc835d679ec7eef16b9/lua/tools/rime_api.lua#L81-L110 https://github.com/shewer/librime-lua-script/blob/020fb77c4f6f0e2334b6efc835d679ec7eef16b9/lua/tools/rime_api.lua#L162-L173

--   以下加入  rime.lua

log.info( "==========" .. Ver_info() .. "===============")
qq420100523 commented 1 year ago

把下面 local function 放入 rime.lua ,可以檢查 log log 可以得到類似 以下訊息 Rime fcitx-rime 5.0.15 (id:f802202b-a976-4d1a-b171-7fba1e1d29f4) Ver: librime 1.7.3 librime-lua 200 lua Lua 5.4

https://github.com/shewer/librime-lua-script/blob/020fb77c4f6f0e2334b6efc835d679ec7eef16b9/lua/tools/rime_api.lua#L81-L110 https://github.com/shewer/librime-lua-script/blob/020fb77c4f6f0e2334b6efc835d679ec7eef16b9/lua/tools/rime_api.lua#L162-L173

--   以下加入  rime.lua

log.info( "==========" .. Ver_info() .. "===============")

E20230202 10:36:57.904137 103181 modules.cc:46] rime.lua error: /Users/zengzw/Library/Rime/rime.lua:2: attempt to call a nil value (global 'Ver_info') 在rime.squirrel.WARNING看到这个错误,然后输入法就异常了

shewer commented 1 year ago

上面兩個link 是function Version() Ver_info() code 沒貼上吧

qq420100523 commented 1 year ago

上面兩個link 是function Version() Ver_info() code 沒貼上吧

是的,刚刚没看清楚

qq420100523 commented 1 year ago

把下面 local function 放入 rime.lua ,可以檢查 log log 可以得到類似 以下訊息 Rime fcitx-rime 5.0.15 (id:f802202b-a976-4d1a-b171-7fba1e1d29f4) Ver: librime 1.7.3 librime-lua 200 lua Lua 5.4

https://github.com/shewer/librime-lua-script/blob/020fb77c4f6f0e2334b6efc835d679ec7eef16b9/lua/tools/rime_api.lua#L81-L110 https://github.com/shewer/librime-lua-script/blob/020fb77c4f6f0e2334b6efc835d679ec7eef16b9/lua/tools/rime_api.lua#L162-L173

--   以下加入  rime.lua

log.info( "==========" .. Ver_info() .. "===============")

========== 鼠鬚管 Squirrel 0.16.1 (id:unknown) Ver: librime 1.8.4 librime-lua 197 lua Lua 5.4=============== 另:Version()方法里的200分支在我的输入法上会卡死,我只能把它注释了

local function Version()
  local ver
  -- if Opencc and Opencc('s2t.json').convert_word then
  --   return 200
  -- else
    if rime_api.regex_match then
    return 197
  elseif rime_api.get_distribution_name then
    return 185
shewer commented 1 year ago

兩個腳本
lua_processor@editor_proc@[editor processor] -- 此proc 會自動載入 filter lua_filter@remove_filter 使用方式 libirme-lua 版本> 197 替換 editor processor < 197 在editor processor 前 插入

安裝1 手動載入( rime.lua 使用require module )

# <schema_id>.custom.yaml  
patch:
    # 假設 editor_processor 在 index 8(0~8) 
   engine/processors/@8: lua_processor@editor_proc@express_editor   # replace >= 197
   #engine/processors/@before 8: lua_processor@editor_proc@express_editor  # insert  <197

rime.lua

editor_proc = require 'editor_proc'

安裝2 自動載入( 不須require ,自動載入版本> 197)

# <schema_id>.custom.yaml  
patch:
    # 假設 editor_processor 在 index 8(0~8) 
   engine/processors/@8: lua_processor@*editor_proc@express_editor   # replace >= 197

editor_proc.lua

#! /usr/bin/env lua
--
-- editor_proc.lua
-- Copyright (C) 2023 Shewer Lu <shewer@gmail.com>
--
-- Distributed under terms of the MIT license.
--
-- librime-lua version >197
--   replase editor lua_processor@editor_proc@[express_editor|fluid_editor|chor_composer]
-- librime-lua version < 197
--   insert lua_processor@editor_proc@[express_editor|fluid_editor|chor_composer] before editor
--

local function load_editor_keybind(env)
  local config = env.engine.schema.config
  local ed_map = config:get_map('editor/bindings')
  env.keybind={}
  for _,key in ipairs(ed_map and ed_map:keys() or {}) do
    local ncmd= ed_map:get_value(key).value
    env.keybind[ncmd] = KeyEvent(key)
  end
end
local function init(env)
  if Component then
    env.editor= Component.Processor(env.engine,"processor", env.name_space)
    env.enable = true
  end
  -- check and insert remove_filter component
  local config = env.engine.schema.config
  local clist = config:get_list("engine/filters")
  local cvalue = ConfigValue("lua_filter@remove_filter")
  local fmatch= false
  for i= 0,clist.size-1 do
    fmatch =  clist:get_value_at(i).value:match(cvalue.value) and true or false
    if fmatch then break end
  end
  if not fmatch then
    clist:insert(0,cvalue.element)
  end
  -- load remove_filter module
  local mfilter= 'remove_filter'
  if not _ENV[mfilter] then
    _ENV[mfilter]= require( mfilter)
  end
end

local P={}

function P.init(env)
  init(env)
  load_editor_keybind(env)
  local dckey=env.keybind['delete_candidate']
  env.keybind['delete_candidate']= dckey and dckey or KeyEvent("Control+Delete")
end

function P.fini(env)
end

function P.func(key,env)
  local Rejected, Accepted, Noop = 0,1,2
  local context= env.engine.context
  if context:has_menu() and env.enable then
    if key:eq(env.keybind['delete_candidate']) then
      local cand= context:get_selected_candidate()
      if cand.type ~= "usertable" and cand.type ~= "userpharse" then
        context:set_property('delete_candidate',cand.text)
        context:refresh_non_confirmed_composition()
        return Accepted
      end
    end
  end
  return env.editor and env.editor:process_key_event(key) or Noop
end

return P

remove_filter.lua

#! /usr/bin/env lua
--
-- remove_filter.lua
-- Copyright (C) 2023 Shewer Lu <shewer@gmail.com>
--
-- Distributed under terms of the MIT license.
--
-- 使用 text dada 建立 屏蔽 candidate
-- 屏蔽 filename:  user_data_dir/[name_space].txt
-- 透過 property "delete_candidate" 來更新 Rmdb
--

-- Rmdb module
-- Rmdb(filename)
-- Rmdb:load() -- load text
-- Rmdb:append() -- update text

-- check get_user_data_dir func
if rime_api.get_user_data_dir then
  rime_api.get_user_data_dir = function()
    return "." -- set user_data_dir
  end
end

local Rmdb_mt={}
Rmdb_mt.__index =Rmdb_mt
function Rmdb_mt:load()
  for line in io.open(self.__filename,"a+"):lines() do
    local word = line:match("^([^#_]+)$")
    self[word]=true
  end
end

function Rmdb_mt:append(word)
  if self[word] then return end

  local fn = io.open(self.__filename,"a")
  if fn then
    fn:write(word .. "\n")
    fn:close()
    self[word]=true
  else
    log.error("Rmdb Error: can't open file:".. self.__filename)
  end
end

function Rmdb(name)
  local tab = setmetatable({}, Rmdb_mt)
  tab.__filename = rime_api.get_user_data_dir() .. package.config:sub(1,1) .. name .. ".txt"
  tab:load()
  return tab
end

local M={}

function M.init(env)
  env.rmdb= Rmdb(env.name_space)
  for k,v in next,env.rmdb do print("----->",k,v) end
  env.notifier= env.engine.context.property_update_notifier:connect(
  function(ctx,name)
    if name ~= "delete_candidate" then return end
    local word=ctx:get_property(name)
    env.rmdb:append(word)
  end)
end

function M.fini(env)
  env.notifier:disconnect()
end

function M.tags_match(seg,env)
  return true
end

function M.func(inp,env)
  for cand in inp:iter() do
    if not env.rmdb[cand.text] then
      yield(cand)
    end
  end
end

return M
qq420100523 commented 1 year ago

没成功,异常现象是:没有候选栏,删除词组的记录文件也没生成,bulid目录里的部署后wubi86.schema.yaml没有自动加上lua_filter@remove_filter 我的配置步骤: 1.把editor_proc.lua和remove_filter.lua放到lua目录 2.在wubi86.schema.yaml文件里注释- express_editor,并添加- lua_processor@*editor_proc@express_editor

shewer commented 1 year ago

不是更換新版 1.6.1嗎 會不會是 librime-lua 版本問題 不然就只能用安裝1了

lua_filter@remove_filter是動態載入到 config 不靠 yaml log 上會有載入 記錄的

qq420100523 commented 1 year ago

不是更換新版 1.6.1嗎 會不會是 librime-lua 版本問題 不然就只能用安裝1了

lua_filter@remove_filter是動態載入到 config 不靠 yaml log 上會有載入 記錄的

E20230202 15:19:03.174437 52898 lua_gears.cc:15] LuaTranslation::Next error(2): /Users/zengzw/Library/Rime/lua/remove_filter.lua:77: attempt to index a nil value (field 'rmdb')
E20230202 15:19:03.318361 52898 lua_gears.cc:15] LuaTranslation::Next error(2): /Users/zengzw/Library/Rime/lua/ecdict.lua:19: attempt to index a nil value
E20230202 15:19:03.318496 52898 lua_gears.cc:15] LuaTranslation::Next error(2): /Users/zengzw/Library/Rime/lua/remove_filter.lua:77: attempt to index a nil value (field 'rmdb')
E20230202 15:19:04.841203 52898 lua_gears.cc:59] Lua Compoment of initialize  error:( module: remove_filter name_space: remove_filter status: 2 ): /Users/zengzw/Library/Rime/lua/remove_filter.lua:28: attempt to index a nil value
E20230202 15:19:05.700676 52898 lua_gears.cc:114] LuaFilter::~LuaFilter of remove_filter error(2): /Users/zengzw/Library/Rime/lua/remove_filter.lua:68: attempt to index a nil value (field 'notifier')
E20230202 15:21:47.055214 52898 lua_gears.cc:59] Lua Compoment of initialize  error:( module: remove_filter name_space: remove_filter status: 2 ): /Users/zengzw/Library/Rime/lua/remove_filter.lua:28: attempt to index a nil value
E20230202 15:21:48.164841 52898 lua_gears.cc:114] LuaFilter::~LuaFilter of remove_filter error(2): /Users/zengzw/Library/Rime/lua/remove_filter.lua:68: attempt to index a nil value (field 'notifier')
E20230202 15:21:48.168138 52898 lua_gears.cc:114] LuaFilter::~LuaFilter of remove_filter error(2): /Users/zengzw/Library/Rime/lua/remove_filter.lua:68: attempt to index a nil value (field 'notifier')
E20230202 15:21:48.680861 52898 lua_gears.cc:59] Lua Compoment of initialize  error:( module: remove_filter name_space: remove_filter status: 2 ): /Users/zengzw/Library/Rime/lua/remove_filter.lua:28: attempt to index a nil value
E20230202 15:21:55.406311 52898 lua_gears.cc:59] Lua Compoment of initialize  error:( module: remove_filter name_space: remove_filter status: 2 ): /Users/zengzw/Library/Rime/lua/remove_filter.lua:28: attempt to index a nil value
E20230202 15:21:56.187666 52898 lua_gears.cc:114] LuaFilter::~LuaFilter of remove_filter error(2): /Users/zengzw/Library/Rime/lua/remove_filter.lua:68: attempt to index a nil value (field 'notifier')
shewer commented 1 year ago

把filter code function M.init() 貼上來 看 env.notifier 空值 env.rmdb 空值 開檔失敗 空值

從 trace 開始找吧 我這是沒問題的 ,我在最新版測試 舊版 我沒版本可試 如 rime_api.get_user_data_dir() 舊版沒有這api ,特地在 檔頭加入 手動 調整路逕


function Rmdb_mt:load()
  for line in io.open(self.__filename,"a+"):lines() do  -- 開檔取行失敗
    local word = line:match("^([^#_]+)$")
    self[word]=true
  end
end

function Rmdb(name)
  local tab = setmetatable({}, Rmdb_mt)
  tab.__filename = rime_api.get_user_data_dir() .. package.config:sub(1,1) .. name .. ".txt"
  --trace
  log.info("**********>>>>>>>>> tracing ", name ,tab.__filename)
   tab:load()
  return tab
end

function M.init(env)
  env.rmdb= Rmdb(env.name_space)
qq420100523 commented 1 year ago

把filter code function M.init() 貼上來 看

-- #! /usr/bin/env lua
--
-- remove_filter.lua
-- Copyright (C) 2023 Shewer Lu <shewer@gmail.com>
--
-- Distributed under terms of the MIT license.
--
-- 使用 text dada 建立 屏蔽 candidate
-- 屏蔽 filename:  user_data_dir/[name_space].txt
-- 透過 property "delete_candidate" 來更新 Rmdb
--

-- Rmdb module
-- Rmdb(filename)
-- Rmdb:load() -- load text
-- Rmdb:append() -- update text

-- check get_user_data_dir func
if rime_api.get_user_data_dir then
  rime_api.get_user_data_dir = function()
    return "." -- set user_data_dir
  end
end

local Rmdb_mt={}
Rmdb_mt.__index =Rmdb_mt
function Rmdb_mt:load()
  for line in io.open(self.__filename,"a+"):lines() do
    local word = line:match("^([^#_]+)$")
    self[word]=true
  end
end

function Rmdb_mt:append(word)
  if self[word] then return end

  local fn = io.open(self.__filename,"a")
  if fn then
    fn:write(word .. "\n")
    fn:close()
    self[word]=true
  else
    log.error("Rmdb Error: can't open file:".. self.__filename)
  end
end

function Rmdb(name)
  local tab = setmetatable({}, Rmdb_mt)
  tab.__filename = rime_api.get_user_data_dir() .. package.config:sub(1,1) .. name .. ".txt"
  tab:load()
  return tab
end

local M={}

function M.init(env)
  env.rmdb= Rmdb(env.name_space)
  for k,v in next,env.rmdb do print("----->",k,v) end
  env.notifier= env.engine.context.property_update_notifier:connect(
  function(ctx,name)
    if name ~= "delete_candidate" then return end
    local word=ctx:get_property(name)
    env.rmdb:append(word)
  end)
end

function M.fini(env)
  env.notifier:disconnect()
end

function M.tags_match(seg,env)
  return true
end

function M.func(inp,env)
  for cand in inp:iter() do
    if not env.rmdb[cand.text] then
      yield(cand)
    end
  end
end

return M

我应该是没有改的

qq420100523 commented 1 year ago

把filter code function M.init() 貼上來 看 env.notifier 空值 env.rmdb 空值 開檔失敗 空值

從 trace 開始找吧 我這是沒問題的 ,我在最新版測試 舊版 我沒版本可試 如 rime_api.get_user_data_dir() 舊版沒有這api ,特地在 檔頭加入 手動 調整路逕

function Rmdb_mt:load()
  for line in io.open(self.__filename,"a+"):lines() do  -- 開檔取行失敗
    local word = line:match("^([^#_]+)$")
    self[word]=true
  end
end

function Rmdb(name)
  local tab = setmetatable({}, Rmdb_mt)
  tab.__filename = rime_api.get_user_data_dir() .. package.config:sub(1,1) .. name .. ".txt"
  --trace
  log.info("**********>>>>>>>>> tracing ", name ,tab.__filename)
   tab:load()
  return tab
end

function M.init(env)
  env.rmdb= Rmdb(env.name_space)

ok,我这边先调试一下

qq420100523 commented 1 year ago

把filter code function M.init() 貼上來 看 env.notifier 空值 env.rmdb 空值 開檔失敗 空值

從 trace 開始找吧 我這是沒問題的 ,我在最新版測試 舊版 我沒版本可試 如 rime_api.get_user_data_dir() 舊版沒有這api ,特地在 檔頭加入 手動 調整路逕

function Rmdb_mt:load()
  for line in io.open(self.__filename,"a+"):lines() do  -- 開檔取行失敗
    local word = line:match("^([^#_]+)$")
    self[word]=true
  end
end

function Rmdb(name)
  local tab = setmetatable({}, Rmdb_mt)
  tab.__filename = rime_api.get_user_data_dir() .. package.config:sub(1,1) .. name .. ".txt"
  --trace
  log.info("**********>>>>>>>>> tracing ", name ,tab.__filename)
   tab:load()
  return tab
end

function M.init(env)
  env.rmdb= Rmdb(env.name_space)

问题找到了

-- remove_filter.lua
-- check get_user_data_dir func
if not rime_api.get_user_data_dir then
  rime_api.get_user_data_dir = function()
    return "." -- set user_data_dir
  end
end

if的条件要取反(not)

shewer commented 1 year ago

以後要調整增修屏蔽 可以到 user_data_dir/name_sppace.txt 在第一字元插入 # 取消屏蔽

在 rmdb:append() 前可以加上條件限定屏蔽規則

如果 engine/translators 有 lua_translation 可以試試增加 一個版本 candidate ( 我個人是用lua_processor commit_text( Ver_info() ) )

if input == "...." then yield( Candidate('ver', seg.start,seg._end,'版本', Ver_info()) ) end

可以再試試 安裝2 是否可以用自動載入了

qq420100523 commented 1 year ago

1.修改remove_filter.txt中一行,插入#号后,会导致当前文件内已记录的所有屏蔽词filter都不生效,手动还原内容也不行,继续添加屏蔽词会filter,但只生效后加的,原记录的屏蔽词都不生效,好奇怪的情况。 2.在 rmdb:append() 前可以加上條件限定屏蔽規則 --〉用意是?

  1. Candidate Ver_info 这个好,方便看版本号。 4.方式2也成功自动载入了。
shewer commented 1 year ago

1 要重新載入 Rmdb(name)

-- fixed  tab[nil] error 
function Rmdb_mt:load()
  for line in io.open(self.__filename,"a+"):lines() do
    local word = line:match("^([^#_]+)$")
    if word then 
      self[word]=true
    end
  end
end

2 example before append(word)

    if utf8.len(word) >1 then
       rmdb:append(word)
    end
redleafnew commented 7 months ago

这个搞成功了吗?