rime-ice/rime.lua

313 lines
11 KiB
Lua
Raw Normal View History

2022-10-30 16:47:40 +01:00
-- Rime lua 扩展https://github.com/hchunhui/librime-lua
-------------------------------------------------------------
-- 日期时间
-- 提高权重的原因:因为在方案中设置了大于 1 的 initial_quality导致 rq sj xq dt ts 产出的候选项在所有词语的最后。
function date_translator(input, seg, env)
2023-01-19 11:36:43 +01:00
local config = env.engine.schema.config
local date = config:get_string(env.name_space .. "/date") or "rq"
local time = config:get_string(env.name_space .. "/time") or "sj"
local week = config:get_string(env.name_space .. "/week") or "xq"
local datetime = config:get_string(env.name_space .. "/datetime") or "dt"
local timestamp = config:get_string(env.name_space .. "/timestamp") or "ts"
2022-10-30 16:47:40 +01:00
-- 日期
if (input == date) then
2022-10-30 16:47:40 +01:00
local cand = Candidate("date", seg.start, seg._end, os.date("%Y-%m-%d"), "")
cand.quality = 100
yield(cand)
local cand = Candidate("date", seg.start, seg._end, os.date("%Y/%m/%d"), "")
cand.quality = 100
yield(cand)
local cand = Candidate("date", seg.start, seg._end, os.date("%Y.%m.%d"), "")
cand.quality = 100
yield(cand)
local cand = Candidate("date", seg.start, seg._end, os.date("%Y 年 %m 月 %d 日"), "")
cand.quality = 100
yield(cand)
end
-- 时间
if (input == time) then
2022-10-30 16:47:40 +01:00
local cand = Candidate("time", seg.start, seg._end, os.date("%H:%M"), "")
cand.quality = 100
yield(cand)
local cand = Candidate("time", seg.start, seg._end, os.date("%H:%M:%S"), "")
cand.quality = 100
yield(cand)
end
-- 星期
if (input == week) then
2022-10-30 16:47:40 +01:00
local weakTab = {'', '', '', '', '', '', ''}
local cand = Candidate("week", seg.start, seg._end, "星期" .. weakTab[tonumber(os.date("%w") + 1)], "")
2022-10-30 16:47:40 +01:00
cand.quality = 100
yield(cand)
2023-01-19 11:36:43 +01:00
local cand = Candidate("week", seg.start, seg._end, "礼拜" .. weakTab[tonumber(os.date("%w") + 1)], "")
cand.quality = 100
yield(cand)
local cand = Candidate("week", seg.start, seg._end, "" .. weakTab[tonumber(os.date("%w") + 1)], "")
2022-10-30 16:47:40 +01:00
cand.quality = 100
yield(cand)
end
-- ISO 8601/RFC 3339 的时间格式 (固定东八区)(示例 2022-01-07T20:42:51+08:00
if (input == datetime) then
2022-10-30 16:47:40 +01:00
local cand = Candidate("datetime", seg.start, seg._end, os.date("%Y-%m-%dT%H:%M:%S+08:00"), "")
cand.quality = 100
yield(cand)
local cand = Candidate("time", seg.start, seg._end, os.date("%Y%m%d%H%M%S"), "")
cand.quality = 100
yield(cand)
end
-- 时间戳(十位数,到秒,示例 1650861664
if (input == timestamp) then
2022-10-30 16:47:40 +01:00
local cand = Candidate("datetime", seg.start, seg._end, os.time(), "")
cand.quality = 100
yield(cand)
end
end
-------------------------------------------------------------
-- 以词定字
-- https://github.com/BlindingDark/rime-lua-select-character
-- 删除了默认按键,需要在 key_binderdefault.custom.yaml下设置
local function utf8_sub(s, i, j)
i = i or 1
j = j or -1
if i < 1 or j < 1 then
local n = utf8.len(s)
if not n then
return nil
end
if i < 0 then
i = n + 1 + i
end
if j < 0 then
j = n + 1 + j
end
if i < 0 then
i = 1
elseif i > n then
i = n
end
if j < 0 then
j = 1
elseif j > n then
j = n
end
end
if j < i then
return ""
end
i = utf8.offset(s, i)
j = utf8.offset(s, j + 1)
if i and j then
return s:sub(i, j - 1)
elseif i then
return s:sub(i)
else
return ""
end
end
local function first_character(s)
return utf8_sub(s, 1, 1)
end
local function last_character(s)
return utf8_sub(s, -1, -1)
end
function select_character(key, env)
local engine = env.engine
local context = engine.context
local commit_text = context:get_commit_text()
local config = engine.schema.config
-- local first_key = config:get_string('key_binder/select_first_character') or 'bracketleft'
-- local last_key = config:get_string('key_binder/select_last_character') or 'bracketright'
local first_key = config:get_string('key_binder/select_first_character')
local last_key = config:get_string('key_binder/select_last_character')
if (key:repr() == first_key and commit_text ~= "") then
engine:commit_text(first_character(commit_text))
context:clear()
return 1 -- kAccepted
end
if (key:repr() == last_key and commit_text ~= "") then
engine:commit_text(last_character(commit_text))
context:clear()
return 1 -- kAccepted
end
return 2 -- kNoop
end
-------------------------------------------------------------
-- 长词优先(提升「西安」「提案」「图案」「饥饿」等词汇的优先级)
-- 感谢&参考于: https://github.com/tumuyan/rime-melt
-- 修改:不提升英文和中英混输的
function long_word_filter(input, env)
-- 提升 count 个词语,插入到第 idx 个位置,默认 2、4。
2023-01-19 11:36:43 +01:00
local config = env.engine.schema.config
local count = config:get_int(env.name_space .. "/count") or 2
local idx = config:get_int(env.name_space .. "/idx") or 4
2022-10-30 16:47:40 +01:00
local l = {}
local firstWordLength = 0 -- 记录第一个候选词的长度,提前的候选词至少要比第一个候选词长
-- local s1 = 0 -- 记录筛选了多少个英语词条(只提升 count 个词的权重并且对comment长度过长的候选进行过滤)
local s2 = 0 -- 记录筛选了多少个汉语词条(只提升 count 个词的权重)
local i = 1
for cand in input:iter() do
leng = utf8.len(cand.text)
if (firstWordLength < 1 or i < idx) then
2022-10-30 16:47:40 +01:00
i = i + 1
firstWordLength = leng
yield(cand)
-- 不知道这两行是干嘛用的,似乎注释掉也没有影响。
-- elseif #table > 30 then
-- table.insert(l, cand)
-- 注释掉了英文的
-- elseif ((leng > firstWordLength) and (s1 < 2)) and (string.find(cand.text, "^[%w%p%s]+$")) then
-- s1 = s1 + 1
-- if (string.len(cand.text) / string.len(cand.comment) > 1.5) then
-- yield(cand)
-- end
-- 换了个正则,否则中英混输的也会被提升
-- elseif ((leng > firstWordLength) and (s2 < count)) and (string.find(cand.text, "^[%w%p%s]+$")==nil) then
elseif ((leng > firstWordLength) and (s2 < count)) and (string.find(cand.text, "[%w%p%s]+") == nil) then
2022-10-30 16:47:40 +01:00
yield(cand)
s2 = s2 + 1
else
table.insert(l, cand)
end
end
for i, cand in ipairs(l) do
yield(cand)
end
end
-------------------------------------------------------------
-- 降低部分英语单词在候选项的位置
-- https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题
-- 感谢大佬 @[Shewer Lu](https://github.com/shewer) 指点
function reduce_english_filter(input, env)
local config = env.engine.schema.config
-- load data
if not env.idx then
2023-02-13 15:07:50 +01:00
env.idx = config:get_int(env.name_space .. "/idx") -- 要插入的位置
end
if not env.words then
2023-02-13 15:07:50 +01:00
env.words = {} -- 要过滤的词
local list = config:get_list(env.name_space .. "/words")
for i = 0, list.size - 1 do
local word = list:get_value_at(i).value
env.words[word] = true
end
end
2023-02-13 15:07:50 +01:00
-- filter start
local code = env.engine.context.input
if env.words[code] then
2023-02-13 16:52:57 +01:00
local first_cand
local index = 0
2023-02-13 15:07:50 +01:00
for cand in input:iter() do
2023-02-13 16:52:57 +01:00
index = index + 1
if first_cand then
yield(cand)
else
first_cand = cand
end
if index >= env.idx then
yield(first_cand)
2023-02-13 15:07:50 +01:00
break
end
end
end
2023-02-13 15:07:50 +01:00
-- yield other
for cand in input:iter() do
2023-02-13 15:07:50 +01:00
yield(cand)
end
end
-------------------------------------------------------------
2023-01-19 11:36:43 +01:00
-- v 模式,单个字符优先
-- 因为设置了英文翻译器的 initial_quality 大于 1导致输入「va」时候选项是「van vain …… ā á ǎ à」
-- 把候选项应改为「ā á ǎ à …… van vain」让单个字符的排在前面
function v_filter(input, env)
local code = env.engine.context.input -- 当前编码
local l = {}
for cand in input:iter() do
-- 特殊情况处理
if (cand.text == "Vs.") then
2023-01-19 11:36:43 +01:00
yield(cand)
end
-- 特殊情况处理
local arr = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}
for _, v in ipairs(arr) do
if (v == cand.text and string.len(code) == 2 and string.find(code, "v") == 1) then
yield(cand)
break
end
end
2023-01-19 11:36:43 +01:00
-- 以 v 开头、2 个长度的编码、候选项为单个字符的,提到前面来。
if (string.len(code) == 2 and string.find(code, "v") == 1 and utf8.len(cand.text) == 1) then
yield(cand)
else
table.insert(l, cand)
end
end
for _, cand in ipairs(l) do
2023-01-19 11:36:43 +01:00
yield(cand)
2022-10-30 16:47:40 +01:00
end
end
-------------------------------------------------------------
-- iRime 九宫格专用,将输入框的数字转为对应的拼音或英文
function irime_t9_preedit(input, env)
for cand in input:iter() do
if (string.find(cand.text, "%w+") ~= nil) then
cand:get_genuine().preedit = cand.text
else
cand:get_genuine().preedit = cand.comment
end
yield(cand)
end
end
-------------------------------------------------------------
-- 限制码长(最多能输入 length_limit 个字符,超过后不再上屏,不设置时默认 100
-- 参考于https://github.com/rime/weasel/issues/733
function code_length_limit_processor(key, env)
local ctx = env.engine.context
local config = env.engine.schema.config
-- 限制
local length_limit = config:get_int(env.name_space) or 100
2022-10-30 16:47:40 +01:00
if (length_limit ~= nil) then
if (string.len(ctx.input) > length_limit) then
2022-10-30 16:47:40 +01:00
-- ctx:clear()
ctx:pop_input(1) -- 删除输入框中最后个编码字符
return 1
end
end
-- 放行
return 2
end
-------------------------------------------------------------
2023-01-02 19:48:02 +01:00
-- Unicode 输入
-- 复制自: https://github.com/shewer/librime-lua-script/blob/main/lua/component/unicode.lua
function unicode(input, seg, env)
local ucodestr = seg:has_tag("unicode") and input:match("U(%x+)")
if ucodestr and #ucodestr > 1 then
local code = tonumber(ucodestr, 16)
local text = utf8.char(code)
yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x", code)))
if #ucodestr < 5 then
for i = 0, 15 do
local text = utf8.char(code * 16 + i)
yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x~%x", code, i)))
end
end
end
end
-------------------------------------------------------------