Added support for superscript and repeated character sequences

This commit is contained in:
Yuki Joou 2024-02-04 22:45:58 +01:00
parent dac0c64d4c
commit 266f408640
2 changed files with 70 additions and 9 deletions

View file

@ -229,15 +229,35 @@ static std::unordered_map<
}},
};
// This maps KeySyms to a list of characters indicating what repeating the key
// should convert to.
static std::unordered_map<fcitx::KeySym const,
std::vector<std::string> const> const
keyToRepeatConversion = {
{FcitxKey_colon, {"ː", "ˑ", "ːː"}},
{FcitxKey_braceright, {"ˈ", "ˌ"}},
};
// Maps regular IPA characters to their superscript variants
static std::unordered_map<std::string, std::string> const superscripts = {
{"-", ""},
{"h", "ʰ"},
{"w", "ʷ"},
{"j", "ʲ"},
{"ɣ", "ˠ"},
{"ʕ", "ˤ"},
{"n", ""},
{"l", "ˡ"},
// TODO: Find a complete list of all IPA superscripts and complete this.
};
std::optional<std::string> getIPAForSIL(std::string baseCharacter,
fcitx::KeySym silModifier)
{
FCITX_INFO() << "Figuring IPA for " << baseCharacter << " & "
<< silModifier;
try {
return SILtoIPA.at(baseCharacter).at(silModifier);
} catch (std::out_of_range& e) {
FCITX_INFO() << "Couldn't get IPA character: " << e.what();
return {};
}
}
@ -250,20 +270,58 @@ bool isSILModifier(fcitx::KeySym key)
void SILState::handleAlphaKey(fcitx::Key key)
{
// TODO: Don't make this a special case, have a better system for handling
// this!
if (key.check(FcitxKey_colon)) {
m_buffer.type("ː");
// This ignores all non-alpha keys, with built-in flags and by banning
// modifiers ranges.
if (key.isModifier() || key.isCursorMove() || key.hasModifier() ||
((key.sym() & 0xff00) == 0xff00 || (key.sym() & 0xff00) == 0xfe00))
return;
if (keyToRepeatConversion.contains(key.sym())) {
auto keyConversions = keyToRepeatConversion.at(key.sym());
if (m_repeatedKeyCount == 0) {
m_buffer.type(keyConversions[m_repeatedKeyCount++]);
m_repeatedKey = key.sym();
} else {
if (m_repeatedKey == key.sym()) {
if (m_repeatedKeyCount >= keyConversions.size()) {
m_buffer.type(keyConversions[0]);
m_repeatedKeyCount = 1;
return;
}
for (size_t i = 0;
i < keyConversions[m_repeatedKeyCount - 1].size();
++i)
m_buffer.backspace();
m_buffer.type(keyConversions[m_repeatedKeyCount++]);
return;
}
m_buffer.type(keyConversions[0]);
m_repeatedKey = key.sym();
m_repeatedKeyCount = 0;
}
return;
}
if (!isSILModifier(key.sym()) || getLastCharacter().empty()) {
m_repeatedKeyCount = 0;
m_repeatedKey = FcitxKey_None;
auto lastCharacter = getLastCharacter();
if (key.sym() == FcitxKey_asciicircum &&
superscripts.contains(lastCharacter)) {
m_buffer.backspace();
m_buffer.type(superscripts.at(lastCharacter));
return;
}
if (!isSILModifier(key.sym()) || lastCharacter.empty()) {
m_buffer.type(key.sym());
return;
}
if (isSILModifier(key.sym())) {
auto ipaChar = getIPAForSIL(getLastCharacter(), key.sym());
auto ipaChar = getIPAForSIL(lastCharacter, key.sym());
if (ipaChar) {
m_buffer.backspace();
m_buffer.type(*ipaChar);

View file

@ -45,6 +45,9 @@ class SILState : public fcitx::InputContextProperty
SILEngine* m_engine;
fcitx::InputContext* m_ic;
fcitx::InputBuffer m_buffer{{fcitx::InputBufferOption::NoOption}};
fcitx::KeySym m_repeatedKey = FcitxKey_None;
uint16_t m_repeatedKeyCount = 0;
};
class SILEngine : public fcitx::InputMethodEngineV2