Files
msime-windows/engine/schemes/japanese_romaji_scheme.cpp
fanlusky 5a5dea6b7e feat(japanese): 日语模式禁用 -/= 翻页并用 - 打长音符
日语模式下把 - 让给长音符(ー)输入,同时禁掉 -/= 的候选翻页:

- 罗马字方案接受 VK_OEM_MINUS,set_raw_input 不再把 - 过滤掉;
  罗马字表里本来就有 - 到 ー 的条目,只缺按键准入。
- n 后面接 - 时按辅音处理,让前面的 n 收成 ん,避免 n- 卡在 pending。
- 空编码时单独按 - 也起头组合,候选框第一项是 ー、第二项是普通 -。
- 组词流程同样适用:判据只看日语模式加组合状态,不再走翻页和词转字。
- -/= 在日语模式下不翻页,_ = + 这些没有假名写法的字符退回标点上屏,
  并把 = _ 补进服务端的标点集合,和 TSF 侧保持一致,否则会等不到回包。

TSF 侧的影子分类、IsVirtualKeyNeed(ForFreshComposition) 和服务端按键策略
三处同时改,统一以配置项 input_mode == japanese 为判据(R 模式不在范围内,
TSF 侧看不到临时会话,用会话类型判断会让两侧分类打架)。
2026-09-15 01:57:50 +08:00

94 lines
2.9 KiB
C++

#include "japanese_romaji_scheme.h"
#include "../japanese/romaji_converter.h"
#include <algorithm>
#include <cctype>
namespace
{
bool IsRomajiKey(ImeKeyCode vk)
{
return vk >= 'A' && vk <= 'Z';
}
} // namespace
void JapaneseRomajiScheme::reset()
{
raw_input_.clear();
key_strokes_.clear();
}
void JapaneseRomajiScheme::handle_key(ImeKeyCode vk, ImeModifierMask modifiers_down, ImeCharacter wch)
{
if (vk == ImeKey::Backspace)
{
if (!raw_input_.empty())
raw_input_.pop_back();
if (!key_strokes_.empty())
key_strokes_.pop_back();
return;
}
if (vk == ImeKey::Escape || vk == ImeKey::Return)
{
reset();
return;
}
if (vk == ImeKey::Apostrophe && wch == u'\'')
{
raw_input_.push_back('\'');
key_strokes_.push_back(KeyStroke{vk, modifiers_down, wch});
return;
}
// '-' 是长音符(ー)的罗马字写法,不是翻页键,罗马字表里已有对应条目。
if (vk == ImeKey::Minus && wch == u'-')
{
raw_input_.push_back('-');
key_strokes_.push_back(KeyStroke{vk, modifiers_down, wch});
return;
}
if (!IsRomajiKey(vk))
return;
key_strokes_.push_back(KeyStroke{vk, modifiers_down, wch});
if ((wch >= u'a' && wch <= u'z') || (wch >= u'A' && wch <= u'Z'))
raw_input_.push_back(static_cast<char>(wch));
else
raw_input_.push_back(static_cast<char>(vk + ('a' - 'A')));
}
void JapaneseRomajiScheme::set_raw_input(const std::string &raw_input, const std::string &raw_input_with_cases)
{
raw_input_ = raw_input_with_cases.empty() ? raw_input : raw_input_with_cases;
raw_input_.erase(std::remove_if(raw_input_.begin(), raw_input_.end(),
[](unsigned char ch) { return !std::isalpha(ch) && ch != '\'' && ch != '-'; }),
raw_input_.end());
key_strokes_.clear();
}
QueryRequest JapaneseRomajiScheme::build_request() const
{
QueryRequest request;
request.scheme = type();
request.raw_input_with_cases = raw_input_;
request.raw_input = raw_input_;
std::transform(request.raw_input.begin(), request.raw_input.end(), request.raw_input.begin(),
[](unsigned char ch) { return static_cast<char>(std::tolower(ch)); });
request.normalized_input = request.raw_input;
const auto converted = japanese::ConvertRomaji(request.raw_input);
request.raw_segmentation = request.raw_input_with_cases;
request.normalized_segmentation = converted.hiragana + converted.pending;
request.segmentation = request.normalized_segmentation;
request.key_strokes = key_strokes_;
request.valid = !request.raw_input.empty();
return request;
}
std::string JapaneseRomajiScheme::get_preedit() const
{
return raw_input_;
}
SchemeType JapaneseRomajiScheme::type() const
{
return SchemeType::JapaneseRomaji;
}