diff --git a/src/varnam_engine.cpp b/src/varnam_engine.cpp index 548a234..16b387b 100644 --- a/src/varnam_engine.cpp +++ b/src/varnam_engine.cpp @@ -2,11 +2,8 @@ #include "varnam_state.h" #include "varnam_utils.h" -#include -#include #include #include -#include extern "C" { #include @@ -36,13 +33,13 @@ void VarnamEngine::activate(const InputMethodEntry &entry, #ifdef DEBUG_MODE VARNAM_INFO() << "activate scheme:" << entry.uniqueName(); #endif - - char *schemeName = (char *)entry.uniqueName().c_str(); + char *schemeName = const_cast(entry.uniqueName().c_str()); int rv = varnam_init_from_id(schemeName, &varnam_handle); if (rv != VARNAM_SUCCESS) { VARNAM_WARN() << "Failed to initialize Varnam"; throw std::runtime_error("failed to initialize varnam"); } + varnam_config(varnam_handle, VARNAM_CONFIG_SET_DICTIONARY_MATCH_EXACT, config_.strictlyFollowScheme.value()); varnam_config(varnam_handle, VARNAM_CONFIG_SET_DICTIONARY_SUGGESTIONS_LIMIT, diff --git a/src/varnam_state.cpp b/src/varnam_state.cpp index 83e4c89..c8c15be 100644 --- a/src/varnam_state.cpp +++ b/src/varnam_state.cpp @@ -33,8 +33,8 @@ VarnamState::~VarnamState() { std::string VarnamState::bufferToString() { std::string str; std::stringstream strstream; - for (auto c : buffer_) { - strstream << c; + for (auto ch : buffer_) { + strstream << ch; } str.assign(strstream.str()); return str; @@ -75,37 +75,14 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) { << keyEvent.key().toString(KeyStringFormat::Localized); #endif auto key = keyEvent.key(); - auto states = keyEvent.rawKey().states() & - KeyStates{KeyState::Mod1, KeyState::CapsLock, KeyState::Shift, - KeyState::Ctrl, KeyState::Super}; - if (states.test(KeyState::Super)) { - states |= KeyState::Super2; - } - // filter control key event - if (keyEvent.rawKey().check(FcitxKey_Control_L) || - keyEvent.rawKey().check(FcitxKey_Control_R)) { - keyEvent.filter(); - return; - } - // filter shift key event - if (keyEvent.rawKey().check(FcitxKey_Shift_L) || - keyEvent.rawKey().check(FcitxKey_Shift_R)) { - keyEvent.filter(); - return; - } - // filter alt key event - if (keyEvent.rawKey().check(FcitxKey_Alt_L) || - keyEvent.rawKey().check(FcitxKey_Alt_R)) { - keyEvent.filter(); - return; - } - // filter super key event - if (keyEvent.rawKey().check(FcitxKey_Super_L) || - keyEvent.rawKey().check(FcitxKey_Super_R)) { + + // filter modififer keys + if (key.checkKeyList(keyListToFilter)) { keyEvent.filter(); return; } - // handle candidate selection through modifier + index key + + // handle candidate selection through index key if (!buffer_.empty() && key.isDigit()) { if (auto candidateList = ic_->inputPanel().candidateList(); candidateList && candidateList->size()) { @@ -117,12 +94,13 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) { return; } } - if (states.test(KeyState::Ctrl)) { + + if (key.states().test(KeyState::Ctrl)) { if (buffer_.empty()) { keyEvent.filter(); return; } - if (keyEvent.rawKey().sym() == FcitxKey_Delete) { + if (key.sym() == FcitxKey_Delete) { if (preedit_.empty()) { keyEvent.filter(); return; @@ -162,14 +140,15 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) { return; } - switch (keyEvent.rawKey().sym()) { + switch (key.sym()) { case FcitxKey_space: case FcitxKey_Tab: case FcitxKey_Return: - cursor = 0; - bufferPos = 0; - utfCharPos = 0; - commitPreedit(keyEvent.rawKey().sym()); + if (buffer_.empty()) { + keyEvent.filter(); + return; + } + commitPreedit(key.sym()); updateUI(); keyEvent.filterAndAccept(); return; @@ -184,17 +163,15 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) { return; } if (cursor > 0) { - cursor -= getNumOfUTFCharUnits(u32_preedit[utfCharPos]); - if (cursor < 0) { - cursor = 0; + unsigned int offset = getNumOfUTFCharUnits(u32_preedit[utfCharPos]); + if (cursor >= offset) { + cursor -= offset; } - --bufferPos; - if (bufferPos < 0) { - bufferPos = 0; + if (bufferPos > 0) { + --bufferPos; } - --utfCharPos; - if (utfCharPos < 0) { - utfCharPos = 0; + if (utfCharPos > 0) { + --utfCharPos; } #ifdef DEBUG_MODE VARNAM_INFO() << "[left] cursor at:" << cursor @@ -210,10 +187,10 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) { keyEvent.filter(); return; } - if (bufferPos < buffer_.size()) { + if (bufferPos < (buffer_.size() - 1)) { ++bufferPos; } - if (utfCharPos < u32_preedit.size()) { + if (utfCharPos < (u32_preedit.size() - 1)) { ++utfCharPos; } if (cursor < preedit_.textLength()) { @@ -237,9 +214,6 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) { keyEvent.filter(); return; } - if (cursor > 0) { - --cursor; - } // [TODO] use cursor position to remove elements buffer_.pop_back(); getVarnamResult(); @@ -247,23 +221,13 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) { keyEvent.filterAndAccept(); return; case FcitxKey_Delete: - if (preedit_.empty()) { - keyEvent.filter(); - return; - } - // [TODO] - if (ic_->surroundingText().selectedText().length() > 0) { - ic_->deleteSurroundingText( - -ic_->surroundingText().cursor(), - ic_->surroundingText().selectedText().length()); - ic_->updateSurroundingText(); - keyEvent.filterAndAccept(); - return; - } + keyEvent.filter(); return; case FcitxKey_Home: + keyEvent.filter(); return; case FcitxKey_End: + keyEvent.filter(); return; default: break; @@ -313,7 +277,7 @@ void VarnamState::setLookupTable() { candidates_p->setPageSize(engine_->getConfig()->pageSize.value()); int count = varray_length(result_); for (int i = 0; i < count; i++) { - vword *word = (vword *)varray_get(result_, i); + vword *word = static_cast(varray_get(result_, i)); candidates_p->append(engine_, word->text, i); } std::string userInput = bufferToString(); @@ -374,33 +338,19 @@ void VarnamState::selectCandidate(int index) { void VarnamState::commitPreedit(const FcitxKeySym &key) { std::string stringToCommit; - if (buffer_.empty()) { - switch (key) { - case FcitxKey_space: - break; - case FcitxKey_Tab: - stringToCommit = '\t'; - break; - case FcitxKey_Return: - stringToCommit = '\n'; - break; - default: - return; - } - } else { - stringToCommit.assign(preedit_.toStringForCommit()); - if (!stringToCommit.empty() && - engine_->getConfig()->shouldLearnWords.value()) { + stringToCommit.assign(preedit_.toStringForCommit()); + if (!stringToCommit.empty() && + engine_->getConfig()->shouldLearnWords.value()) { #ifdef DEBUG_MODE - VARNAM_INFO() << "learn word:" << preedit_.toString(); + VARNAM_INFO() << "learn word:" << preedit_.toString(); #endif - std::string wordToLearn( - preedit_.toStringForCommit()); // [TODO] try unique_ptr - std::thread learnThread(varnam_learn_word, engine_->getVarnamHandle(), - std::move(wordToLearn), 0); - learnThread.detach(); - } + std::string wordToLearn( + preedit_.toStringForCommit()); // [TODO] try unique_ptr + std::thread learnThread(varnam_learn_word, engine_->getVarnamHandle(), + std::move(wordToLearn), 0); + learnThread.detach(); } + if (isWordBreak(key)) { stringToCommit = stringutils::concat(stringToCommit, getWordBreakChar(key)); } @@ -409,10 +359,7 @@ void VarnamState::commitPreedit(const FcitxKeySym &key) { << getWordBreakChar(key); #endif ic_->commitString(stringToCommit); - buffer_.clear(); - preedit_.clear(); - bufferPos = 0; - cursor = 0; + reset(); } void VarnamState::updateUI() { @@ -430,6 +377,9 @@ void VarnamState::updateUI() { return; } first_res = static_cast(varray_get(result_, 0)); + if (first_res == nullptr) { + return; + } std::string preedit_res(first_res->text); if (preedit_res.empty()) { return; diff --git a/src/varnam_state.h b/src/varnam_state.h index da18771..ac13048 100644 --- a/src/varnam_state.h +++ b/src/varnam_state.h @@ -4,11 +4,8 @@ #include "varnam_candidate.h" #include -#include -#include #include #include -#include extern "C" { #include @@ -22,9 +19,9 @@ class VarnamState : public InputContextProperty { private: // Private Variables - int cursor; - int bufferPos; - int utfCharPos; + unsigned int cursor; + unsigned int bufferPos; + unsigned int utfCharPos; InputContext *ic_; VarnamEngine *engine_; diff --git a/src/varnam_utils.cpp b/src/varnam_utils.cpp index e903bcd..cf73a9e 100644 --- a/src/varnam_utils.cpp +++ b/src/varnam_utils.cpp @@ -1,5 +1,4 @@ #include "varnam_utils.h" -#include extern "C" { #include @@ -84,20 +83,21 @@ int getNumOfUTFCharUnits(char32_t code_point) { return 4; } else { // Invalid Unicode code point - return -1; + return 0; } } -void varnam_learn_word(int varnam_handle_id, std::string word_, int weight) { - char *word = (char *)word_.c_str(); +void varnam_learn_word(int varnam_handle_id, const std::string &word_, + int weight) { + char *word = const_cast(word_.c_str()); int rv = varnam_learn(varnam_handle_id, word, weight); if (rv != VARNAM_SUCCESS) { VARNAM_WARN() << "Failed to learn word:" << word; } } -void varnam_unlearn_word(int varnam_handle_id, std::string word_) { - char *word = (char *)word_.c_str(); +void varnam_unlearn_word(int varnam_handle_id, const std::string &word_) { + char *word = const_cast(word_.c_str()); int rv = varnam_unlearn(varnam_handle_id, word); if (rv != VARNAM_SUCCESS) { VARNAM_WARN() << "Failed to unlearn word:" << word; diff --git a/src/varnam_utils.h b/src/varnam_utils.h index 8ccb6a9..1f8491e 100644 --- a/src/varnam_utils.h +++ b/src/varnam_utils.h @@ -27,6 +27,11 @@ static KeyList selectionKeys = { Key{FcitxKey_9}, Key{FcitxKey_0}, }; +static KeyList keyListToFilter = { + Key{FcitxKey_Shift_L}, Key{FcitxKey_Shift_R}, Key{FcitxKey_Control_L}, + Key{FcitxKey_Control_R}, Key{FcitxKey_Alt_L}, Key{FcitxKey_Alt_R}, + Key{FcitxKey_Super_L}, Key{FcitxKey_Super_R}}; + // check if the input is a word break character bool isWordBreak(FcitxKeySym keyVal, bool inscriptMode = false); @@ -38,10 +43,11 @@ const std::string getWordBreakChar(FcitxKeySym keyVal, int getNumOfUTFCharUnits(char32_t code_point); // varnam learn function, to run on a separate thread -void varnam_learn_word(int varnam_handle_id, std::string word_, int weight); +void varnam_learn_word(int varnam_handle_id, const std::string &word_, + int weight); // varnam unlearn function, to run on a separate thread -void varnam_unlearn_word(int varnam_handle_id, std::string word_); +void varnam_unlearn_word(int varnam_handle_id, const std::string &word_); // check the current key and states against a key list and return the index template