Support paired punctuation.

This commit is contained in:
fanlusky committed 2026-08-10 00:38:09 +08:00
1 parent dd113048f8
commit a2aedbf39f
9 files changed
+63 -5

No files matched your search

+2
View File
@@ -104,6 +104,8 @@ ime_mode_scope = "app"
word_to_character = false
# 智能标点:中文标点模式下,字母/数字后的 , . : 输出英文标点(类似小狼毫 digit_separators)
smart_punctuation = true
# 成对标点补全:输入左侧符号时自动补全右侧符号,并将光标置于中间
paired_punctuation = true
# 组合说明:
# legacy + shuangpin -> 使用旧版双拼会话实现(当前最稳定)
# legacy + quanpin -> 自动切换为新版引擎全拼会话
+17
View File
@@ -71,6 +71,7 @@ bool g_paging_page_up_down_enabled = true;
bool g_candidate_arrow_navigation_enabled = true;
bool g_word_to_character_enabled = false;
bool g_smart_punctuation_enabled = true;
bool g_paired_punctuation_enabled = true;
std::string g_candidate_window_layout = "vertical";
std::string g_candidate_window_preedit_style = "pinyin";
std::string g_theme_mode = "dark";
@@ -591,6 +592,7 @@ bool LoadImeConfig()
g_candidate_arrow_navigation_enabled = tbl["general"]["candidate_arrow_navigation"].value_or(true);
g_word_to_character_enabled = tbl["input"]["word_to_character"].value_or(false);
g_smart_punctuation_enabled = tbl["input"]["smart_punctuation"].value_or(true);
g_paired_punctuation_enabled = tbl["input"]["paired_punctuation"].value_or(true);
{
// Prefer explicit bool keys; fall back to legacy switch_language array.
const auto legacy = tbl["keybindings"]["switch_language"].as_array();
@@ -1661,6 +1663,21 @@ bool SetConfiguredSmartPunctuationEnabled(bool enabled)
return true;
}
bool GetConfiguredPairedPunctuationEnabled()
{
return g_paired_punctuation_enabled;
}
bool SetConfiguredPairedPunctuationEnabled(bool enabled)
{
if (!WriteConfiguredValue("input", "paired_punctuation", enabled ? "true" : "false"))
{
return false;
}
g_paired_punctuation_enabled = enabled;
return true;
}
const std::string &GetConfiguredCandidateWindowLayout()
{
return g_candidate_window_layout;
+2
View File
@@ -172,6 +172,8 @@ bool GetConfiguredWordToCharacterEnabled();
bool SetConfiguredWordToCharacterEnabled(bool enabled);
bool GetConfiguredSmartPunctuationEnabled();
bool SetConfiguredSmartPunctuationEnabled(bool enabled);
bool GetConfiguredPairedPunctuationEnabled();
bool SetConfiguredPairedPunctuationEnabled(bool enabled);
const std::string &GetConfiguredCandidateWindowLayout();
bool SetConfiguredCandidateWindowLayout(const std::string &layout);
const std::string &GetConfiguredCandidateWindowPreeditStyle();
+3
View File
@@ -2179,6 +2179,9 @@ void RegisteredPipeMonitorThread(HANDLE clientPipe, UINT pipeRole, uint64_t hand
SendToTsfWorkerThreadClientViaNamedpipe(
hello.client_id, Global::DataFromServerMsgTypeToTsfWorkerThread::SmartPunctuationChanged,
GetConfiguredSmartPunctuationEnabled() ? L"1" : L"0");
SendToTsfWorkerThreadClientViaNamedpipe(
hello.client_id, Global::DataFromServerMsgTypeToTsfWorkerThread::PairedPunctuationChanged,
GetConfiguredPairedPunctuationEnabled() ? L"1" : L"0");
}
}
+3 -1
View File
@@ -356,8 +356,10 @@ constexpr UINT PipeReady = 9;
constexpr UINT InsertText = 10;
// Smart punctuation after ASCII letters/digits (',' '.' ':'). Payload "0"/"1".
constexpr UINT SmartPunctuationChanged = 11;
// Auto-complete opening paired punctuation and leave the caret inside. Payload "0"/"1".
constexpr UINT PairedPunctuationChanged = 12;
// Highest worker opcode this build emits. Keep in sync with TSF MaxKnown.
constexpr UINT MaxKnown = SmartPunctuationChanged;
constexpr UINT MaxKnown = PairedPunctuationChanged;
} // namespace DataFromServerMsgTypeToTsfWorkerThread
} // namespace Global
+4 -1
View File
@@ -222,7 +222,8 @@ void PostConfig()
{"shuangpin_schema", GetConfiguredShuangpinSchema()},
{"wubi_schema", GetConfiguredWubiSchema()},
{"word_to_character", GetConfiguredWordToCharacterEnabled()},
{"smart_punctuation", GetConfiguredSmartPunctuationEnabled()}}},
{"smart_punctuation", GetConfiguredSmartPunctuationEnabled()},
{"paired_punctuation", GetConfiguredPairedPunctuationEnabled()}}},
{"general",
{{"floating_toolbar", GetConfiguredFloatingToolbarEnabled()},
{"floating_toolbar_fullwidth", toolbar.fullwidth},
@@ -336,6 +337,8 @@ bool ApplyConfigUpdate(const json::object &data)
return SetConfiguredWordToCharacterEnabled(json::value_to<bool>(data.at("value")));
if (path == "input.smart_punctuation")
return SetConfiguredSmartPunctuationEnabled(json::value_to<bool>(data.at("value")));
if (path == "input.paired_punctuation")
return SetConfiguredPairedPunctuationEnabled(json::value_to<bool>(data.at("value")));
if (path == "appearance.tsf_preedit_style")
return SetConfiguredTsfPreeditStyle(json::value_to<std::string>(data.at("value")));
if (path == "appearance.candidate_window_layout")
+13 -1
View File
@@ -2585,6 +2585,17 @@ HRESULT OnControllerCreatedSettingsWnd( //
PostSettingsConfig();
}
}
else if (path == "input.paired_punctuation")
{
const bool value = json::value_to<bool>(data.at("value"));
if (SetConfiguredPairedPunctuationEnabled(value))
{
BroadcastToTsfWorkerThreadViaNamedpipe(
Global::DataFromServerMsgTypeToTsfWorkerThread::PairedPunctuationChanged,
value ? L"1" : L"0");
PostSettingsConfig();
}
}
else if (path.rfind("general.floating_toolbar_", 0) == 0)
{
const std::string item = path.substr(std::string("general.floating_toolbar_").size());
@@ -2865,7 +2876,8 @@ void PostSettingsConfig()
{"shuangpin_schema", GetConfiguredShuangpinSchema()},
{"wubi_schema", GetConfiguredWubiSchema()},
{"word_to_character", GetConfiguredWordToCharacterEnabled()},
{"smart_punctuation", GetConfiguredSmartPunctuationEnabled()}}},
{"smart_punctuation", GetConfiguredSmartPunctuationEnabled()},
{"paired_punctuation", GetConfiguredPairedPunctuationEnabled()}}},
{"general",
{{"floating_toolbar", GetConfiguredFloatingToolbarEnabled()},
{"floating_toolbar_fullwidth", toolbar.fullwidth},
+14
View File
@@ -1437,6 +1437,7 @@ LRESULT CALLBACK WndProcCandWindow(HWND hwnd, UINT message, WPARAM wParam, LPARA
const bool previous_cloud_candidates = GetConfiguredCloudCandidatesEnabled();
const bool previous_comma_period = GetConfiguredPagingCommaPeriodEnabled();
const bool previous_smart_punctuation = GetConfiguredSmartPunctuationEnabled();
const bool previous_paired_punctuation = GetConfiguredPairedPunctuationEnabled();
const std::string previous_tsf_preedit_style = GetConfiguredTsfPreeditStyle();
const std::string previous_theme_mode = GetConfiguredThemeMode();
const std::string previous_theme_cand = GetConfiguredThemeCand();
@@ -1505,6 +1506,12 @@ LRESULT CALLBACK WndProcCandWindow(HWND hwnd, UINT message, WPARAM wParam, LPARA
Global::DataFromServerMsgTypeToTsfWorkerThread::SmartPunctuationChanged,
GetConfiguredSmartPunctuationEnabled() ? L"1" : L"0");
}
if (previous_paired_punctuation != GetConfiguredPairedPunctuationEnabled())
{
BroadcastToTsfWorkerThreadViaNamedpipe(
Global::DataFromServerMsgTypeToTsfWorkerThread::PairedPunctuationChanged,
GetConfiguredPairedPunctuationEnabled() ? L"1" : L"0");
}
const VoiceInputConfig &voice_input = GetConfiguredVoiceInput();
if (previous_voice_input.enabled != voice_input.enabled ||
previous_voice_input.hotkey_ralt != voice_input.hotkey_ralt ||
@@ -2026,6 +2033,7 @@ LRESULT CALLBACK WndProcSettingsWindow(HWND hwnd, UINT message, WPARAM wParam, L
const bool previous_cloud_candidates = GetConfiguredCloudCandidatesEnabled();
const bool previous_comma_period = GetConfiguredPagingCommaPeriodEnabled();
const bool previous_smart_punctuation = GetConfiguredSmartPunctuationEnabled();
const bool previous_paired_punctuation = GetConfiguredPairedPunctuationEnabled();
const std::string previous_tsf_preedit_style = GetConfiguredTsfPreeditStyle();
const std::string previous_theme_mode = GetConfiguredThemeMode();
const std::string previous_theme_cand = GetConfiguredThemeCand();
@@ -2101,6 +2109,12 @@ LRESULT CALLBACK WndProcSettingsWindow(HWND hwnd, UINT message, WPARAM wParam, L
Global::DataFromServerMsgTypeToTsfWorkerThread::SmartPunctuationChanged,
GetConfiguredSmartPunctuationEnabled() ? L"1" : L"0");
}
if (previous_paired_punctuation != GetConfiguredPairedPunctuationEnabled())
{
BroadcastToTsfWorkerThreadViaNamedpipe(
Global::DataFromServerMsgTypeToTsfWorkerThread::PairedPunctuationChanged,
GetConfiguredPairedPunctuationEnabled() ? L"1" : L"0");
}
PostSettingsConfig();
}
}
@@ -25,7 +25,8 @@ TEST_CASE(ipc_pipe_ready_is_a_distinct_server_reply)
REQUIRE_EQ(Global::DataFromServerMsgTypeToTsfWorkerThread::PipeReady, 9u);
REQUIRE_EQ(Global::DataFromServerMsgTypeToTsfWorkerThread::InsertText, 10u);
REQUIRE_EQ(Global::DataFromServerMsgTypeToTsfWorkerThread::SmartPunctuationChanged, 11u);
REQUIRE_EQ(Global::DataFromServerMsgTypeToTsfWorkerThread::MaxKnown, 11u);
REQUIRE_EQ(Global::DataFromServerMsgTypeToTsfWorkerThread::PairedPunctuationChanged, 12u);
REQUIRE_EQ(Global::DataFromServerMsgTypeToTsfWorkerThread::MaxKnown, 12u);
REQUIRE(Global::DataFromServerMsgTypeToTsfWorkerThread::FocusSessionReady >
Global::DataFromServerMsgTypeToTsfWorkerThread::PagingCommaPeriodChanged);
REQUIRE(Global::DataFromServerMsgTypeToTsfWorkerThread::PipeReady >
@@ -34,9 +35,11 @@ TEST_CASE(ipc_pipe_ready_is_a_distinct_server_reply)
Global::DataFromServerMsgTypeToTsfWorkerThread::PipeReady);
REQUIRE(Global::DataFromServerMsgTypeToTsfWorkerThread::SmartPunctuationChanged >
Global::DataFromServerMsgTypeToTsfWorkerThread::InsertText);
REQUIRE(Global::DataFromServerMsgTypeToTsfWorkerThread::PairedPunctuationChanged >
Global::DataFromServerMsgTypeToTsfWorkerThread::SmartPunctuationChanged);
REQUIRE_EQ(
Global::DataFromServerMsgTypeToTsfWorkerThread::MaxKnown,
Global::DataFromServerMsgTypeToTsfWorkerThread::SmartPunctuationChanged);
Global::DataFromServerMsgTypeToTsfWorkerThread::PairedPunctuationChanged);
}
TEST_CASE(ipc_client_suspension_is_a_distinct_nonterminal_route_reset)