Merge pull request #9072 from keymanapp/fix/core-7377-transform-unbreak-epic-ldml

fix(core): fix ldml transforms 🙀
This commit is contained in:
Steven R. Loomis 2023-06-23 11:58:48 -05:00 committed by GitHub
commit 0e9324074e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -225,77 +225,86 @@ ldml_processor::process_event(
state->actions().push_backspace(KM_KBP_BT_UNKNOWN);
} else {
state->actions().push_backspace(KM_KBP_BT_CHAR, last_char);
state->context().pop_back();
}
state->context().pop_back();
}
break;
default:
// from kmx_processor.cpp
// Construct a context buffer from the items up until the last KM_KBP_CT_MARKER marker
ldml::string_list ctxt;
auto cp = state->context();
// We're only interested in as much of the context as is a KM_KBP_CT_CHAR.
// This will stop at the KM_KBP_CT_MARKER type.
uint8_t last_type = KM_KBP_BT_UNKNOWN;
for (auto c = cp.rbegin(); c != cp.rend(); c++) {
last_type = c->type;
if (last_type != KM_KBP_BT_CHAR) {
break;
}
km::kbp::kmx::char16_single buf;
const int len = km::kbp::kmx::Utf32CharToUtf16(c->character, buf);
const std::u16string str(buf.ch, len);
ctxt.push_front(str); // prepend to string
}
if (last_type != KM_KBP_BT_MARKER) {
// There was no beginning-of-translation marker.
//Add one.
state->context().push_marker(0x0);
state->actions().push_marker(0x0);
}
// Look up the key
const std::u16string str = keys.lookup(vk, modifier_state);
if (str.empty()) {
// not found
state->actions().commit(); // finish up and
return KM_KBP_STATUS_OK; // Nothing to do- no key
}
const std::u32string str32 = kmx::u16string_to_u32string(str);
for(size_t i=0; i<str32.length(); i++) {
state->context().push_character(str32[i]);
state->actions().push_character(str32[i]);
}
// add the newly added char
ctxt.push_back(str);
// Now process transforms
std::u16string outputString;
// Process the transforms
if (!!transforms) {
{
// adapted from kmx_processor.cpp
// TODO-LDML: unroll ctxt into a str
std::u16string ctxtstr;
for (size_t i = 0; i < ctxt.size(); i++) {
ctxtstr.append(ctxt[i]);
}
const size_t matchedContext = transforms->apply(ctxtstr, outputString);
/** a copy of the current/changed context, for transform use */
ldml::string_list ctxt;
if (matchedContext > 0) {
// Found something.
// Now, clear out the old context
for (size_t i = 0; i < matchedContext; i++) {
state->context().pop_back(); // Pop off last
auto deletedChar = ctxt[ctxt.size() - i - 1][0];
state->actions().push_backspace(KM_KBP_BT_CHAR, deletedChar); // Cause prior char to be removed
// Construct a context buffer of all the KM_KBP_BT_CHAR items
// Extract the context into 'ctxt' for transforms to process
if (!!transforms) {
// if no transforms, no reason to do this extraction
auto &cp = state->context();
// We're only interested in as much of the context as is a KM_KBP_BT_CHAR.
uint8_t last_type = KM_KBP_BT_UNKNOWN;
for (auto c = cp.rbegin(); c != cp.rend(); c++) {
last_type = c->type;
if (last_type != KM_KBP_BT_CHAR) {
// not a char, get out
break;
}
// extract UTF-32 to 1 or 2 UTF-16 chars in a string
km::kbp::kmx::char16_single buf;
const int len = km::kbp::kmx::Utf32CharToUtf16(c->character, buf);
const std::u16string str(buf.ch, len);
ctxt.push_front(str); // prepend to string
}
// Now, add in the updated text
const std::u32string outstr32 = kmx::u16string_to_u32string(outputString);
for (size_t i = 0; i < outstr32.length(); i++) {
state->context().push_character(outstr32[i]);
state->actions().push_character(outstr32[i]);
}
// Look up the key
const std::u16string str = keys.lookup(vk, modifier_state);
if (str.empty()) {
// not found
state->actions().push_invalidate_context();
state->actions().push_emit_keystroke();
break; // ----- commit and exit
}
// found the correct string - push it into the context and actions
const std::u32string str32 = kmx::u16string_to_u32string(str);
for(size_t i=0; i<str32.length(); i++) {
state->context().push_character(str32[i]);
state->actions().push_character(str32[i]);
}
// Now process transforms
// Process the transforms
if (!!transforms) {
// add the newly added char to ctxt
ctxt.push_back(str);
std::u16string outputString;
// TODO-LDML: unroll ctxt into a str. Would be better to have transforms be able to process a vector
std::u16string ctxtstr;
for (size_t i = 0; i < ctxt.size(); i++) {
ctxtstr.append(ctxt[i]);
}
const size_t matchedContext = transforms->apply(ctxtstr, outputString);
if (matchedContext > 0) {
// Found something.
// Now, clear out the old context
for (size_t i = 0; i < matchedContext; i++) {
state->context().pop_back(); // Pop off last
auto deletedChar = ctxt[ctxt.size() - i - 1][0];
state->actions().push_backspace(KM_KBP_BT_CHAR, deletedChar); // Cause prior char to be removed
}
// Now, add in the updated text
const std::u32string outstr32 = kmx::u16string_to_u32string(outputString);
for (size_t i = 0; i < outstr32.length(); i++) {
state->context().push_character(outstr32[i]);
state->actions().push_character(outstr32[i]);
}
}
}
}
}
// end of normal processing: commit and exit
state->actions().commit();
} catch (std::bad_alloc &) {
state->actions().clear();