From 7cf7997a411fe51842e8a95f57990e4e67d398e1 Mon Sep 17 00:00:00 2001 From: amzxyz Date: Mon, 5 Jan 2026 01:09:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8F=A5=E4=B8=AD=E5=8F=8D=E6=9F=A5?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E4=B8=A4=E4=B8=AAbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/super_english.lua | 15 +++++++- lua/super_filter.lua | 73 ++--------------------------------- lua/super_lookup.lua | 90 +++++++++++++++++++++++++++++++------------ 3 files changed, 84 insertions(+), 94 deletions(-) diff --git a/lua/super_english.lua b/lua/super_english.lua index 031d27d..e69f406 100644 --- a/lua/super_english.lua +++ b/lua/super_english.lua @@ -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, "~") diff --git a/lua/super_filter.lua b/lua/super_filter.lua index 9a52fde..bc1be16 100644 --- a/lua/super_filter.lua +++ b/lua/super_filter.lua @@ -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 diff --git a/lua/super_lookup.lua b/lua/super_lookup.lua index 842a964..2df77c7 100644 --- a/lua/super_lookup.lua +++ b/lua/super_lookup.lua @@ -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】查表