fix: 句中反查修复了两个bug

This commit is contained in:
amzxyz
2026-01-05 01:09:44 +08:00
parent 470509ff92
commit 7cf7997a41
3 changed files with 84 additions and 94 deletions

View File

@@ -278,6 +278,19 @@ function F.func(input, env)
local best_candidate_saved = false
local code_len = #curr_input
if code_len > 2 and sub(curr_input, -2) == "\\\\" then
local raw_text = sub(curr_input, 1, code_len - 2)
if is_ascii_phrase_fast(raw_text) then
if ctx.composition and not ctx.composition:empty() then
ctx.composition:back().prompt = "〔英文造词〕"
end
local cand = Candidate("english", 0, code_len, raw_text, "")
cand.preedit = raw_text
yield(cand)
return -- 强制结束,独占输出
end
end
-- [Check 1] 外部脚本发来的打断信号
local break_signal = (ctx:get_property("english_spacing") == "true")
local effective_prev_is_eng = env.prev_commit_is_eng
@@ -398,7 +411,7 @@ function F.func(input, env)
local cand = Candidate("completion", 0, #curr_input, output_text, "~")
cand.preedit = output_preedit
cand.quality = 9999999
cand.quality = 999
yield(cand)
else
local cand = Candidate("completion", 0, #curr_input, curr_input, "~")

View File

@@ -569,37 +569,6 @@ function M.func(input, env)
end
local symbol = env.symbol
-- 强制英文检测 (仅针对双击符号 \\)
local force_english_text = nil
local delimiter = nil
-- 只有定义了符号,且输入长度足够才检测
if symbol and #symbol == 1 then
delimiter = symbol .. symbol -- 定义触发符为两个符号
if code and #code >= 3 then
local c_len = #code
-- 严格检测:末尾最后两个字符必须等于 "符号+符号"
if string.sub(code, c_len - 1, c_len) == delimiter then
-- 提取基础文本 (去掉末尾的 \\)
local base = string.sub(code, 1, c_len - 2)
if base and #base > 0 then
-- 纯 ASCII 检查 (防止误把中文截断)
local ascii_only = true
for i = 1, #base do
if string.byte(base, i) > 127 then
ascii_only = false; break
end
end
if ascii_only then
force_english_text = base
end
end
end
end
end
-- =======================================================
local code_has_symbol = symbol and #symbol == 1 and (find(code, symbol, 1, true) ~= nil)
-- segmentation用于保持原有的包裹/分段逻辑
@@ -689,22 +658,9 @@ function M.func(input, env)
nc.preedit = formatted.preedit
return nc, (formatted.text or ""), wrapped
end
-- 兜底逻辑 (处理无候选词的情况,如 scx\\)
-- 兜底逻辑
local function improved_fallback_emit()
-- 优先处理强制英文:只要触发符匹配,即使无其他候选也必须输出
if force_english_text then
local start_pos = (last_seg and last_seg.start) or 0
-- 关键点end_pos 设为 #code确保上屏时覆盖掉 "scx\\"
local end_pos = #code
local eng = Candidate("completion", start_pos, end_pos, force_english_text, "")
eng.preedit = force_english_text
-- 这里不设 pipeline直接输出保证它一定是第一个
yield(eng)
return true
end
-- 以下是原有的 Wrap/Completion 兜底逻辑
-- Wrap/Completion 兜底逻辑
if not code_has_symbol or not tail_text then return false end
local pos = tail_text:find(symbol, 1, true)
if not (pos and pos > 1) then return false end
@@ -755,16 +711,6 @@ function M.func(input, env)
end
if idx == 1 then
-- 有候选词时,优先插入英文
if force_english_text then
local start_pos = 0
local end_pos = #code -- 覆盖全长,消除 \\
local eng = Candidate("completion", start_pos, end_pos, force_english_text, cand.comment)
eng.preedit = force_english_text
emit_ctx.drop_sentence_after_completion = true
emit_with_pipeline(eng, emit_ctx)
end
if not emit_ctx.drop_sentence_after_completion then
local txt = cand.text or ""
if is_table_type(cand) and #txt >= 4 and has_english_token_fast(txt) then
@@ -772,7 +718,7 @@ function M.func(input, env)
end
end
if (not force_english_text) and env.locked and (not wrap_key) and env.cache then
if env.locked and (not wrap_key) and env.cache then
local start_pos = (last_seg and last_seg.start) or 0
local end_pos = (last_seg and last_seg._end) or #code
if keep_tail_len and keep_tail_len > 0 then
@@ -828,17 +774,6 @@ function M.func(input, env)
end
if idx2 == 1 then
-- 分组模式下同样插入英文
if force_english_text then
local start_pos = 0
local end_pos = #code -- 覆盖全长
local eng = Candidate("completion", start_pos, end_pos, force_english_text, cand.comment)
eng.preedit = force_english_text
emit_ctx.drop_sentence_after_completion = true
emit_with_pipeline(eng, emit_ctx)
end
if not emit_ctx.drop_sentence_after_completion then
local t = fast_type(cand)
local txt = cand.text or ""
@@ -848,7 +783,7 @@ function M.func(input, env)
end
local emitted = false
if (not force_english_text) and env.locked and (not wrap_key) and env.cache then
if env.locked and (not wrap_key) and env.cache then
local start_pos = (last_seg and last_seg.start) or 0
local end_pos = (last_seg and last_seg._end) or #code
if keep_tail_len and keep_tail_len > 0 then

View File

@@ -54,42 +54,84 @@ local function get_schema_rules(env)
return main_rules or {}, xlit_rules or {}
end
-- 【DB】构建编码
local function expand_code_variant(main_projection, xlit_projection, part)
local out, seen = {}, {}
local function add(s) if s and #s > 0 and not seen[s] then seen[s] = true out[#out + 1] = s end end
-- 统一添加函数 (负责去重 + 顺序保持)
local function add(s)
if s and #s > 0 and not seen[s] then
seen[s] = true
table.insert(out, s)
end
end
-- 1. 定义“种子”列表,首先放入原始编码 part
local seeds = { part }
-- 通用奇数位提取器 (1, 3, 5...)
-- 规则:纯小写字母 + 偶数长度
local function extract_odd_positions(s)
if not s or not s:match("^%l+$") or #s % 2 ~= 0 then return nil end
local res = ""
for i = 1, #s, 2 do res = res .. s:sub(i, i) end
return res
end
-- 2. 提取只有一个单引号编码,若成功则将其作为第二个“种子”加入列表
-- 例如part="ce'shi",提取出 "cs" 加入 seeds
-- 检查奇偶位组合,如果是 [jqxy] + u则生成对应的 v 版本
local function get_v_variant(s)
if not s or not s:match("^%l+$") or #s % 2 ~= 0 then return nil end
local res = ""
local has_change = false
for i = 1, #s, 2 do
local char_odd = s:sub(i, i)
local char_even = s:sub(i+1, i+1)
if (char_odd == 'j' or char_odd == 'q' or char_odd == 'x' or char_odd == 'y') and char_even == 'v' then
res = res .. char_odd .. 'u'
has_change = true
else
res = res .. char_odd .. char_even
end
end
return has_change and res or nil
end
-- 预处理单引号特例 (ce'shi -> cs)全拼用
local _, quote_count = part:gsub("'", "")
if quote_count == 1 then
local s1, s2 = part:match("^([^']*)'([^']*)$")
if s1 and s2 and #s1 > 0 and #s2 > 0 then
local derived_code = s1:sub(1,1) .. s2:sub(1,1)
table.insert(seeds, derived_code)
add(s1:sub(1,1) .. s2:sub(1,1))
end
end
-- 3. 遍历所有种子(原始编码 + 缩写编码),统一进行规则投影
for _, code in ipairs(seeds) do
-- A. 应用 main_projection
if main_projection then
local p = main_projection:apply(code, true)
if p and #p > 0 then
add(p)
if #p == 4 then
add(p:sub(1,1) .. p:sub(3,3))
end
end
end
-- B. 应用 xlit_projection
if code:match('^%u+$') and xlit_projection then
local xlit_result = xlit_projection:apply(code, true)
if xlit_result and #xlit_result > 0 then add(xlit_result) end
-- 保留原始编码,用户可能加入直接的编码用
-- 只有纯小写字母 (ceui) 才保留,含符号(ce'shi)或大写(ABC)均不保留
if part:match("^%l+$") then
add(part)
end
-- 对“原始编码”进行奇位提取 (ceui -> cu)
-- extract_odd_positions 内部已经校验了 ^%l+$,所以这里直接调用即可
local raw_extracted = extract_odd_positions(part)
if raw_extracted then add(raw_extracted) end
-- 规则投影 (Main Projection)
if main_projection and not part:match('^%u+$') then
local p = main_projection:apply(part, true)
if p and #p > 0 then
-- A. 加入投影全码 (如 yuif)
add(p)
-- B. 生成 v 变体 (如 yuif -> yvif)
local v_variant = get_v_variant(p)
if v_variant then add(v_variant) end
-- C. 对投影全码提取奇位 (如 yuif -> yi)
local proj_extracted = extract_odd_positions(p)
if proj_extracted then add(proj_extracted) end
end
end
-- 大写反查 (Xlit)
if part:match('^%u+$') and xlit_projection then
local xlit_result = xlit_projection:apply(part, true)
if xlit_result and #xlit_result > 0 then add(xlit_result) end
end
return out
end
-- 【DB】查表