diff --git a/CMakeLists.txt b/CMakeLists.txt index 567f1fe..5cf641e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.6) project(fcitx5-anthy VERSION 5.1.6) -set(REQUIRED_FCITX_VERSION 5.1.12) +set(REQUIRED_FCITX_VERSION 5.1.13) find_package(ECM 1.0.0 REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) include(FeatureSummary) diff --git a/src/action.cpp b/src/action.cpp index ef944a5..6572726 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -9,29 +9,37 @@ #include "action.h" #include "utils.h" #include +#include +#include +#include +#include +#include +#include -Action::Action() - : name_(""), performFunction_(nullptr), keyBindings_(nullptr) {} +Action::Action() : performFunction_(nullptr), keyBindings_(nullptr) {} -Action::Action(const std::string &name, const fcitx::KeyList &hotkey, PMF pmf) - : name_(name), performFunction_(pmf), keyBindings_(&hotkey) {} +Action::Action(std::string name, const fcitx::KeyList &hotkey, + std::function pmf) + : name_(std::move(name)), performFunction_(std::move(pmf)), + keyBindings_(&hotkey) {} -bool Action::perform(AnthyState *performer) { +bool Action::perform() { if (performFunction_) { - return (performer->*performFunction_)(); + return performFunction_(); } return false; } -bool Action::perform(AnthyState *performer, const fcitx::KeyEvent &key) { - if (!performFunction_) +bool Action::perform(const fcitx::KeyEvent &key) { + if (!performFunction_) { return false; + } if (!matchKeyEvent(key)) { return false; } - return (performer->*performFunction_)(); + return performFunction_(); } bool Action::matchKeyEvent(const fcitx::KeyEvent &key) { diff --git a/src/action.h b/src/action.h index b419673..2dce197 100644 --- a/src/action.h +++ b/src/action.h @@ -9,7 +9,10 @@ #define _FCITX5_ANTHY_ACTION_H_ #include +#include +#include #include +#include #include #define ACTION_CONFIG_CIRCLE_INPUT_MODE_KEY "CircleInputModeKey" @@ -92,18 +95,16 @@ class AnthyState; -typedef bool (AnthyState::*PMF)(); - class Action { public: Action(); - Action(const std::string &name, const fcitx::KeyList &hotkey, PMF pmf); + Action(std::string name, const fcitx::KeyList &hotkey, + std::function pmf); FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITHOUT_SPEC(Action); -public: - bool perform(AnthyState *performer); - bool perform(AnthyState *performer, const fcitx::KeyEvent &key); + bool perform(); + bool perform(const fcitx::KeyEvent &key); // bool operator<(const Action &b) { return name_ < b.name_; } @@ -113,7 +114,7 @@ class Action { private: std::string name_; - PMF performFunction_; + std::function performFunction_; const fcitx::KeyList *keyBindings_; }; diff --git a/src/config.h b/src/config.h index 5ab9268..c8c269b 100644 --- a/src/config.h +++ b/src/config.h @@ -11,7 +11,10 @@ #include #include #include +#include +#include #include +#include namespace fcitx { FCITX_CONFIG_ENUM_NAME_WITH_I18N(CandidateLayoutHint, N_("Not Set"), @@ -80,6 +83,11 @@ enum class TenKeyType { FCITX_CONFIG_ENUM_NAME_WITH_I18N(TenKeyType, N_("Wide"), N_("Half"), N_("Follow mode")); +enum class PeriodBehavior { None, Convert, Commit }; + +FCITX_CONFIG_ENUM_NAME_WITH_I18N(PeriodBehavior, N_("None"), N_("Convert"), + N_("Commit")); + struct AnthyKeyProfile { fcitx::KeyList hk_CONVERT; @@ -202,6 +210,10 @@ FCITX_CONFIGURATION( fcitx::OptionWithAnnotation tenKeyType{this, "TenKeyType", _("Ten key type"), TenKeyType::FOLLOWMODE}; + fcitx::OptionWithAnnotation + periodBehavior{this, "PeriodBehavior", + _("Behavior on a comma or a period"), + PeriodBehavior::None}; fcitx::Option learnOnManualCommit{this, "LearnOnManualCommit", _("Learn on manual commit"), true}; fcitx::Option learnOnAutoCommit{this, "LearnOnAutoCommit", diff --git a/src/conversion.cpp b/src/conversion.cpp index 0bdefa2..a598a77 100644 --- a/src/conversion.cpp +++ b/src/conversion.cpp @@ -6,12 +6,23 @@ * */ #include "conversion.h" +#include "reading.h" #include "state.h" #include "utils.h" +#include +#include +#include #include #include +#include #include +#include #include +#include +#include +#include +#include +#include static void rotateCase(std::string &str); @@ -20,7 +31,8 @@ static void rotateCase(std::string &str); // ConversionSegment::ConversionSegment(std::string str, int cand_id, unsigned int reading_len) - : string_(str), candidateId_(cand_id), readingLen_(reading_len) {} + : string_(std::move(str)), candidateId_(cand_id), readingLen_(reading_len) { +} const std::string &ConversionSegment::string() const { return string_; } @@ -29,7 +41,7 @@ int ConversionSegment::candidateId() const { return candidateId_; } unsigned int ConversionSegment::readingLength() const { return readingLen_; } void ConversionSegment::set(std::string str, int cand_id) { - string_ = str; + string_ = std::move(str); candidateId_ = cand_id; } @@ -53,8 +65,9 @@ Conversion::~Conversion() = default; // void Conversion::convert(std::string source, CandidateType ctype, bool single_segment) { - if (isConverting()) + if (isConverting()) { return; + } clear(); @@ -64,17 +77,19 @@ void Conversion::convert(std::string source, CandidateType ctype, struct anthy_conv_stat conv_stat; anthy_get_stat(anthyContext_.get(), &conv_stat); if (conv_stat.nr_segment <= 0) { - dest = source; + dest = std::move(source); anthy_set_string(anthyContext_.get(), dest.c_str()); } - if (single_segment) + if (single_segment) { joingAllSegments(); + } // get information about conversion string anthy_get_stat(anthyContext_.get(), &conv_stat); - if (conv_stat.nr_segment <= 0) + if (conv_stat.nr_segment <= 0) { return; + } // select first segment curSegment_ = 0; @@ -108,10 +123,11 @@ void Conversion::predict() { struct anthy_prediction_stat ps; anthy_get_prediction_stat(anthyContext_.get(), &ps); - if (ps.nr_prediction > 0) + if (ps.nr_prediction > 0) { predicting_ = true; - else + } else { anthy_reset_context(anthyContext_.get()); + } #endif /* HAS_ANTHY_PREDICTION */ } @@ -139,8 +155,7 @@ void Conversion::clear(int segment_id) { int new_start_segment_id = startId_ + segment_id + 1; if (curSegment_ >= 0) { curSegment_ -= new_start_segment_id - startId_; - if (curSegment_ < 0) - curSegment_ = 0; + curSegment_ = std::max(curSegment_, 0); } // adjust offset @@ -156,16 +171,18 @@ void Conversion::clear(int segment_id) { } void Conversion::commit(int segment_id, bool learn) { - if (!isConverting()) + if (!isConverting()) { return; + } // learn for (unsigned int i = startId_; learn && i < segments_.size() && (segment_id < 0 || (int)i <= segment_id); i++) { - if (segments_[i].candidateId() >= 0) + if (segments_[i].candidateId() >= 0) { anthy_commit_segment(anthyContext_.get(), i, segments_[i].candidateId()); + } } clear(segment_id); @@ -180,22 +197,25 @@ bool Conversion::isPredicting() const { return predicting_; } std::string Conversion::get() const { std::string str; - for (auto it = segments_.begin(); it != segments_.end(); it++) + for (auto it = segments_.begin(); it != segments_.end(); it++) { str += it->string(); + } return str; } unsigned int Conversion::length() const { unsigned int len = 0; - for (auto it = segments_.begin(); it != segments_.end(); it++) + for (auto it = segments_.begin(); it != segments_.end(); it++) { len += it->string().length(); + } return len; } unsigned int Conversion::utf8Length() const { unsigned int len = 0; - for (auto it = segments_.begin(); it != segments_.end(); it++) + for (auto it = segments_.begin(); it != segments_.end(); it++) { len += fcitx::utf8::length(it->string()); + } return len; } @@ -232,8 +252,9 @@ void Conversion::updatePreedit() { // segments of the converted sentence // int Conversion::nrSegments() { - if (!isConverting()) + if (!isConverting()) { return 0; + } struct anthy_conv_stat conv_stat; anthy_get_stat(anthyContext_.get(), &conv_stat); @@ -243,24 +264,25 @@ int Conversion::nrSegments() { std::string Conversion::segmentString(int segment_id, int candidate_id) { if (segment_id < 0) { - if (curSegment_ < 0) - return std::string(); - else - segment_id = curSegment_; + if (curSegment_ < 0) { + return {}; + } + segment_id = curSegment_; } struct anthy_conv_stat conv_stat; anthy_get_stat(anthyContext_.get(), &conv_stat); - if (conv_stat.nr_segment <= 0) - return std::string(); + if (conv_stat.nr_segment <= 0) { + return {}; + } if (startId_ < 0 || startId_ >= conv_stat.nr_segment) { - return std::string(); // error + return {}; // error } if (segment_id < 0 || segment_id + startId_ >= conv_stat.nr_segment) { - return std::string(); // error + return {}; // error } // character position of the head of segment. @@ -273,10 +295,11 @@ std::string Conversion::segmentString(int segment_id, int candidate_id) { int real_seg = segment_id + startId_; int cand; - if (candidate_id <= FCITX_ANTHY_LAST_SPECIAL_CANDIDATE) + if (candidate_id <= FCITX_ANTHY_LAST_SPECIAL_CANDIDATE) { cand = segments_[segment_id].candidateId(); - else + } else { cand = candidate_id; + } // get information of this segment struct anthy_segment_stat seg_stat; @@ -291,22 +314,24 @@ std::string Conversion::segmentString(int segment_id, int candidate_id) { int len = anthy_get_segment(anthyContext_.get(), real_seg, cand, nullptr, 0); if (len > 0) { - char buf[len + 1]; - anthy_get_segment(anthyContext_.get(), real_seg, cand, buf, + std::vector buf; + buf.resize(len + 1); + anthy_get_segment(anthyContext_.get(), real_seg, cand, buf.data(), len + 1); - buf[len] = '\0'; - segment_str = buf; + buf.back() = '\0'; + segment_str = buf.data(); } } return segment_str; } -int Conversion::selectedSegment() { return curSegment_; } +int Conversion::selectedSegment() const { return curSegment_; } void Conversion::selectSegment(int segment_id) { - if (!isConverting()) + if (!isConverting()) { return; + } if (segment_id < 0) { curSegment_ = -1; @@ -330,22 +355,24 @@ void Conversion::selectSegment(int segment_id) { } int Conversion::segmentSize(int segment_id) { - if (!isConverting()) + if (!isConverting()) { return -1; + } struct anthy_conv_stat conv_stat; anthy_get_stat(anthyContext_.get(), &conv_stat); if (segment_id < 0) { - if (curSegment_ < 0) + if (curSegment_ < 0) { return -1; - else - segment_id = curSegment_; + } + segment_id = curSegment_; } int real_segment_id = segment_id + startId_; - if (real_segment_id >= conv_stat.nr_segment) + if (real_segment_id >= conv_stat.nr_segment) { return -1; + } struct anthy_segment_stat seg_stat; anthy_get_segment_stat(anthyContext_.get(), real_segment_id, &seg_stat); @@ -354,10 +381,12 @@ int Conversion::segmentSize(int segment_id) { } void Conversion::resizeSegment(int relative_size, int segment_id) { - if (isPredicting()) + if (isPredicting()) { return; - if (!isConverting()) + } + if (!isConverting()) { return; + } struct anthy_conv_stat conv_stat; anthy_get_stat(anthyContext_.get(), &conv_stat); @@ -365,19 +394,19 @@ void Conversion::resizeSegment(int relative_size, int segment_id) { int real_segment_id; if (segment_id < 0) { - if (curSegment_ < 0) + if (curSegment_ < 0) { return; - else - segment_id = curSegment_; + } + segment_id = curSegment_; real_segment_id = segment_id + startId_; } else { real_segment_id = segment_id + startId_; - if (curSegment_ > segment_id) - curSegment_ = segment_id; + curSegment_ = std::min(curSegment_, segment_id); } - if (real_segment_id >= conv_stat.nr_segment) + if (real_segment_id >= conv_stat.nr_segment) { return; + } // do resize anthy_resize_segment(anthyContext_.get(), real_segment_id, relative_size); @@ -397,10 +426,10 @@ void Conversion::resizeSegment(int relative_size, int segment_id) { unsigned int Conversion::segmentPosition(int segment_id) { if (segment_id < 0) { - if (curSegment_ < 0) + if (curSegment_ < 0) { return length(); - else - segment_id = curSegment_; + } + segment_id = curSegment_; } unsigned int pos = 0; @@ -420,7 +449,7 @@ class AnthyCandidate : public fcitx::CandidateWord { setText(fcitx::Text(std::move(str))); } - void select(fcitx::InputContext *) const override { + void select(fcitx::InputContext * /*inputContext*/) const override { anthy_->actionSelectCandidate(idx_); anthy_->updateUI(); } @@ -475,15 +504,15 @@ Conversion::candidates(int segment_id) { if (isPredicting()) { #ifdef HAS_ANTHY_PREDICTION - std::string str; struct anthy_prediction_stat ps; anthy_get_prediction_stat(anthyContext_.get(), &ps); for (int i = 0; i < ps.nr_prediction; i++) { int len = anthy_get_prediction(anthyContext_.get(), i, nullptr, 0); - if (len <= 0) + if (len <= 0) { continue; + } std::vector buf; buf.resize(len + 1); @@ -496,19 +525,21 @@ Conversion::candidates(int segment_id) { struct anthy_conv_stat conv_stat; anthy_get_stat(anthyContext_.get(), &conv_stat); - if (conv_stat.nr_segment <= 0) + if (conv_stat.nr_segment <= 0) { return nullptr; + } if (segment_id < 0) { - if (curSegment_ < 0) + if (curSegment_ < 0) { return nullptr; - else - segment_id = curSegment_; + } + segment_id = curSegment_; } int real_segment_id = segment_id + startId_; - if (real_segment_id >= conv_stat.nr_segment) + if (real_segment_id >= conv_stat.nr_segment) { return nullptr; + } struct anthy_segment_stat seg_stat; anthy_get_segment_stat(anthyContext_.get(), real_segment_id, &seg_stat); @@ -516,8 +547,9 @@ Conversion::candidates(int segment_id) { for (int i = 0; i < seg_stat.nr_candidate; i++) { int len = anthy_get_segment(anthyContext_.get(), real_segment_id, i, nullptr, 0); - if (len <= 0) + if (len <= 0) { continue; + } std::vector buf; buf.resize(len + 1); @@ -544,14 +576,15 @@ int Conversion::selectedCandidate(int segment_id) { anthy_get_prediction_stat(anthyContext_.get(), &ps); - if (ps.nr_prediction <= 0) + if (ps.nr_prediction <= 0) { return -1; + } if (segment_id < 0) { - if (curSegment_ < 0) + if (curSegment_ < 0) { return -1; - else - segment_id = curSegment_; + } + segment_id = curSegment_; } else if (segment_id >= ps.nr_prediction) { return -1; } @@ -564,14 +597,15 @@ int Conversion::selectedCandidate(int segment_id) { anthy_get_stat(anthyContext_.get(), &cs); - if (cs.nr_segment <= 0) + if (cs.nr_segment <= 0) { return -1; + } if (segment_id < 0) { - if (curSegment_ < 0) + if (curSegment_ < 0) { return -1; - else - segment_id = curSegment_; + } + segment_id = curSegment_; } else if (segment_id >= cs.nr_segment) { return -1; } @@ -585,14 +619,16 @@ int Conversion::selectedCandidate(int segment_id) { void Conversion::selectCandidate(int candidate_id, int segment_id) { if (isPredicting()) { #ifdef HAS_ANTHY_PREDICTION - if (candidate_id < FCITX_ANTHY_CANDIDATE_DEFAULT) + if (candidate_id < FCITX_ANTHY_CANDIDATE_DEFAULT) { return; + } struct anthy_prediction_stat ps; anthy_get_prediction_stat(anthyContext_.get(), &ps); - if (ps.nr_prediction <= 0) + if (ps.nr_prediction <= 0) { return; + } if (!isConverting()) { curSegment_ = 0; @@ -606,25 +642,28 @@ void Conversion::selectCandidate(int candidate_id, int segment_id) { #endif /* HAS_ANTHY_PREDICTION */ } else if (isConverting()) { - if (candidate_id <= FCITX_ANTHY_LAST_SPECIAL_CANDIDATE) + if (candidate_id <= FCITX_ANTHY_LAST_SPECIAL_CANDIDATE) { return; + } struct anthy_conv_stat conv_stat; anthy_get_stat(anthyContext_.get(), &conv_stat); - if (conv_stat.nr_segment <= 0) + if (conv_stat.nr_segment <= 0) { return; + } if (segment_id < 0) { - if (curSegment_ < 0) + if (curSegment_ < 0) { return; - else - segment_id = curSegment_; + } + segment_id = curSegment_; } int real_segment_id = segment_id + startId_; - if (segment_id >= conv_stat.nr_segment) + if (segment_id >= conv_stat.nr_segment) { return; + } struct anthy_segment_stat seg_stat; anthy_get_segment_stat(anthyContext_.get(), real_segment_id, &seg_stat); @@ -656,8 +695,9 @@ std::string Conversion::readingSubstr(int segment_id, int candidate_id, int prev_cand = 0; std::string string; - if (segment_id < (int)segments_.size()) + if (segment_id < (int)segments_.size()) { prev_cand = segments_[segment_id].candidateId(); + } switch ((CandidateType)candidate_id) { case FCITX_ANTHY_CANDIDATE_LATIN: @@ -710,25 +750,30 @@ std::string Conversion::readingSubstr(int segment_id, int candidate_id, std::string Conversion::predictionString(int candidate_id) { #ifdef HAS_ANTHY_PREDICTION - if (!isPredicting()) - return std::string(); + if (!isPredicting()) { + return {}; + } struct anthy_prediction_stat ps; anthy_get_prediction_stat(anthyContext_.get(), &ps); - if (ps.nr_prediction <= 0) - return std::string(); + if (ps.nr_prediction <= 0) { + return {}; + } int len = anthy_get_prediction(anthyContext_.get(), candidate_id, nullptr, 0); - if (len <= 0) - return std::string(); + if (len <= 0) { + return {}; + } - char buf[len + 1]; - anthy_get_prediction(anthyContext_.get(), candidate_id, buf, len + 1); - buf[len] = '\0'; + std::vector buf; + buf.resize(len + 1); + anthy_get_prediction(anthyContext_.get(), candidate_id, buf.data(), + len + 1); + buf.back() = '\0'; - std::string cand = buf; + std::string cand = buf.data(); return cand; #else /* HAS_ANTHY_PREDICTION */ @@ -742,10 +787,11 @@ void Conversion::joingAllSegments() { anthy_get_stat(anthyContext_.get(), &conv_stat); int nr_seg = conv_stat.nr_segment - startId_; - if (nr_seg > 1) + if (nr_seg > 1) { anthy_resize_segment(anthyContext_.get(), startId_, 1); - else + } else { break; + } } while (true); } @@ -763,15 +809,18 @@ static void rotateCase(std::string &str) { if (is_mixed) { // Anthy -> anthy, anThy -> anthy - for (unsigned int i = 0; i < str.length(); i++) + for (unsigned int i = 0; i < str.length(); i++) { str[i] = fcitx::charutils::tolower(str[i]); - } else if (isupper(str[0])) { + } + } else if (fcitx::charutils::isupper(str[0])) { // ANTHY -> Anthy - for (unsigned int i = 1; i < str.length(); i++) + for (unsigned int i = 1; i < str.length(); i++) { str[i] = fcitx::charutils::tolower(str[i]); + } } else { // anthy -> ANTHY - for (unsigned int i = 0; i < str.length(); i++) + for (unsigned int i = 0; i < str.length(); i++) { str[i] = fcitx::charutils::toupper(str[i]); + } } } diff --git a/src/conversion.h b/src/conversion.h index 470480f..c8556ba 100644 --- a/src/conversion.h +++ b/src/conversion.h @@ -10,6 +10,12 @@ #include "reading.h" #include +#include +#include +#include +#include +#include +#include class AnthyState; @@ -41,7 +47,7 @@ class ConversionSegment final { int candidateId_; unsigned int readingLen_; }; -typedef std::vector ConversionSegments; +using ConversionSegments = std::vector; class Conversion { public: @@ -71,7 +77,7 @@ class Conversion { std::string segmentString(int segment_id = -1, int candidate_id = FCITX_ANTHY_LAST_SPECIAL_CANDIDATE); - int selectedSegment(); + int selectedSegment() const; void selectSegment(int segment_id); int segmentSize(int segment_id = -1); void resizeSegment(int relative_size, int segment_id = -1); @@ -88,7 +94,6 @@ class Conversion { std::string predictionString(int candidate_id); void joingAllSegments(); -private: AnthyState &state_; // convertors diff --git a/src/default_tables.cpp b/src/default_tables.cpp index 1a0d075..1440efe 100644 --- a/src/default_tables.cpp +++ b/src/default_tables.cpp @@ -7,15 +7,13 @@ */ #include "default_tables.h" +#include #include +#include /* from Suikyo */ -ConvRule fcitx_anthy_romaji_typing_rule[] = { - {"-", "ー", ""}, -#if 0 -{"[", "「", ""}, -{"]", "」", ""}, -#endif +const std::array fcitx_anthy_romaji_typing_rule = { + ConvRule{"-", "ー", ""}, {"a", "あ", ""}, {"i", "い", ""}, {"u", "う", ""}, @@ -37,19 +35,11 @@ ConvRule fcitx_anthy_romaji_typing_rule[] = { {"whi", "うぃ", ""}, {"whe", "うぇ", ""}, {"who", "うぉ", ""}, -#if 0 -{"va", "う゛ぁ", ""}, -{"vi", "う゛ぃ", ""}, -{"vu", "う゛", ""}, -{"ve", "う゛ぇ", ""}, -{"vo", "う゛ぉ", ""}, -#else {"va", "ヴぁ", ""}, {"vi", "ヴぃ", ""}, {"vu", "ヴ", ""}, {"ve", "ヴぇ", ""}, {"vo", "ヴぉ", ""}, -#endif {"ka", "か", ""}, {"ki", "き", ""}, {"ku", "く", ""}, @@ -310,90 +300,54 @@ ConvRule fcitx_anthy_romaji_typing_rule[] = { {"zwo", "ずぉ", ""}, {"lwa", "ゎ", ""}, {"whu", "う", ""}, -#if 0 /* emulate dead key */ -{"\\.", "・", ""}, -{";r", "→", ""}, -{";l", "←", ""}, -{";u", "↑", ""}, -{";d", "↓", ""}, -{";p", "〒", ""}, -{";e", "€", ""}, -{";t", "™", ""}, -{";s", "®", ""}, -{";c", "©", ""}, -#endif - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_romaji_double_consonant_rule[] = { - {"vv", "っ", "v"}, {"xx", "っ", "x"}, {"kk", "っ", "k"}, - {"gg", "っ", "g"}, {"ss", "っ", "s"}, {"zz", "っ", "z"}, - {"jj", "っ", "j"}, {"tt", "っ", "t"}, {"dd", "っ", "d"}, - {"hh", "っ", "h"}, {"ff", "っ", "f"}, {"bb", "っ", "b"}, - {"pp", "っ", "p"}, {"mm", "っ", "m"}, {"yy", "っ", "y"}, - {"rr", "っ", "r"}, {"ww", "っ", "w"}, {"cc", "っ", "c"}, - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_half_symbol_rule[] = { - {",", ",", ""}, {".", ".", ""}, {"!", "!", ""}, - {"\"", "\"", ""}, {"#", "#", ""}, {"$", "$", ""}, - {"%", "%", ""}, {"&", "&", ""}, {"'", "'", ""}, - {"(", "(", ""}, {")", ")", ""}, {"~", "~", ""}, - {"-", "-", ""}, {"=", "=", ""}, {"^", "^", ""}, - {"\\", "\\", ""}, {"|", "|", ""}, {"`", "`", ""}, - {"@", "@", ""}, {"{", "{", ""}, {"[", "[", ""}, - {"+", "+", ""}, {";", ";", ""}, {"*", "*", ""}, - {":", ":", ""}, {"}", "}", ""}, {"]", "]", ""}, - {"<", "<", ""}, {">", ">", ""}, {"?", "?", ""}, - {"/", "/", ""}, {"_", "_", ""}, {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_wide_symbol_rule[] = { - {",", "、", ""}, {".", "。", ""}, {"!", "!", ""}, - {"\"", "”", ""}, {"#", "#", ""}, {"$", "$", ""}, - {"%", "%", ""}, {"&", "&", ""}, {"'", "’", ""}, - {"(", "(", ""}, {")", ")", ""}, {"~", "〜", ""}, - {"-", "ー", ""}, {"=", "=", ""}, {"^", "^", ""}, - {"\\", "\", ""}, {"|", "|", ""}, {"`", "‘", ""}, - {"@", "@", ""}, {"{", "{", ""}, {"[", "「", ""}, - {"+", "+", ""}, {";", ";", ""}, {"*", "*", ""}, - {":", ":", ""}, {"}", "}", ""}, {"]", "」", ""}, - {"<", "<", ""}, {">", ">", ""}, {"?", "?", ""}, - {"/", "/", ""}, {"_", "_", ""}, {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_half_number_rule[] = { - {"1", "1", ""}, - {"2", "2", ""}, - {"3", "3", ""}, - {"4", "4", ""}, - {"5", "5", ""}, - {"6", "6", ""}, - {"7", "7", ""}, - {"8", "8", ""}, - {"9", "9", ""}, - {"0", "0", ""}, - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_wide_number_rule[] = { - {"1", "1", ""}, - {"2", "2", ""}, - {"3", "3", ""}, - {"4", "4", ""}, - {"5", "5", ""}, - {"6", "6", ""}, - {"7", "7", ""}, - {"8", "8", ""}, - {"9", "9", ""}, - {"0", "0", ""}, - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_kana_typing_rule[] = { +}; + +const std::array fcitx_anthy_romaji_double_consonant_rule = { + ConvRule{"vv", "っ", "v"}, {"xx", "っ", "x"}, {"kk", "っ", "k"}, + {"gg", "っ", "g"}, {"ss", "っ", "s"}, {"zz", "っ", "z"}, + {"jj", "っ", "j"}, {"tt", "っ", "t"}, {"dd", "っ", "d"}, + {"hh", "っ", "h"}, {"ff", "っ", "f"}, {"bb", "っ", "b"}, + {"pp", "っ", "p"}, {"mm", "っ", "m"}, {"yy", "っ", "y"}, + {"rr", "っ", "r"}, {"ww", "っ", "w"}, {"cc", "っ", "c"}, +}; + +const std::array fcitx_anthy_half_symbol_rule = { + ConvRule{",", ",", ""}, {".", ".", ""}, {"!", "!", ""}, {"\"", "\"", ""}, + {"#", "#", ""}, {"$", "$", ""}, {"%", "%", ""}, {"&", "&", ""}, + {"'", "'", ""}, {"(", "(", ""}, {")", ")", ""}, {"~", "~", ""}, + {"-", "-", ""}, {"=", "=", ""}, {"^", "^", ""}, {"\\", "\\", ""}, + {"|", "|", ""}, {"`", "`", ""}, {"@", "@", ""}, {"{", "{", ""}, + {"[", "[", ""}, {"+", "+", ""}, {";", ";", ""}, {"*", "*", ""}, + {":", ":", ""}, {"}", "}", ""}, {"]", "]", ""}, {"<", "<", ""}, + {">", ">", ""}, {"?", "?", ""}, {"/", "/", ""}, {"_", "_", ""}, +}; + +const std::array fcitx_anthy_wide_symbol_rule = { + ConvRule{",", "、", ""}, {".", "。", ""}, {"!", "!", ""}, {"\"", "”", ""}, + {"#", "#", ""}, {"$", "$", ""}, {"%", "%", ""}, {"&", "&", ""}, + {"'", "’", ""}, {"(", "(", ""}, {")", ")", ""}, {"~", "〜", ""}, + {"-", "ー", ""}, {"=", "=", ""}, {"^", "^", ""}, {"\\", "\", ""}, + {"|", "|", ""}, {"`", "‘", ""}, {"@", "@", ""}, {"{", "{", ""}, + {"[", "「", ""}, {"+", "+", ""}, {";", ";", ""}, {"*", "*", ""}, + {":", ":", ""}, {"}", "}", ""}, {"]", "」", ""}, {"<", "<", ""}, + {">", ">", ""}, {"?", "?", ""}, {"/", "/", ""}, {"_", "_", ""}, +}; + +const std::array fcitx_anthy_half_number_rule = { + ConvRule{"1", "1", ""}, {"2", "2", ""}, {"3", "3", ""}, {"4", "4", ""}, + {"5", "5", ""}, {"6", "6", ""}, {"7", "7", ""}, {"8", "8", ""}, + {"9", "9", ""}, {"0", "0", ""}, +}; + +const std::array fcitx_anthy_wide_number_rule = { + ConvRule{"1", "1", ""}, {"2", "2", ""}, {"3", "3", ""}, {"4", "4", ""}, + {"5", "5", ""}, {"6", "6", ""}, {"7", "7", ""}, {"8", "8", ""}, + {"9", "9", ""}, {"0", "0", ""}, +}; + +const std::array fcitx_anthy_kana_typing_rule = { // no modifiers keys - {"1", "ぬ", ""}, + ConvRule{"1", "ぬ", ""}, {"2", "", "ふ"}, {"3", "あ", ""}, {"4", "う", ""}, @@ -469,9 +423,6 @@ ConvRule fcitx_anthy_kana_typing_rule[] = { {"O", "ら", ""}, {"P", "", "せ"}, {"`", "゛", ""}, -#if 0 -{"{", "「", ""}, -#endif {"A", "", "ち"}, {"S", "", "と"}, @@ -484,9 +435,6 @@ ConvRule fcitx_anthy_kana_typing_rule[] = { {"L", "り", ""}, {"+", "れ", ""}, {"*", "ヶ", ""}, -#if 0 -{"}", "」", ""}, -#endif {"Z", "っ", ""}, {"X", "", "さ"}, @@ -495,316 +443,308 @@ ConvRule fcitx_anthy_kana_typing_rule[] = { {"B", "", "こ"}, {"M", "も", ""}, {"N", "み", ""}, -#if 0 -{"?", "・", ""}, -#endif {"_", "ろ", ""}, - {nullptr, nullptr, nullptr}, }; -ConvRule fcitx_anthy_kana_voiced_consonant_rule[] = { - {"か@", "が", ""}, {"き@", "ぎ", ""}, {"く@", "ぐ", ""}, - {"け@", "げ", ""}, {"こ@", "ご", ""}, {"さ@", "ざ", ""}, - {"し@", "じ", ""}, {"す@", "ず", ""}, {"せ@", "ぜ", ""}, - {"そ@", "ぞ", ""}, {"た@", "だ", ""}, {"ち@", "ぢ", ""}, - {"つ@", "づ", ""}, {"て@", "で", ""}, {"と@", "ど", ""}, - {"は@", "ば", ""}, {"ひ@", "び", ""}, {"ふ@", "ぶ", ""}, - {"へ@", "べ", ""}, {"ほ@", "ぼ", ""}, {"か`", "が", ""}, - {"き`", "ぎ", ""}, {"く`", "ぐ", ""}, {"け`", "げ", ""}, - {"こ`", "ご", ""}, {"さ`", "ざ", ""}, {"し`", "じ", ""}, - {"す`", "ず", ""}, {"せ`", "ぜ", ""}, {"そ`", "ぞ", ""}, - {"た`", "だ", ""}, {"ち`", "ぢ", ""}, {"つ`", "づ", ""}, - {"て`", "で", ""}, {"と`", "ど", ""}, {"は`", "ば", ""}, - {"ひ`", "び", ""}, {"ふ`", "ぶ", ""}, {"へ`", "べ", ""}, - {"ほ`", "ぼ", ""}, {"は[", "ぱ", ""}, {"ひ[", "ぴ", ""}, - {"ふ[", "ぷ", ""}, {"へ[", "ぺ", ""}, {"ほ[", "ぽ", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_kana_voiced_consonant_rule = { + ConvRule{"か@", "が", ""}, {"き@", "ぎ", ""}, {"く@", "ぐ", ""}, + {"け@", "げ", ""}, {"こ@", "ご", ""}, {"さ@", "ざ", ""}, + {"し@", "じ", ""}, {"す@", "ず", ""}, {"せ@", "ぜ", ""}, + {"そ@", "ぞ", ""}, {"た@", "だ", ""}, {"ち@", "ぢ", ""}, + {"つ@", "づ", ""}, {"て@", "で", ""}, {"と@", "ど", ""}, + {"は@", "ば", ""}, {"ひ@", "び", ""}, {"ふ@", "ぶ", ""}, + {"へ@", "べ", ""}, {"ほ@", "ぼ", ""}, {"か`", "が", ""}, + {"き`", "ぎ", ""}, {"く`", "ぐ", ""}, {"け`", "げ", ""}, + {"こ`", "ご", ""}, {"さ`", "ざ", ""}, {"し`", "じ", ""}, + {"す`", "ず", ""}, {"せ`", "ぜ", ""}, {"そ`", "ぞ", ""}, + {"た`", "だ", ""}, {"ち`", "ぢ", ""}, {"つ`", "づ", ""}, + {"て`", "で", ""}, {"と`", "ど", ""}, {"は`", "ば", ""}, + {"ひ`", "び", ""}, {"ふ`", "ぶ", ""}, {"へ`", "べ", ""}, + {"ほ`", "ぼ", ""}, {"は[", "ぱ", ""}, {"ひ[", "ぴ", ""}, + {"ふ[", "ぷ", ""}, {"へ[", "ぺ", ""}, {"ほ[", "ぽ", ""}, }; -ConvRule fcitx_anthy_romaji_ja_period_rule[] = { - {".", "。", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_romaji_ja_period_rule = { + ConvRule{".", "。", ""}, }; -ConvRule fcitx_anthy_romaji_ja_comma_rule[] = { - {",", "、", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_romaji_ja_comma_rule = { + ConvRule{",", "、", ""}, }; -ConvRule fcitx_anthy_romaji_wide_period_rule[] = { - {".", ".", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_romaji_wide_period_rule = { + ConvRule{".", ".", ""}, }; -ConvRule fcitx_anthy_romaji_wide_comma_rule[] = { - {",", ",", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_romaji_wide_comma_rule = { + ConvRule{",", ",", ""}, }; -ConvRule fcitx_anthy_romaji_half_period_rule[] = { - {".", ".", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_romaji_half_period_rule = { + ConvRule{".", ".", ""}, }; -ConvRule fcitx_anthy_romaji_half_comma_rule[] = { - {",", ",", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_romaji_half_comma_rule = { + ConvRule{",", ",", ""}, }; -ConvRule fcitx_anthy_kana_ja_period_rule[] = { - {">", "。", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_kana_ja_period_rule = { + ConvRule{">", "。", ""}, }; -ConvRule fcitx_anthy_kana_ja_comma_rule[] = { - {"<", "、", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_kana_ja_comma_rule = { + ConvRule{"<", "、", ""}, }; -ConvRule fcitx_anthy_kana_wide_period_rule[] = { - {">", ".", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_kana_wide_period_rule = { + ConvRule{">", ".", ""}, }; -ConvRule fcitx_anthy_kana_wide_comma_rule[] = { - {"<", ",", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_kana_wide_comma_rule = { + ConvRule{"<", ",", ""}, }; -ConvRule fcitx_anthy_kana_half_period_rule[] = { - {">", ".", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_kana_half_period_rule = { + ConvRule{">", ".", ""}, }; -ConvRule fcitx_anthy_kana_half_comma_rule[] = { - {"<", ",", ""}, - {nullptr, nullptr, nullptr}, +const std::array fcitx_anthy_kana_half_comma_rule = { + ConvRule{"<", ",", ""}, }; -ConvRule fcitx_anthy_romaji_ja_bracket_rule[] = { - {"[", "「", ""}, +const std::array fcitx_anthy_romaji_ja_bracket_rule = { + ConvRule{"[", "「", ""}, {"]", "」", ""}, - {nullptr, nullptr, nullptr}, }; -ConvRule fcitx_anthy_romaji_wide_bracket_rule[] = { - {"[", "[", ""}, +const std::array fcitx_anthy_romaji_wide_bracket_rule = { + ConvRule{"[", "[", ""}, {"]", "]", ""}, - {nullptr, nullptr, nullptr}, }; -ConvRule fcitx_anthy_kana_ja_bracket_rule[] = { - {"{", "「", ""}, +const std::array fcitx_anthy_kana_ja_bracket_rule = { + ConvRule{"{", "「", ""}, {"}", "」", ""}, - {nullptr, nullptr, nullptr}, }; -ConvRule fcitx_anthy_kana_wide_bracket_rule[] = { - {"{", "[", ""}, +const std::array fcitx_anthy_kana_wide_bracket_rule = { + ConvRule{"{", "[", ""}, {"}", "]", ""}, - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_romaji_ja_slash_rule[] = { - {"/", "・", ""}, - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_romaji_wide_slash_rule[] = { - {"/", "/", ""}, - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_kana_ja_slash_rule[] = { - {"?", "・", ""}, - {nullptr, nullptr, nullptr}, -}; - -ConvRule fcitx_anthy_kana_wide_slash_rule[] = { - {"?", "/", ""}, - {nullptr, nullptr, nullptr}, -}; - -HiraganaKatakanaRule fcitx_anthy_hiragana_katakana_table[] = { - {"あ", "ア", "ア"}, - {"い", "イ", "イ"}, - {"う", "ウ", "ウ"}, - {"え", "エ", "エ"}, - {"お", "オ", "オ"}, - {"か", "カ", "カ"}, - {"き", "キ", "キ"}, - {"く", "ク", "ク"}, - {"け", "ケ", "ケ"}, - {"こ", "コ", "コ"}, - {"が", "ガ", "ガ"}, - {"ぎ", "ギ", "ギ"}, - {"ぐ", "グ", "グ"}, - {"げ", "ゲ", "ゲ"}, - {"ご", "ゴ", "ゴ"}, - {"さ", "サ", "サ"}, - {"し", "シ", "シ"}, - {"す", "ス", "ス"}, - {"せ", "セ", "セ"}, - {"そ", "ソ", "ソ"}, - {"ざ", "ザ", "ザ"}, - {"じ", "ジ", "ジ"}, - {"ず", "ズ", "ズ"}, - {"ぜ", "ゼ", "ゼ"}, - {"ぞ", "ゾ", "ゾ"}, - {"た", "タ", "タ"}, - {"ち", "チ", "チ"}, - {"つ", "ツ", "ツ"}, - {"て", "テ", "テ"}, - {"と", "ト", "ト"}, - {"だ", "ダ", "ダ"}, - {"ぢ", "ヂ", "ヂ"}, - {"づ", "ヅ", "ヅ"}, - {"で", "デ", "デ"}, - {"ど", "ド", "ド"}, - {"な", "ナ", "ナ"}, - {"に", "ニ", "ニ"}, - {"ぬ", "ヌ", "ヌ"}, - {"ね", "ネ", "ネ"}, - {"の", "ノ", "ノ"}, - {"は", "ハ", "ハ"}, - {"ひ", "ヒ", "ヒ"}, - {"ふ", "フ", "フ"}, - {"へ", "ヘ", "ヘ"}, - {"ほ", "ホ", "ホ"}, - {"ば", "バ", "バ"}, - {"び", "ビ", "ビ"}, - {"ぶ", "ブ", "ブ"}, - {"べ", "ベ", "ベ"}, - {"ぼ", "ボ", "ボ"}, - {"ぱ", "パ", "パ"}, - {"ぴ", "ピ", "ピ"}, - {"ぷ", "プ", "プ"}, - {"ぺ", "ペ", "ペ"}, - {"ぽ", "ポ", "ポ"}, - {"ま", "マ", "マ"}, - {"み", "ミ", "ミ"}, - {"む", "ム", "ム"}, - {"め", "メ", "メ"}, - {"も", "モ", "モ"}, - {"や", "ヤ", "ヤ"}, - {"ゆ", "ユ", "ユ"}, - {"よ", "ヨ", "ヨ"}, - {"ら", "ラ", "ラ"}, - {"り", "リ", "リ"}, - {"る", "ル", "ル"}, - {"れ", "レ", "レ"}, - {"ろ", "ロ", "ロ"}, - - {"わ", "ワ", "ワ"}, - {"を", "ヲ", "ヲ"}, - {"ん", "ン", "ン"}, - - {"ぁ", "ァ", "ァ"}, - {"ぃ", "ィ", "ィ"}, - {"ぅ", "ゥ", "ゥ"}, - {"ぇ", "ェ", "ェ"}, - {"ぉ", "ォ", "ォ"}, - - {"っ", "ッ", "ッ"}, - - {"ゃ", "ャ", "ャ"}, - {"ゅ", "ュ", "ュ"}, - {"ょ", "ョ", "ョ"}, - - {"ヵ", "ヵ", "カ"}, - {"ヶ", "ヶ", "ケ"}, - - {"ゎ", "ヮ", "ワ"}, - {"ゐ", "ヰ", "ィ"}, - {"ゑ", "ヱ", "ェ"}, - -#if 1 - //{"う゛" "ヴ" "ヴ"}, - {"ヴ", "ヴ", "ヴ"}, -#endif - -#if 1 - {"ー", "ー", "ー"}, - {"、", "、", "、"}, - {"。", "。", "。"}, - {"!", "!", "!"}, - {"”", "”", "\""}, - {"#", "#", "#"}, - {"$", "$", "$"}, - {"%", "%", "%"}, - {"&", "&", "&"}, - {"’", "’", "'"}, - {"(", "(", "("}, - {")", ")", ")"}, - {"〜", "〜", "~"}, - {"=", "=", "="}, - {"^", "^", "^"}, - {"\", "\", "\\"}, - {"|", "|", "|"}, - {"‘", "‘", "`"}, - {"@", "@", "@"}, - {"{", "{", "{"}, - {"「", "「", "「"}, - {"+", "+", "+"}, - {";", ";", ";"}, - {"*", "*", "*"}, - {":", ":", ":"}, - {"}", "}", "}"}, - {"」", "」", "」"}, - {"<", "<", "<"}, - {">", ">", ">"}, - {"?", "?", "?"}, - {"/", "/", "/"}, - {"_", "_", "_"}, -#endif - {nullptr, nullptr, nullptr}, -}; - -WideRule fcitx_anthy_wide_table[] = { - {"a", "a"}, {"b", "b"}, {"c", "c"}, {"d", "d"}, {"e", "e"}, - {"f", "f"}, {"g", "g"}, {"h", "h"}, {"i", "i"}, {"j", "j"}, - {"k", "k"}, {"l", "l"}, {"m", "m"}, {"n", "n"}, {"o", "o"}, - {"p", "p"}, {"q", "q"}, {"r", "r"}, {"s", "s"}, {"t", "t"}, - {"u", "u"}, {"v", "v"}, {"w", "w"}, {"x", "x"}, {"y", "y"}, - {"z", "z"}, {"A", "A"}, {"B", "B"}, {"C", "C"}, {"D", "D"}, - {"E", "E"}, {"F", "F"}, {"G", "G"}, {"H", "H"}, {"I", "I"}, - {"J", "J"}, {"K", "K"}, {"L", "L"}, {"M", "M"}, {"N", "N"}, - {"O", "O"}, {"P", "P"}, {"Q", "Q"}, {"R", "R"}, {"S", "S"}, - {"T", "T"}, {"U", "U"}, {"V", "V"}, {"W", "W"}, {"X", "X"}, - {"Y", "Y"}, {"Z", "Z"}, {"1", "1"}, {"2", "2"}, {"3", "3"}, - {"4", "4"}, {"5", "5"}, {"6", "6"}, {"7", "7"}, {"8", "8"}, - {"9", "9"}, {"0", "0"}, {"-", "−"}, {",", ","}, {".", "."}, - {"!", "!"}, {"\"", "”"}, {"#", "#"}, {"$", "$"}, {"%", "%"}, - {"&", "&"}, {"'", "’"}, {"(", "("}, {")", ")"}, {"~", "〜"}, - {"=", "="}, {"^", "^"}, {"\\", "\"}, {"|", "|"}, {"`", "‘"}, - {"@", "@"}, {"{", "{"}, {"[", "["}, {"+", "+"}, {";", ";"}, - {":", ":"}, {"}", "}"}, {"]", "]"}, {"<", "<"}, {">", ">"}, - {"?", "?"}, {"/", "/"}, {"_", "_"}, {"*", "*"}, {nullptr, nullptr}, -}; - -VoicedConsonantRule fcitx_anthy_voiced_consonant_table[] = { - {"か", "が", ""}, {"き", "ぎ", ""}, {"く", "ぐ", ""}, - {"け", "げ", ""}, {"こ", "ご", ""}, {"さ", "ざ", ""}, - {"し", "じ", ""}, {"す", "ず", ""}, {"せ", "ぜ", ""}, - {"そ", "ぞ", ""}, {"た", "だ", ""}, {"ち", "ぢ", ""}, - {"つ", "づ", ""}, {"て", "で", ""}, {"と", "ど", ""}, - {"は", "ば", "ぱ"}, {"ひ", "び", "ぴ"}, {"ふ", "ぶ", "ぷ"}, - {"へ", "べ", "ぺ"}, {"ほ", "ぼ", "ぽ"}, {nullptr, nullptr, nullptr}, -}; - -KeyCodeToCharRule fcitx_anthy_keypad_table[] = { - {FcitxKey_KP_Equal, "="}, {FcitxKey_KP_Multiply, "*"}, - {FcitxKey_KP_Add, "+"}, {FcitxKey_KP_Separator, ","}, - {FcitxKey_KP_Subtract, "-"}, {FcitxKey_KP_Decimal, "."}, - {FcitxKey_KP_Divide, "/"}, {FcitxKey_KP_0, "0"}, - {FcitxKey_KP_1, "1"}, {FcitxKey_KP_2, "2"}, - {FcitxKey_KP_3, "3"}, {FcitxKey_KP_4, "4"}, - {FcitxKey_KP_5, "5"}, {FcitxKey_KP_6, "6"}, - {FcitxKey_KP_7, "7"}, {FcitxKey_KP_8, "8"}, - {FcitxKey_KP_9, "9"}, {0, nullptr}}; - -KeyCodeToCharRule fcitx_anthy_kana_table[] = { - {FcitxKey_kana_fullstop, "。"}, +}; + +const std::array fcitx_anthy_romaji_ja_slash_rule = { + ConvRule{"/", "・", ""}, +}; + +const std::array fcitx_anthy_romaji_wide_slash_rule = { + ConvRule{"/", "/", ""}, +}; + +const std::array fcitx_anthy_kana_ja_slash_rule = { + ConvRule{"?", "・", ""}, +}; + +const std::array fcitx_anthy_kana_wide_slash_rule = { + ConvRule{"?", "/", ""}, +}; + +const std::array + fcitx_anthy_hiragana_katakana_table = { + HiraganaKatakanaRule{"あ", "ア", "ア"}, + {"い", "イ", "イ"}, + {"う", "ウ", "ウ"}, + {"え", "エ", "エ"}, + {"お", "オ", "オ"}, + {"か", "カ", "カ"}, + {"き", "キ", "キ"}, + {"く", "ク", "ク"}, + {"け", "ケ", "ケ"}, + {"こ", "コ", "コ"}, + {"が", "ガ", "ガ"}, + {"ぎ", "ギ", "ギ"}, + {"ぐ", "グ", "グ"}, + {"げ", "ゲ", "ゲ"}, + {"ご", "ゴ", "ゴ"}, + {"さ", "サ", "サ"}, + {"し", "シ", "シ"}, + {"す", "ス", "ス"}, + {"せ", "セ", "セ"}, + {"そ", "ソ", "ソ"}, + {"ざ", "ザ", "ザ"}, + {"じ", "ジ", "ジ"}, + {"ず", "ズ", "ズ"}, + {"ぜ", "ゼ", "ゼ"}, + {"ぞ", "ゾ", "ゾ"}, + {"た", "タ", "タ"}, + {"ち", "チ", "チ"}, + {"つ", "ツ", "ツ"}, + {"て", "テ", "テ"}, + {"と", "ト", "ト"}, + {"だ", "ダ", "ダ"}, + {"ぢ", "ヂ", "ヂ"}, + {"づ", "ヅ", "ヅ"}, + {"で", "デ", "デ"}, + {"ど", "ド", "ド"}, + {"な", "ナ", "ナ"}, + {"に", "ニ", "ニ"}, + {"ぬ", "ヌ", "ヌ"}, + {"ね", "ネ", "ネ"}, + {"の", "ノ", "ノ"}, + {"は", "ハ", "ハ"}, + {"ひ", "ヒ", "ヒ"}, + {"ふ", "フ", "フ"}, + {"へ", "ヘ", "ヘ"}, + {"ほ", "ホ", "ホ"}, + {"ば", "バ", "バ"}, + {"び", "ビ", "ビ"}, + {"ぶ", "ブ", "ブ"}, + {"べ", "ベ", "ベ"}, + {"ぼ", "ボ", "ボ"}, + {"ぱ", "パ", "パ"}, + {"ぴ", "ピ", "ピ"}, + {"ぷ", "プ", "プ"}, + {"ぺ", "ペ", "ペ"}, + {"ぽ", "ポ", "ポ"}, + {"ま", "マ", "マ"}, + {"み", "ミ", "ミ"}, + {"む", "ム", "ム"}, + {"め", "メ", "メ"}, + {"も", "モ", "モ"}, + {"や", "ヤ", "ヤ"}, + {"ゆ", "ユ", "ユ"}, + {"よ", "ヨ", "ヨ"}, + {"ら", "ラ", "ラ"}, + {"り", "リ", "リ"}, + {"る", "ル", "ル"}, + {"れ", "レ", "レ"}, + {"ろ", "ロ", "ロ"}, + + {"わ", "ワ", "ワ"}, + {"を", "ヲ", "ヲ"}, + {"ん", "ン", "ン"}, + + {"ぁ", "ァ", "ァ"}, + {"ぃ", "ィ", "ィ"}, + {"ぅ", "ゥ", "ゥ"}, + {"ぇ", "ェ", "ェ"}, + {"ぉ", "ォ", "ォ"}, + + {"っ", "ッ", "ッ"}, + + {"ゃ", "ャ", "ャ"}, + {"ゅ", "ュ", "ュ"}, + {"ょ", "ョ", "ョ"}, + + {"ヵ", "ヵ", "カ"}, + {"ヶ", "ヶ", "ケ"}, + + {"ゎ", "ヮ", "ワ"}, + {"ゐ", "ヰ", "ィ"}, + {"ゑ", "ヱ", "ェ"}, + + //{"う゛" "ヴ" "ヴ"}, + {"ヴ", "ヴ", "ヴ"}, + + {"ー", "ー", "ー"}, + {"、", "、", "、"}, + {"。", "。", "。"}, + {"!", "!", "!"}, + {"”", "”", "\""}, + {"#", "#", "#"}, + {"$", "$", "$"}, + {"%", "%", "%"}, + {"&", "&", "&"}, + {"’", "’", "'"}, + {"(", "(", "("}, + {")", ")", ")"}, + {"〜", "〜", "~"}, + {"=", "=", "="}, + {"^", "^", "^"}, + {"\", "\", "\\"}, + {"|", "|", "|"}, + {"‘", "‘", "`"}, + {"@", "@", "@"}, + {"{", "{", "{"}, + {"「", "「", "「"}, + {"+", "+", "+"}, + {";", ";", ";"}, + {"*", "*", "*"}, + {":", ":", ":"}, + {"}", "}", "}"}, + {"」", "」", "」"}, + {"<", "<", "<"}, + {">", ">", ">"}, + {"?", "?", "?"}, + {"/", "/", "/"}, + {"_", "_", "_"}, +}; + +const std::array fcitx_anthy_wide_table = { + WideRule{"a", "a"}, {"b", "b"}, {"c", "c"}, {"d", "d"}, {"e", "e"}, + {"f", "f"}, {"g", "g"}, {"h", "h"}, {"i", "i"}, {"j", "j"}, + {"k", "k"}, {"l", "l"}, {"m", "m"}, {"n", "n"}, {"o", "o"}, + {"p", "p"}, {"q", "q"}, {"r", "r"}, {"s", "s"}, {"t", "t"}, + {"u", "u"}, {"v", "v"}, {"w", "w"}, {"x", "x"}, {"y", "y"}, + {"z", "z"}, {"A", "A"}, {"B", "B"}, {"C", "C"}, {"D", "D"}, + {"E", "E"}, {"F", "F"}, {"G", "G"}, {"H", "H"}, {"I", "I"}, + {"J", "J"}, {"K", "K"}, {"L", "L"}, {"M", "M"}, {"N", "N"}, + {"O", "O"}, {"P", "P"}, {"Q", "Q"}, {"R", "R"}, {"S", "S"}, + {"T", "T"}, {"U", "U"}, {"V", "V"}, {"W", "W"}, {"X", "X"}, + {"Y", "Y"}, {"Z", "Z"}, {"1", "1"}, {"2", "2"}, {"3", "3"}, + {"4", "4"}, {"5", "5"}, {"6", "6"}, {"7", "7"}, {"8", "8"}, + {"9", "9"}, {"0", "0"}, {"-", "−"}, {",", ","}, {".", "."}, + {"!", "!"}, {"\"", "”"}, {"#", "#"}, {"$", "$"}, {"%", "%"}, + {"&", "&"}, {"'", "’"}, {"(", "("}, {")", ")"}, {"~", "〜"}, + {"=", "="}, {"^", "^"}, {"\\", "\"}, {"|", "|"}, {"`", "‘"}, + {"@", "@"}, {"{", "{"}, {"[", "["}, {"+", "+"}, {";", ";"}, + {":", ":"}, {"}", "}"}, {"]", "]"}, {"<", "<"}, {">", ">"}, + {"?", "?"}, {"/", "/"}, {"_", "_"}, {"*", "*"}, +}; + +const std::array fcitx_anthy_voiced_consonant_table = { + VoicedConsonantRule{"か", "が", ""}, + {"き", "ぎ", ""}, + {"く", "ぐ", ""}, + {"け", "げ", ""}, + {"こ", "ご", ""}, + {"さ", "ざ", ""}, + {"し", "じ", ""}, + {"す", "ず", ""}, + {"せ", "ぜ", ""}, + {"そ", "ぞ", ""}, + {"た", "だ", ""}, + {"ち", "ぢ", ""}, + {"つ", "づ", ""}, + {"て", "で", ""}, + {"と", "ど", ""}, + {"は", "ば", "ぱ"}, + {"ひ", "び", "ぴ"}, + {"ふ", "ぶ", "ぷ"}, + {"へ", "べ", "ぺ"}, + {"ほ", "ぼ", "ぽ"}}; + +const std::array fcitx_anthy_keypad_table = { + KeyCodeToCharRule{FcitxKey_KP_Equal, "="}, + {FcitxKey_KP_Multiply, "*"}, + {FcitxKey_KP_Add, "+"}, + {FcitxKey_KP_Separator, ","}, + {FcitxKey_KP_Subtract, "-"}, + {FcitxKey_KP_Decimal, "."}, + {FcitxKey_KP_Divide, "/"}, + {FcitxKey_KP_0, "0"}, + {FcitxKey_KP_1, "1"}, + {FcitxKey_KP_2, "2"}, + {FcitxKey_KP_3, "3"}, + {FcitxKey_KP_4, "4"}, + {FcitxKey_KP_5, "5"}, + {FcitxKey_KP_6, "6"}, + {FcitxKey_KP_7, "7"}, + {FcitxKey_KP_8, "8"}, + {FcitxKey_KP_9, "9"}, +}; + +const std::array fcitx_anthy_kana_table = { + KeyCodeToCharRule{FcitxKey_kana_fullstop, "。"}, {FcitxKey_kana_openingbracket, "「"}, {FcitxKey_kana_closingbracket, "」"}, {FcitxKey_kana_comma, "、"}, @@ -872,12 +812,11 @@ KeyCodeToCharRule fcitx_anthy_kana_table[] = { {FcitxKey_kana_WA, "わ"}, {FcitxKey_kana_N, "ん"}, {FcitxKey_voicedsound, "゛"}, - {FcitxKey_semivoicedsound, "゜"}, - {0, nullptr}}; + {FcitxKey_semivoicedsound, "゜"}}; -NicolaRule fcitx_anthy_nicola_table[] = { +const std::array fcitx_anthy_nicola_table = { // no modifiered keys - {"1", "1", "?", "!"}, + NicolaRule{"1", "1", "?", "!"}, {"2", "2", "/", "゛"}, {"3", "3", "〜", "#"}, {"4", "4", "「", "$"}, @@ -990,6 +929,4 @@ NicolaRule fcitx_anthy_nicola_table[] = { {"<", "ぺ", "ぺ", "む"}, {">", "ぽ", "ぼ", "わ"}, {"?", "・", "ゎ", "ぉ"}, - - {nullptr, nullptr, nullptr, nullptr}, }; diff --git a/src/default_tables.h b/src/default_tables.h index 4b73566..cbce3c2 100644 --- a/src/default_tables.h +++ b/src/default_tables.h @@ -8,95 +8,100 @@ #ifndef _FCITX5_ANTHY_DEFAULT_TABLES_H_ #define _FCITX5_ANTHY_DEFAULT_TABLES_H_ +#include +#include + struct ConvRule { - const char *string; - const char *result; - const char *cont; + std::string_view string; + std::string_view result; + std::string_view cont; }; struct HiraganaKatakanaRule { - const char *hiragana; - const char *katakana; - const char *half_katakana; + std::string_view hiragana; + std::string_view katakana; + std::string_view half_katakana; }; struct WideRule { - const char *code; - const char *wide; + std::string_view code; + std::string_view wide; }; struct KeyCodeToCharRule { unsigned int code; - const char *kana; + std::string_view kana; }; struct VoicedConsonantRule { - const char *string; - const char *voiced; - const char *half_voiced; + std::string_view string; + std::string_view voiced; + std::string_view half_voiced; }; struct NicolaRule { - const char *key; - const char *single; - const char *left_shift; - const char *right_shift; + std::string_view key; + std::string_view single; + std::string_view left_shift; + std::string_view right_shift; }; // fundamental table -extern ConvRule fcitx_anthy_romaji_typing_rule[]; -extern ConvRule fcitx_anthy_romaji_double_consonant_rule[]; -extern ConvRule fcitx_anthy_kana_typing_rule[]; -extern ConvRule fcitx_anthy_kana_voiced_consonant_rule[]; +extern const std::array fcitx_anthy_romaji_typing_rule; +extern const std::array fcitx_anthy_romaji_double_consonant_rule; +extern const std::array fcitx_anthy_kana_typing_rule; +extern const std::array fcitx_anthy_kana_voiced_consonant_rule; // symbol & number -extern ConvRule fcitx_anthy_half_symbol_rule[]; -extern ConvRule fcitx_anthy_wide_symbol_rule[]; -extern ConvRule fcitx_anthy_half_number_rule[]; -extern ConvRule fcitx_anthy_wide_number_rule[]; +extern const std::array fcitx_anthy_half_symbol_rule; +extern const std::array fcitx_anthy_wide_symbol_rule; +extern const std::array fcitx_anthy_half_number_rule; +extern const std::array fcitx_anthy_wide_number_rule; // period table -extern ConvRule fcitx_anthy_romaji_ja_period_rule[]; -extern ConvRule fcitx_anthy_romaji_wide_period_rule[]; -extern ConvRule fcitx_anthy_romaji_half_period_rule[]; +extern const std::array fcitx_anthy_romaji_ja_period_rule; +extern const std::array fcitx_anthy_romaji_wide_period_rule; +extern const std::array fcitx_anthy_romaji_half_period_rule; -extern ConvRule fcitx_anthy_kana_ja_period_rule[]; -extern ConvRule fcitx_anthy_kana_wide_period_rule[]; -extern ConvRule fcitx_anthy_kana_half_period_rule[]; +extern const std::array fcitx_anthy_kana_ja_period_rule; +extern const std::array fcitx_anthy_kana_wide_period_rule; +extern const std::array fcitx_anthy_kana_half_period_rule; // comma table -extern ConvRule fcitx_anthy_romaji_ja_comma_rule[]; -extern ConvRule fcitx_anthy_romaji_wide_comma_rule[]; -extern ConvRule fcitx_anthy_romaji_half_comma_rule[]; +extern const std::array fcitx_anthy_romaji_ja_comma_rule; +extern const std::array fcitx_anthy_romaji_wide_comma_rule; +extern const std::array fcitx_anthy_romaji_half_comma_rule; -extern ConvRule fcitx_anthy_kana_ja_comma_rule[]; -extern ConvRule fcitx_anthy_kana_wide_comma_rule[]; -extern ConvRule fcitx_anthy_kana_half_comma_rule[]; +extern const std::array fcitx_anthy_kana_ja_comma_rule; +extern const std::array fcitx_anthy_kana_wide_comma_rule; +extern const std::array fcitx_anthy_kana_half_comma_rule; // bracket table -extern ConvRule fcitx_anthy_romaji_ja_bracket_rule[]; -extern ConvRule fcitx_anthy_romaji_wide_bracket_rule[]; +extern const std::array fcitx_anthy_romaji_ja_bracket_rule; +extern const std::array fcitx_anthy_romaji_wide_bracket_rule; -extern ConvRule fcitx_anthy_kana_ja_bracket_rule[]; -extern ConvRule fcitx_anthy_kana_wide_bracket_rule[]; +extern const std::array fcitx_anthy_kana_ja_bracket_rule; +extern const std::array fcitx_anthy_kana_wide_bracket_rule; // slash table -extern ConvRule fcitx_anthy_romaji_ja_slash_rule[]; -extern ConvRule fcitx_anthy_romaji_wide_slash_rule[]; +extern const std::array fcitx_anthy_romaji_ja_slash_rule; +extern const std::array fcitx_anthy_romaji_wide_slash_rule; -extern ConvRule fcitx_anthy_kana_ja_slash_rule[]; -extern ConvRule fcitx_anthy_kana_wide_slash_rule[]; +extern const std::array fcitx_anthy_kana_ja_slash_rule; +extern const std::array fcitx_anthy_kana_wide_slash_rule; // misc -extern HiraganaKatakanaRule fcitx_anthy_hiragana_katakana_table[]; -extern WideRule fcitx_anthy_wide_table[]; -extern VoicedConsonantRule fcitx_anthy_voiced_consonant_table[]; +extern const std::array + fcitx_anthy_hiragana_katakana_table; +extern const std::array fcitx_anthy_wide_table; +extern const std::array + fcitx_anthy_voiced_consonant_table; // key code -extern KeyCodeToCharRule fcitx_anthy_keypad_table[]; -extern KeyCodeToCharRule fcitx_anthy_kana_table[]; +extern const std::array fcitx_anthy_keypad_table; +extern const std::array fcitx_anthy_kana_table; // nicola -extern NicolaRule fcitx_anthy_nicola_table[]; +extern const std::array fcitx_anthy_nicola_table; #endif // _FCITX5_ANTHY_DEFAULT_TABLES_H_ diff --git a/src/engine.cpp b/src/engine.cpp index b8c91ef..af3b121 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -7,22 +7,40 @@ #include "engine.h" #include "action.h" +#include "config.h" +#include "key2kana_table.h" #include "state.h" #include "style_file.h" -#include +#include +#include #include #include +#include +#include +#include #include -#include +#include +#include +#include #include +#include #include +#include #include +#include #include #include +#include +#include +#include #include +#include +#include +#include #include #include #include +#include FCITX_DEFINE_LOG_CATEGORY(anthy_logcategory, "anthy") @@ -131,16 +149,16 @@ struct AnthyModeTraits : AnthyStatusHelper { static auto mode(AnthyState *state) { return state->inputMode(); } static void setMode(AnthyState *state, InputMode mode) { - return state->setInputMode(mode, /*propagate=*/true); + state->setInputMode(mode, /*propagate=*/true); } static const char *icon(InputMode mode) { - if (auto *s = status(mode)) { + if (const auto *s = status(mode)) { return s->icon; } return ""; } static std::string label(InputMode mode) { - if (auto *s = status(mode)) { + if (const auto *s = status(mode)) { return fcitx::stringutils::concat(s->label, " - ", _(s->description)); } @@ -153,10 +171,10 @@ struct AnthyModeTraits : AnthyStatusHelper { static auto mode(AnthyState *state) { return state->typingMethod(); } static void setMode(AnthyState *state, TypingMethod mode) { - return state->engine()->setTypingMethod(mode); + state->engine()->setTypingMethod(mode); } static auto label(TypingMethod mode) { - if (auto *s = status(mode)) { + if (const auto *s = status(mode)) { return _(s->label); } return ""; @@ -170,10 +188,10 @@ struct AnthyModeTraits return state->engine()->conversionMode(); } static void setMode(AnthyState *state, ConversionMode mode) { - return state->engine()->setConversionMode(mode); + state->engine()->setConversionMode(mode); } static std::string label(ConversionMode mode) { - if (auto *s = status(mode)) { + if (const auto *s = status(mode)) { return fcitx::stringutils::concat(s->label, " - ", _(s->description)); } @@ -188,7 +206,7 @@ struct AnthyModeTraits return state->engine()->periodCommaStyle(); } static void setMode(AnthyState *state, PeriodCommaStyle mode) { - return state->engine()->setPeriodCommaStyle(mode); + state->engine()->setPeriodCommaStyle(mode); } }; @@ -199,7 +217,7 @@ struct AnthyModeTraits return state->engine()->symbolStyle(); } static void setMode(AnthyState *state, SymbolStyle mode) { - return state->engine()->setSymbolStyle(mode); + state->engine()->setSymbolStyle(mode); } }; @@ -208,17 +226,17 @@ class AnthyAction : public fcitx::Action { public: explicit AnthyAction(AnthyEngine *engine) : engine_(engine) {} std::string shortText(fcitx::InputContext *ic) const override { - auto state = engine_->state(ic); + auto *state = engine_->state(ic); auto mode = AnthyModeTraits::mode(state); return AnthyModeTraits::label(mode); } std::string longText(fcitx::InputContext *ic) const override { - auto state = engine_->state(ic); + auto *state = engine_->state(ic); auto mode = AnthyModeTraits::mode(state); return AnthyModeTraits::description(mode); } std::string icon(fcitx::InputContext *ic) const override { - auto state = engine_->state(ic); + auto *state = engine_->state(ic); auto mode = AnthyModeTraits::mode(state); return AnthyModeTraits::icon(mode); } @@ -238,11 +256,11 @@ class AnthySubAction : public fcitx::SimpleAction { setCheckable(true); } bool isChecked(fcitx::InputContext *ic) const override { - auto state = engine_->state(ic); + auto *state = engine_->state(ic); return mode_ == AnthyModeTraits::mode(state); } void activate(fcitx::InputContext *ic) override { - auto state = engine_->state(ic); + auto *state = engine_->state(ic); AnthyModeTraits::setMode(state, mode_); } @@ -278,8 +296,8 @@ AnthyEngine::AnthyEngine(fcitx::Instance *instance) 0); if constexpr (fcitx::isAndroid() || fcitx::isApple() || fcitx::isEmscripten()) { - const auto &sp = fcitx::StandardPath::global(); - std::string anthy_conf = sp.locate(fcitx::StandardPath::Type::Data, + const auto &sp = fcitx::StandardPaths::global(); + std::string anthy_conf = sp.locate(fcitx::StandardPathsType::Data, "anthy/anthy-unicode.conf"); std::string anthy_prefix = fcitx::fs::dirName(anthy_conf); // "CONFFILE" must be overridden first to change main config file path @@ -292,7 +310,7 @@ AnthyEngine::AnthyEngine(fcitx::Instance *instance) // /sdcard/Android/data//files/data/anthy anthy_conf_override( "XDG_CONFIG_HOME", - sp.userDirectory(fcitx::StandardPath::Type::Data).c_str()); + sp.userDirectory(fcitx::StandardPathsType::Data).string().c_str()); } if (anthy_init()) { throw std::runtime_error("Failed to init anthy library."); @@ -383,9 +401,9 @@ AnthyEngine::AnthyEngine(fcitx::Instance *instance) AnthyEngine::~AnthyEngine() { anthy_quit(); } -void AnthyEngine::keyEvent(const fcitx::InputMethodEntry &, +void AnthyEngine::keyEvent(const fcitx::InputMethodEntry & /*entry*/, fcitx::KeyEvent &keyEvent) { - auto anthy = keyEvent.inputContext()->propertyFor(&factory_); + auto *anthy = keyEvent.inputContext()->propertyFor(&factory_); auto result = anthy->processKeyEvent(keyEvent); anthy->updateUI(); if (result) { @@ -393,7 +411,7 @@ void AnthyEngine::keyEvent(const fcitx::InputMethodEntry &, } } -std::string AnthyEngine::keyProfileName() { +std::string AnthyEngine::keyProfileName() const { const std::string key_profile[] = {"", "atok.sty", "canna.sty", @@ -406,7 +424,7 @@ std::string AnthyEngine::keyProfileName() { return key_profile[profile]; } -std::string AnthyEngine::romajiTableName() { +std::string AnthyEngine::romajiTableName() const { const std::string key_profile[] = { "", "atok.sty", "azik.sty", "canna.sty", @@ -420,7 +438,7 @@ std::string AnthyEngine::romajiTableName() { return key_profile[profile]; } -std::string AnthyEngine::kanaTableName() { +std::string AnthyEngine::kanaTableName() const { const std::string key_profile[] = { "", "101kana.sty", @@ -436,7 +454,7 @@ std::string AnthyEngine::kanaTableName() { return key_profile[profile]; } -std::string AnthyEngine::nicolaTableName() { +std::string AnthyEngine::nicolaTableName() const { const std::string key_profile[] = { "", "nicola-a.sty", @@ -458,8 +476,8 @@ std::string AnthyEngine::fullFileName(const std::string &name) { if (name.empty()) { return {}; } - return fcitx::StandardPath::global().locate( - fcitx::StandardPath::Type::PkgData, + return fcitx::StandardPaths::global().locate( + fcitx::StandardPathsType::PkgData, fcitx::stringutils::joinPath("anthy", name)); } @@ -469,8 +487,6 @@ void AnthyEngine::reloadConfig() { } void AnthyEngine::populateConfig() { - std::string file; - StyleFile style; // load key bindings keyProfileFileLoaded_ = false; @@ -481,7 +497,9 @@ void AnthyEngine::populateConfig() { do { \ std::string str = (ACTION_CONFIG_##key##_KEY); \ std::string keystr; \ - style.getString(keystr, "KeyBindings", str); \ + if (auto value = style.getString("KeyBindings", str)) { \ + keystr = std::move(*value); \ + } \ keyProfile_.hk_##key = fcitx::Key::keyListFromString(keystr); \ } while (0) #include "action_defs.h" @@ -532,31 +550,33 @@ void AnthyEngine::populateOptionToState() { if (factory_.registered()) { instance_->inputContextManager().foreach( [this](fcitx::InputContext *ic) { - auto state = this->state(ic); + auto *state = this->state(ic); state->configure(); return true; }); } } -std::string AnthyEngine::subMode(const fcitx::InputMethodEntry &, +std::string AnthyEngine::subMode(const fcitx::InputMethodEntry & /*entry*/, fcitx::InputContext &ic) { - auto state = this->state(&ic); + auto *state = this->state(&ic); return AnthyModeTraits::description(state->inputMode()); } -std::string AnthyEngine::subModeLabelImpl(const fcitx::InputMethodEntry &, - fcitx::InputContext &ic) { - auto state = this->state(&ic); +std::string +AnthyEngine::subModeLabelImpl(const fcitx::InputMethodEntry & /*unused*/, + fcitx::InputContext &ic) { + auto *state = this->state(&ic); - if (auto *s = AnthyStatusHelper::status( - state->inputMode())) { + if (const auto *s = + AnthyStatusHelper::status( + state->inputMode())) { return s->label; } return ""; } -void AnthyEngine::activate(const fcitx::InputMethodEntry &, +void AnthyEngine::activate(const fcitx::InputMethodEntry & /*entry*/, fcitx::InputContextEvent &event) { // Setup action. if (*config_.interface->showInputModeLabel) { @@ -581,16 +601,16 @@ void AnthyEngine::activate(const fcitx::InputMethodEntry &, } } -void AnthyEngine::deactivate(const fcitx::InputMethodEntry &, +void AnthyEngine::deactivate(const fcitx::InputMethodEntry & /*entry*/, fcitx::InputContextEvent &event) { - auto anthy = event.inputContext()->propertyFor(&factory_); + auto *anthy = event.inputContext()->propertyFor(&factory_); anthy->autoCommit(event); anthy->updateUI(); } -void AnthyEngine::reset(const fcitx::InputMethodEntry &, +void AnthyEngine::reset(const fcitx::InputMethodEntry & /*entry*/, fcitx::InputContextEvent &event) { - auto anthy = event.inputContext()->propertyFor(&factory_); + auto *anthy = event.inputContext()->propertyFor(&factory_); anthy->reset(); anthy->updateUI(); } @@ -600,10 +620,11 @@ void AnthyEngine::invokeActionImpl(const fcitx::InputMethodEntry &entry, const int cursor = event.cursor(); if (event.action() != fcitx::InvokeActionEvent::Action::LeftClick || cursor < 0) { - return InputMethodEngineV3::invokeActionImpl(entry, event); + InputMethodEngineV3::invokeActionImpl(entry, event); + return; } event.filter(); - auto anthy = event.inputContext()->propertyFor(&factory_); + auto *anthy = event.inputContext()->propertyFor(&factory_); anthy->movePreeditCaret(event.cursor()); anthy->updateUI(); } diff --git a/src/engine.h b/src/engine.h index ded409a..247bf02 100644 --- a/src/engine.h +++ b/src/engine.h @@ -10,18 +10,25 @@ #include "action.h" #include "config.h" #include "key2kana_table.h" -#include "style_file.h" #include #include #include +#include #include +#include +#include +#include #include #include +#include #include #include #include #include #include +#include +#include +#include FCITX_DECLARE_LOG_CATEGORY(anthy_logcategory); @@ -35,14 +42,14 @@ class AnthyEngine : public fcitx::InputMethodEngineV3 { void keyEvent(const fcitx::InputMethodEntry &entry, fcitx::KeyEvent &keyEvent) override; void reloadConfig() override; - std::string subMode(const fcitx::InputMethodEntry &, - fcitx::InputContext &) override; - void activate(const fcitx::InputMethodEntry &, - fcitx::InputContextEvent &) override; + std::string subMode(const fcitx::InputMethodEntry & /*entry*/, + fcitx::InputContext & /*inputContext*/) override; + void activate(const fcitx::InputMethodEntry & /*entry*/, + fcitx::InputContextEvent & /*event*/) override; void deactivate(const fcitx::InputMethodEntry &entry, fcitx::InputContextEvent &event) override; - void reset(const fcitx::InputMethodEntry &, - fcitx::InputContextEvent &) override; + void reset(const fcitx::InputMethodEntry & /*entry*/, + fcitx::InputContextEvent & /*event*/) override; void invokeActionImpl(const fcitx::InputMethodEntry &entry, fcitx::InvokeActionEvent &event) override; @@ -70,15 +77,15 @@ class AnthyEngine : public fcitx::InputMethodEngineV3 { FCITX_ADDON_DEPENDENCY_LOADER(clipboard, instance_->addonManager()); - bool constructed() { return constructed_; } + bool constructed() const { return constructed_; } auto inputModeAction() { return inputModeAction_.get(); } auto typingMethodAction() { return typingMethodAction_.get(); } auto conversionModeAction() { return conversionModeAction_.get(); } auto periodStyleAction() { return periodStyleAction_.get(); } auto symbolStyleAction() { return symbolStyleAction_.get(); } - std::string subModeLabelImpl(const fcitx::InputMethodEntry &, - fcitx::InputContext &) override; + std::string subModeLabelImpl(const fcitx::InputMethodEntry & /*unused*/, + fcitx::InputContext & /*unused*/) override; const auto &propertyFactory() const { return factory_; } @@ -88,8 +95,8 @@ class AnthyEngine : public fcitx::InputMethodEngineV3 { PeriodCommaStyle periodCommaStyle() const { return *config_.general->periodCommaStyle; } - SymbolStyle symbolStyle() { return *config_.general->symbolStyle; } - TypingMethod typingMethod() { return *config_.general->typingMethod; } + SymbolStyle symbolStyle() const { return *config_.general->symbolStyle; } + TypingMethod typingMethod() const { return *config_.general->typingMethod; } void setPeriodCommaStyle(PeriodCommaStyle period) { setAndPopulateOption(config_.general.mutableValue()->periodCommaStyle, @@ -122,10 +129,10 @@ class AnthyEngine : public fcitx::InputMethodEngineV3 { populateOptionToState(); } - std::string keyProfileName(); - std::string romajiTableName(); - std::string kanaTableName(); - std::string nicolaTableName(); + std::string keyProfileName() const; + std::string romajiTableName() const; + std::string kanaTableName() const; + std::string nicolaTableName() const; std::string fullFileName(const std::string &name); bool constructed_ = false; diff --git a/src/kana.cpp b/src/kana.cpp index 72abbf0..977ed65 100644 --- a/src/kana.cpp +++ b/src/kana.cpp @@ -6,17 +6,21 @@ * */ #include "kana.h" +#include "config.h" #include "default_tables.h" -#include "engine.h" +#include "key2kana_base.h" #include "state.h" #include "utils.h" +#include +#include +#include +#include -static bool has_voiced_consonant(std::string str) { - VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table; +static bool has_voiced_consonant(std::string_view str) { + const auto &table = fcitx_anthy_voiced_consonant_table; - for (unsigned int i = 0; table[i].string; i++) { - if (!strcmp(str.c_str(), table[i].string) && table[i].voiced && - *table[i].voiced) { + for (const auto &item : table) { + if (item.string == str && !item.voiced.empty()) { return true; } } @@ -24,12 +28,11 @@ static bool has_voiced_consonant(std::string str) { return false; } -static bool has_half_voiced_consonant(std::string str) { - VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table; +static bool has_half_voiced_consonant(std::string_view str) { + const auto &table = fcitx_anthy_voiced_consonant_table; - for (unsigned int i = 0; table[i].string; i++) { - if (!strcmp(str.c_str(), table[i].string) && table[i].half_voiced && - *table[i].half_voiced) { + for (const auto &item : table) { + if (item.string == str && !item.half_voiced.empty()) { return true; } } @@ -37,26 +40,28 @@ static bool has_half_voiced_consonant(std::string str) { return false; } -std::string to_voiced_consonant(std::string str) { - VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table; +std::string to_voiced_consonant(std::string_view str) { + const auto &table = fcitx_anthy_voiced_consonant_table; - for (unsigned int i = 0; table[i].string; i++) { - if (!strcmp(str.c_str(), table[i].string)) - return std::string(table[i].voiced); + for (const auto &item : table) { + if (str == item.string) { + return std::string(item.voiced); + } } - return str; + return std::string{str}; } -std::string to_half_voiced_consonant(std::string str) { - VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table; +std::string to_half_voiced_consonant(std::string_view str) { + const auto &table = fcitx_anthy_voiced_consonant_table; - for (unsigned int i = 0; table[i].string; i++) { - if (!strcmp(str.c_str(), table[i].string)) - return std::string(table[i].half_voiced); + for (const auto &item : table) { + if (item.string == str) { + return std::string(item.half_voiced); + } } - return str; + return std::string{str}; } KanaConvertor::KanaConvertor(AnthyState &anthy) @@ -64,10 +69,12 @@ KanaConvertor::KanaConvertor(AnthyState &anthy) KanaConvertor::~KanaConvertor() {} -bool KanaConvertor::canAppend(const fcitx::KeyEvent &key, bool) { +bool KanaConvertor::canAppend(const fcitx::KeyEvent &key, + bool /*ignore_space*/) { // ignore key release. - if (key.isRelease()) + if (key.isRelease()) { return false; + } auto states = key.rawKey().states(); // ignore short cut keys of application. @@ -77,48 +84,32 @@ bool KanaConvertor::canAppend(const fcitx::KeyEvent &key, bool) { } auto sym = key.rawKey().sym(); - if (sym == FcitxKey_overline || - (sym >= FcitxKey_kana_fullstop && sym <= FcitxKey_semivoicedsound)) { - return true; - } - -#if 0 - if (key.code == SCIM_KEY_KP_Equal || - (key.code >= SCIM_KEY_KP_Multiply && - key.code <= SCIM_KEY_KP_9)) - { - return true; - } -#endif - - return false; + return sym == FcitxKey_overline || + (sym >= FcitxKey_kana_fullstop && sym <= FcitxKey_semivoicedsound); } bool KanaConvertor::append(const fcitx::KeyEvent &key, std::string &result, std::string &pending, std::string &raw) { - KeyCodeToCharRule *table = fcitx_anthy_keypad_table; - auto sym = key.rawKey().sym(); // handle keypad code if (sym == FcitxKey_KP_Equal || (sym >= FcitxKey_KP_Multiply && sym <= FcitxKey_KP_9)) { TenKeyType ten_key_type = *config().general->tenKeyType; - for (unsigned int i = 0; table[i].code; i++) { - if (table[i].code == sym) { - if (ten_key_type == TenKeyType::WIDE) - result = util::convert_to_wide(table[i].kana); - else - result = table[i].kana; - raw = table[i].kana; + for (const auto &item : fcitx_anthy_keypad_table) { + if (item.code == sym) { + if (ten_key_type == TenKeyType::WIDE) { + result = util::convert_to_wide(item.kana); + } else { + result = item.kana; + } + raw = item.kana; return false; } } } - table = fcitx_anthy_kana_table; - // handle voiced sound if (sym == FcitxKey_voicedsound && !pending_.empty() && has_voiced_consonant(pending_)) { @@ -138,16 +129,16 @@ bool KanaConvertor::append(const fcitx::KeyEvent &key, std::string &result, } // kana key code - for (unsigned int i = 0; table[i].code; i++) { - if (table[i].code == sym) { - bool retval = pending_.empty() ? false : true; + for (const auto &item : fcitx_anthy_kana_table) { + if (item.code == sym) { + bool retval = !pending_.empty(); - if (has_voiced_consonant(table[i].kana)) { + if (has_voiced_consonant(item.kana)) { result = std::string(); - pending = table[i].kana; - pending_ = table[i].kana; + pending = item.kana; + pending_ = item.kana; } else { - result = table[i].kana; + result = item.kana; pending_ = std::string(); } raw = util::get_ascii_code(key); @@ -163,9 +154,9 @@ bool KanaConvertor::append(const fcitx::KeyEvent &key, std::string &result, return append(raw, result, pending); } -bool KanaConvertor::append(const std::string &str, std::string &result, - std::string &) { - result = str; +bool KanaConvertor::append(std::string_view raw, std::string &result, + std::string & /*pending*/) { + result = raw; pending_ = std::string(); return false; @@ -180,8 +171,9 @@ std::string KanaConvertor::pending() const { return pending_; } std::string KanaConvertor::flushPending() { return std::string(); } void KanaConvertor::resetPending(const std::string &result, - const std::string &) { + const std::string & /*raw*/) { pending_ = std::string(); - if (has_voiced_consonant(result)) + if (has_voiced_consonant(result)) { pending_ = result; + } } diff --git a/src/kana.h b/src/kana.h index 1065901..b07f24b 100644 --- a/src/kana.h +++ b/src/kana.h @@ -8,9 +8,10 @@ #ifndef _FCITX5_ANTHY_KANA_H_ #define _FCITX5_ANTHY_KANA_H_ -#include "default_tables.h" #include "key2kana_base.h" -#include "key2kana_table.h" +#include +#include +#include class AnthyState; @@ -23,7 +24,7 @@ class KanaConvertor : public Key2KanaConvertorBase { bool ignore_space = false) override; bool append(const fcitx::KeyEvent &key, std::string &result, std::string &pending, std::string &raw) override; - bool append(const std::string &raw, std::string &result, + bool append(std::string_view raw, std::string &result, std::string &pending) override; void clear() override; diff --git a/src/key2kana.cpp b/src/key2kana.cpp index a51a99c..652b858 100644 --- a/src/key2kana.cpp +++ b/src/key2kana.cpp @@ -8,11 +8,22 @@ */ #include "key2kana.h" -#include "engine.h" +#include "config.h" +#include "key2kana_base.h" +#include "key2kana_table.h" #include "state.h" #include "utils.h" #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include Key2KanaConvertor::Key2KanaConvertor(AnthyState &anthy, Key2KanaTableSet &tables) @@ -27,8 +38,9 @@ Key2KanaConvertor::~Key2KanaConvertor() {} bool Key2KanaConvertor::canAppend(const fcitx::KeyEvent &key, bool ignore_space) { // ignore key release. - if (key.isRelease()) + if (key.isRelease()) { return false; + } auto state = key.rawKey().states(); // ignore short cut keys of apllication. @@ -39,19 +51,22 @@ bool Key2KanaConvertor::canAppend(const fcitx::KeyEvent &key, auto chr = util::get_ascii_code(key); if (fcitx::charutils::isprint(chr) && - (ignore_space || !fcitx::charutils::isspace(chr))) + (ignore_space || !fcitx::charutils::isspace(chr))) { return true; + } - if (util::key_is_keypad(key.rawKey())) + if (util::key_is_keypad(key.rawKey())) { return true; + } return false; } bool Key2KanaConvertor::append(const fcitx::KeyEvent &key, std::string &result, std::string &pending, std::string &raw) { - if (!canAppend(key)) + if (!canAppend(key)) { return false; + } lastKey_ = key.rawKey(); @@ -82,8 +97,9 @@ bool Key2KanaConvertor::append(const fcitx::KeyEvent &key, std::string &result, } result += wide; } else { - if (!pending_.empty()) + if (!pending_.empty()) { retval = true; /* commit prev pending */ + } result = wide; } @@ -92,10 +108,8 @@ bool Key2KanaConvertor::append(const fcitx::KeyEvent &key, std::string &result, return retval; - } else { - // the key isn't keypad - return append(raw, result, pending); - } + } // the key isn't keypad + return append(raw, result, pending); } static int split_string_list(std::vector &vec, @@ -103,7 +117,8 @@ static int split_string_list(std::vector &vec, int count = 0; std::string temp; - std::string::const_iterator bg, ed; + std::string::const_iterator bg; + std::string::const_iterator ed; vec.clear(); @@ -112,41 +127,48 @@ static int split_string_list(std::vector &vec, while (bg != str.end() && ed != str.end()) { for (; ed != str.end(); ++ed) { - if (*ed == ',') + if (*ed == ',') { break; + } } temp.assign(bg, ed); vec.push_back(temp); ++count; - if (ed != str.end()) + if (ed != str.end()) { bg = ++ed; + } } return count; } -bool CheckLayout(void *) { - // TODO - return false; +bool CheckLayout(fcitx::Instance *instance) { + const auto &group = instance->inputMethodManager().currentGroup(); + std::string layout = group.layoutFor("anthy"); + if (layout.empty()) { + layout = group.defaultLayout(); + } + + return layout == "jp" || layout.starts_with("jp-"); } -bool Key2KanaConvertor::append(const std::string &str, std::string &result, +bool Key2KanaConvertor::append(std::string_view str, std::string &result, std::string &pending) { - std::string widestr = str; - std::string matching_str = pending_ + widestr; + std::string matching_str = fcitx::stringutils::concat(pending_, str); Key2KanaRule exact_match; bool has_partial_match = false; bool retval = false; - if (pseudoAsciiMode_ != 0 && processPseudoAsciiMode(widestr)) { - pending_ += widestr; + if (pseudoAsciiMode_ != 0 && processPseudoAsciiMode(str)) { + pending_ += str; pending = pending_; return false; } if (!caseSensitive_) { std::string half = matching_str; - for (unsigned int i = 0; i < half.length(); i++) + for (unsigned int i = 0; i < half.length(); i++) { half[i] = fcitx::charutils::tolower(half[i]); + } matching_str = half; } @@ -154,7 +176,7 @@ bool Key2KanaConvertor::append(const std::string &str, std::string &result, if ((state_.typingMethod() == TypingMethod::KANA) && (CheckLayout(state_.instance())) && (lastKey_.sym() == FcitxKey_backslash) && - (!(lastKey_.code() == 132 || lastKey_.code() == 133)) && + (lastKey_.code() != 132 && lastKey_.code() != 133) && (!config().key->kanaLayoutRoKey->empty())) { // Special treatment for Kana "Ro" key. // This code is a temporary solution. It doesn't care some minor cases. @@ -165,36 +187,30 @@ bool Key2KanaConvertor::append(const std::string &str, std::string &result, result = kana_ro_rule.result(0); pending_.clear(); exactMatch_.clear(); - if (matching_str == "\\") { - return false; - } else { - return true; + return matching_str != "\\"; + } + const std::vector &tables = tables_.get_tables(); + for (auto *table : tables) { + if (!table) { + continue; } - } else { - const std::vector &tables = tables_.get_tables(); - for (unsigned int j = 0; j < tables.size(); j++) { - if (!tables[j]) - continue; - - const Key2KanaRules &rules = tables[j]->table(); - - for (unsigned int i = 0; i < rules.size(); i++) { - /* matching */ - std::string seq = rules[i].sequence(); - if (!caseSensitive_) { - for (unsigned int j = 0; j < seq.length(); j++) - seq[j] = fcitx::charutils::tolower(seq[j]); + for (const auto &rule : table->table()) { + /* matching */ + std::string seq = rule.sequence(); + if (!caseSensitive_) { + for (unsigned int j = 0; j < seq.length(); j++) { + seq[j] = fcitx::charutils::tolower(seq[j]); } - std::string romaji = seq; - if (romaji.find(matching_str) == 0) { - if (romaji.length() == matching_str.length()) { - /* exact match */ - exact_match = rules[i]; - } else { - /* partial match */ - has_partial_match = true; - } + } + std::string romaji = seq; + if (romaji.find(matching_str) == 0) { + if (romaji.length() == matching_str.length()) { + /* exact match */ + exact_match = rule; + } else { + /* partial match */ + has_partial_match = true; } } } @@ -204,14 +220,15 @@ bool Key2KanaConvertor::append(const std::string &str, std::string &result, if (has_partial_match) { exactMatch_ = exact_match; result.clear(); - pending_ += widestr; + pending_ += str; pending = pending_; } else if (!exact_match.isEmpty()) { - if (!exact_match.result(1).empty()) + if (!exact_match.result(1).empty()) { exactMatch_ = exact_match; - else + } else { exactMatch_.clear(); + } pending_ = exact_match.result(1); result = exact_match.result(0); pending = pending_; @@ -234,11 +251,11 @@ bool Key2KanaConvertor::append(const std::string &str, std::string &result, } else { if (!pending_.empty()) { retval = true; /* commit prev pending */ - pending_ = widestr; + pending_ = str; pending = pending_; } else { - result = widestr; + result = str; pending.clear(); pending_.clear(); } @@ -274,22 +291,22 @@ std::string Key2KanaConvertor::flushPending() { return result; } -void Key2KanaConvertor::resetPending(const std::string &, +void Key2KanaConvertor::resetPending(const std::string & /*result*/, const std::string &raw) { lastKey_ = fcitx::Key(); - for (unsigned int i = 0; i < fcitx::utf8::length(raw); i++) { - std::string res, pend; - append(util::utf8_string_substr(raw, i, 1), res, pend); + for (auto chr : fcitx::utf8::MakeUTF8StringViewRange(raw)) { + std::string res; + std::string pend; + append(chr, res, pend); } } -bool Key2KanaConvertor::processPseudoAsciiMode(const std::string &wstr) { - for (unsigned int i = 0; i < wstr.length(); i++) { - if (fcitx::charutils::isupper(wstr[i]) || - fcitx::charutils::isspace(wstr[i])) { +bool Key2KanaConvertor::processPseudoAsciiMode(std::string_view wstr) { + for (auto chr : wstr) { + if (fcitx::charutils::isupper(chr) || fcitx::charutils::isspace(chr)) { isInPseudoAsciiMode_ = true; - } else if (wstr[i] & 0x80) { + } else if (chr & 0x80) { isInPseudoAsciiMode_ = false; } } @@ -298,8 +315,9 @@ bool Key2KanaConvertor::processPseudoAsciiMode(const std::string &wstr) { } void Key2KanaConvertor::resetPseudoAsciiMode() { - if (isInPseudoAsciiMode_) + if (isInPseudoAsciiMode_) { pending_.clear(); + } isInPseudoAsciiMode_ = false; } diff --git a/src/key2kana.h b/src/key2kana.h index 2c228da..ddb9968 100644 --- a/src/key2kana.h +++ b/src/key2kana.h @@ -9,9 +9,12 @@ #ifndef _FCITX5_ANTHY_KEY2KANA_H_ #define _FCITX5_ANTHY_KEY2KANA_H_ -#include "default_tables.h" #include "key2kana_base.h" #include "key2kana_table.h" +#include +#include +#include +#include class AnthyState; @@ -24,6 +27,8 @@ class Key2KanaConvertor : public Key2KanaConvertorBase { bool ignore_space = false) override; bool append(const fcitx::KeyEvent &key, std::string &result, std::string &pending, std::string &raw) override; + bool append(std::string_view str, std::string &result, + std::string &pending) override; void clear() override; bool isPending() const override; @@ -32,14 +37,10 @@ class Key2KanaConvertor : public Key2KanaConvertorBase { void resetPending(const std::string &result, const std::string &raw) override; void setPseudoAsciiMode(int mode) { pseudoAsciiMode_ = mode; } - bool isPseudoAsciiMode() { return isInPseudoAsciiMode_; } - bool processPseudoAsciiMode(const std::string &wstr) override; + bool isPseudoAsciiMode() const { return isInPseudoAsciiMode_; } + bool processPseudoAsciiMode(std::string_view wstr) override; void resetPseudoAsciiMode() override; -private: - bool append(const std::string &str, std::string &result, - std::string &pending) override; - private: Key2KanaTableSet &tables_; diff --git a/src/key2kana_base.h b/src/key2kana_base.h index 1352d6e..bb3ff76 100644 --- a/src/key2kana_base.h +++ b/src/key2kana_base.h @@ -10,6 +10,8 @@ #define _FCITX5_ANTHY_KEY2KANA_BASE_H_ #include +#include +#include class AnthyState; class AnthyConfig; @@ -24,7 +26,7 @@ class Key2KanaConvertorBase { bool ignore_space = false) = 0; virtual bool append(const fcitx::KeyEvent &key, std::string &result, std::string &pending, std::string &raw) = 0; - virtual bool append(const std::string &raw, std::string &result, + virtual bool append(std::string_view raw, std::string &result, std::string &pending) = 0; virtual void clear() = 0; @@ -35,10 +37,12 @@ class Key2KanaConvertorBase { const std::string &raw) = 0; virtual void resetPseudoAsciiMode() {} - virtual bool processPseudoAsciiMode(const std::string &) { return false; } + virtual bool processPseudoAsciiMode(std::string_view /*unused*/) { + return false; + } void setCaseSensitive(bool sensitive) { caseSensitive_ = sensitive; } - bool isCaseSensitive() { return caseSensitive_; } + bool isCaseSensitive() const { return caseSensitive_; } protected: const AnthyConfig &config() const; diff --git a/src/key2kana_table.cpp b/src/key2kana_table.cpp index 02db186..10f8998 100644 --- a/src/key2kana_table.cpp +++ b/src/key2kana_table.cpp @@ -7,7 +7,14 @@ */ #include "key2kana_table.h" +#include "config.h" +#include "default_tables.h" #include "style_file.h" +#include +#include +#include +#include +#include // fundamental table static Key2KanaTable romaji_table(("DefaultRomajiTable"), @@ -107,8 +114,9 @@ Key2KanaRule::~Key2KanaRule() {} const std::string &Key2KanaRule::sequence() const { return sequence_; } std::string Key2KanaRule::result(unsigned int idx) const { - if (idx < result_.size()) + if (idx < result_.size()) { return result_[idx]; + } return std::string(); } @@ -119,15 +127,18 @@ void Key2KanaRule::clear() { } bool Key2KanaRule::isEmpty() { - if (!sequence_.empty()) + if (!sequence_.empty()) { return false; + } - if (result_.empty()) + if (result_.empty()) { return true; + } - for (unsigned int i = 0; i < result_.size(); i++) { - if (!result_[i].empty()) + for (const auto &i : result_) { + if (!i.empty()) { return false; + } } return true; @@ -135,35 +146,31 @@ bool Key2KanaRule::isEmpty() { Key2KanaTable::Key2KanaTable(std::string name) : name_(std::move(name)) {} -Key2KanaTable::Key2KanaTable(std::string name, ConvRule *table) +Key2KanaTable::Key2KanaTable(std::string name, std::span table) : name_(std::move(name)) { - for (unsigned int i = 0; table[i].string; i++) { - appendRule(table[i].string ? table[i].string : "", - table[i].result ? table[i].result : "", - table[i].cont ? table[i].cont : ""); + for (const auto &item : table) { + appendRule(std::string{item.string}, std::string{item.result}, + std::string{item.cont}); } } -Key2KanaTable::Key2KanaTable(std::string name, NicolaRule *table) +Key2KanaTable::Key2KanaTable(std::string name, + std::span table) : name_(std::move(name)) { - for (unsigned int i = 0; table[i].key; i++) { - appendRule(table[i].key ? table[i].key : "", - table[i].single ? table[i].single : "", - table[i].left_shift ? table[i].left_shift : "", - table[i].right_shift ? table[i].right_shift : ""); + for (const auto &item : table) { + appendRule(std::string{item.key}, std::string{item.single}, + std::string{item.left_shift}, std::string{item.right_shift}); } } -Key2KanaTable::Key2KanaTable(std::string section, const StyleFile &styleFile) +Key2KanaTable::Key2KanaTable(std::string_view section, + const StyleFile &styleFile) : Key2KanaTable(styleFile.title()) { - std::vector keys; - bool success = styleFile.getKeyList(keys, section); - if (success) { - std::vector::iterator it; - for (it = keys.begin(); it != keys.end(); it++) { - std::vector array; - styleFile.getStringArray(array, section, *it); - appendRule(*it, array); + if (auto keys = styleFile.getKeyList(section)) { + for (const auto &key : *keys) { + if (auto array = styleFile.getStringArray(section, key)) { + appendRule(key, std::move(*array)); + } } } } @@ -186,16 +193,16 @@ void Key2KanaTable::appendRule(std::string sequence, std::string normal, std::string left_shift, std::string right_shift) { std::vector list; - list.push_back(normal); - list.push_back(left_shift); - list.push_back(right_shift); + list.push_back(std::move(normal)); + list.push_back(std::move(left_shift)); + list.push_back(std::move(right_shift)); appendRule(std::move(sequence), std::move(list)); } void Key2KanaTable::clear() { rules_.clear(); } Key2KanaTableSet::Key2KanaTableSet() - : name_(""), fundamentalTable_(nullptr), + : fundamentalTable_(nullptr), voicedConsonantTable_(Key2KanaTable("voiced consonant table")), additionalTable_(nullptr), typingMethod_(TypingMethod::ROMAJI), periodStyle_(PeriodStyle::JAPANESE), commaStyle_(CommaStyle::JAPANESE), @@ -256,30 +263,30 @@ static void create_voiced_consonant_table(Key2KanaTable &table, const Key2KanaRules &rules = fund_table.table(); for (it = rules.begin(); it != rules.end(); it++) { std::string result = it->result(0); - if (result == sonant_mark) + if (result == sonant_mark) { sonant_mark_list.push_back(it->sequence()); - else if (result == half_sonant_mark) + } else if (result == half_sonant_mark) { half_sonant_mark_list.push_back(it->sequence()); + } } - VoicedConsonantRule *templ = fcitx_anthy_voiced_consonant_table; + const auto &templ = fcitx_anthy_voiced_consonant_table; - for (unsigned int i = 0; templ[i].string; i++) { - if (templ[i].voiced && *templ[i].voiced) { + for (const auto &item : templ) { + if (!item.voiced.empty()) { std::vector::iterator it; for (it = sonant_mark_list.begin(); it != sonant_mark_list.end(); it++) { - table.appendRule(std::string(templ[i].string) + *it, - std::string(templ[i].voiced), std::string()); + table.appendRule(std::string(item.string) + *it, + std::string(item.voiced), std::string()); } } - if (templ[i].half_voiced && *templ[i].half_voiced) { + if (!item.half_voiced.empty()) { std::vector::iterator it; for (it = half_sonant_mark_list.begin(); it != half_sonant_mark_list.end(); it++) { - table.appendRule(std::string(templ[i].string) + *it, - std::string(templ[i].half_voiced), - std::string()); + table.appendRule(std::string(item.string) + *it, + std::string(item.half_voiced), std::string()); } } } @@ -293,36 +300,41 @@ void Key2KanaTableSet::resetTables() { bool is_nicola = typingMethod_ == TypingMethod::NICOLA; // symbols table - if (useHalfSymbol_) + if (useHalfSymbol_) { allTables_.push_back(&half_symbol_table); - else + } else { allTables_.push_back(&wide_symbol_table); + } // numbers table - if (useHalfNumber_) + if (useHalfNumber_) { allTables_.push_back(&half_number_table); - else + } else { allTables_.push_back(&wide_number_table); + } if (is_romaji || is_kana) { switch (periodStyle_) { case PeriodStyle::JAPANESE: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_ja_period_table); - else + } else { allTables_.push_back(&kana_ja_period_table); + } break; case PeriodStyle::WIDE: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_wide_period_table); - else + } else { allTables_.push_back(&kana_wide_period_table); + } break; case PeriodStyle::HALF: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_half_period_table); - else + } else { allTables_.push_back(&kana_half_period_table); + } break; default: break; @@ -332,22 +344,25 @@ void Key2KanaTableSet::resetTables() { if (is_romaji || is_kana) { switch (commaStyle_) { case CommaStyle::JAPANESE: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_ja_comma_table); - else + } else { allTables_.push_back(&kana_ja_comma_table); + } break; case CommaStyle::WIDE: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_wide_comma_table); - else + } else { allTables_.push_back(&kana_wide_comma_table); + } break; case CommaStyle::HALF: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_half_comma_table); - else + } else { allTables_.push_back(&kana_half_comma_table); + } break; default: break; @@ -357,16 +372,20 @@ void Key2KanaTableSet::resetTables() { if (is_romaji || is_kana) { switch (bracketStyle_) { case BracketStyle::JAPANESE: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_ja_bracket_table); - else + } else { allTables_.push_back(&kana_ja_bracket_table); + } break; case BracketStyle::WIDE: - if (is_romaji) - allTables_.push_back(&romaji_wide_bracket_table); - else + if (is_romaji) { + { + allTables_.push_back(&romaji_wide_bracket_table); + } + } else { allTables_.push_back(&kana_wide_bracket_table); + } break; default: break; @@ -376,16 +395,18 @@ void Key2KanaTableSet::resetTables() { if (is_romaji || is_kana) { switch (slashStyle_) { case SlashStyle::JAPANESE: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_ja_slash_table); - else + } else { allTables_.push_back(&kana_ja_slash_table); + } break; case SlashStyle::WIDE: - if (is_romaji) + if (is_romaji) { allTables_.push_back(&romaji_wide_slash_table); - else + } else { allTables_.push_back(&kana_wide_slash_table); + } break; default: break; diff --git a/src/key2kana_table.h b/src/key2kana_table.h index e775f96..8370263 100644 --- a/src/key2kana_table.h +++ b/src/key2kana_table.h @@ -12,7 +12,9 @@ #include "default_tables.h" #include "style_file.h" #include +#include #include +#include #include enum class PeriodStyle { @@ -65,10 +67,10 @@ class Key2KanaRule { class Key2KanaTable { public: Key2KanaTable(std::string name); - Key2KanaTable(std::string name, ConvRule *table); - Key2KanaTable(std::string name, NicolaRule *table); + Key2KanaTable(std::string name, std::span table); + Key2KanaTable(std::string name, std::span table); - Key2KanaTable(std::string section, const StyleFile &styleFile); + Key2KanaTable(std::string_view section, const StyleFile &styleFile); FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITHOUT_SPEC(Key2KanaTable) @@ -114,7 +116,6 @@ class Key2KanaTableSet { private: void resetTables(); -private: std::string name_; // tables diff --git a/src/nicola.cpp b/src/nicola.cpp index a2c8d21..ad0ec88 100644 --- a/src/nicola.cpp +++ b/src/nicola.cpp @@ -8,11 +8,24 @@ */ #include "nicola.h" +#include "config.h" +#include "default_tables.h" #include "engine.h" +#include "key2kana_base.h" +#include "key2kana_table.h" #include "state.h" #include "utils.h" +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include void NicolaTimeoutFunc(void *arg) { NicolaConvertor *convertor = (NicolaConvertor *)arg; @@ -59,8 +72,9 @@ bool NicolaConvertor::canAppend(const fcitx::KeyEvent &key, bool ignore_space) { return true; } - if (isThumbKey(key.rawKey())) + if (isThumbKey(key.rawKey())) { return true; + } return false; } @@ -70,20 +84,22 @@ void NicolaConvertor::search(const fcitx::Key &key, NicolaShiftType shift_type, raw = util::get_ascii_code(key); std::string str1; - if (isCaseSensitive()) + if (isCaseSensitive()) { str1 = raw; - else + } else { str1 = fcitx::charutils::tolower(util::get_ascii_code(key)); + } const std::vector &tables = tables_.get_tables(); for (unsigned int j = 0; j < tables.size(); j++) { - if (!tables[j]) + if (!tables[j]) { continue; + } const Key2KanaRules &rules = tables[j]->table(); - for (unsigned int i = 0; i < rules.size(); i++) { - std::string str2 = rules[i].sequence(); + for (const auto &rule : rules) { + std::string str2 = rule.sequence(); for (unsigned int k = 0; !isCaseSensitive() && k < str2.length(); k++) { @@ -93,13 +109,13 @@ void NicolaConvertor::search(const fcitx::Key &key, NicolaShiftType shift_type, if (str1 == str2) { switch (shift_type) { case FCITX_ANTHY_NICOLA_SHIFT_RIGHT: - result = rules[i].result(2); + result = rule.result(2); break; case FCITX_ANTHY_NICOLA_SHIFT_LEFT: - result = rules[i].result(1); + result = rule.result(1); break; default: - result = rules[i].result(0); + result = rule.result(0); break; } break; @@ -114,14 +130,15 @@ void NicolaConvertor::search(const fcitx::Key &key, NicolaShiftType shift_type, bool NicolaConvertor::handleVoicedConsonant(std::string &result, std::string &pending) { - VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table; + const auto &table = fcitx_anthy_voiced_consonant_table; - if (result.empty()) + if (result.empty()) { return false; + } if (pending_.empty()) { - for (unsigned int i = 0; table[i].string; i++) { - if (result == table[i].string) { + for (const auto &item : table) { + if (result == item.string) { pending = pending_ = result; result = std::string(); return false; @@ -130,9 +147,9 @@ bool NicolaConvertor::handleVoicedConsonant(std::string &result, } else if (result == "\xE3\x82\x9B") { // voiced consonant - for (unsigned int i = 0; table[i].string; i++) { - if (pending_ == table[i].string) { - result = table[i].voiced; + for (const auto &item : table) { + if (pending_ == item.string) { + result = item.voiced; pending_ = std::string(); return false; } @@ -141,9 +158,9 @@ bool NicolaConvertor::handleVoicedConsonant(std::string &result, } else if (result == "\xE3\x82\x9C") { // half voiced consonant - for (unsigned int i = 0; table[i].string; i++) { - if (pending_ == table[i].string) { - result = table[i].half_voiced; + for (const auto &item : table) { + if (pending_ == item.string) { + result = item.half_voiced; pending_ = std::string(); return false; } @@ -152,8 +169,8 @@ bool NicolaConvertor::handleVoicedConsonant(std::string &result, } else { pending_ = std::string(); - for (unsigned int i = 0; table[i].string; i++) { - if (result == table[i].string) { + for (const auto &item : table) { + if (result == item.string) { pending = pending_ = result; result = std::string(); return true; @@ -166,18 +183,12 @@ bool NicolaConvertor::handleVoicedConsonant(std::string &result, } bool NicolaConvertor::isCharKey(const fcitx::KeyEvent &key) { - if (!isThumbKey(key.rawKey()) && - fcitx::charutils::isprint(util::get_ascii_code(key))) - return true; - else - return false; + return !isThumbKey(key.rawKey()) && + fcitx::charutils::isprint(util::get_ascii_code(key)); } bool NicolaConvertor::isThumbKey(const fcitx::Key &key) { - if (isLeftThumbKey(key) || isRightThumbKey(key)) - return true; - - return false; + return isLeftThumbKey(key) || isRightThumbKey(key); } bool NicolaConvertor::isLeftThumbKey(const fcitx::Key &key) { @@ -191,12 +202,13 @@ bool NicolaConvertor::isRightThumbKey(const fcitx::Key &key) { } NicolaShiftType NicolaConvertor::thumbKeyType(const fcitx::Key &key) { - if (isLeftThumbKey(key)) + if (isLeftThumbKey(key)) { return FCITX_ANTHY_NICOLA_SHIFT_LEFT; - else if (isRightThumbKey(key)) + } + if (isRightThumbKey(key)) { return FCITX_ANTHY_NICOLA_SHIFT_RIGHT; - else - return FCITX_ANTHY_NICOLA_SHIFT_NONE; + } + return FCITX_ANTHY_NICOLA_SHIFT_NONE; } bool NicolaConvertor::emitKeyEvent(const fcitx::Key &key) { @@ -224,13 +236,10 @@ void NicolaConvertor::processTimeout() { } void NicolaConvertor::setAlarm(int time_msec) { - if (time_msec < 5) - time_msec = 5; - if (time_msec > 1000) - time_msec = 1000; + uint64_t time = std::clamp(time_msec, 5, 1000); timer_ = state_.instance()->eventLoop().addTimeEvent( - CLOCK_MONOTONIC, fcitx::now(CLOCK_MONOTONIC) + time_msec * 1000, 1, + CLOCK_MONOTONIC, fcitx::now(CLOCK_MONOTONIC) + (time * 1000), 1, [this](fcitx::EventSourceTime *, uint64_t) { processTimeout(); return true; @@ -296,9 +305,9 @@ bool NicolaConvertor::append(const fcitx::KeyEvent &key, std::string &result, } prevThumbKey_ = fcitx::Key(); } - if (isThumbKey(key.rawKey())) + if (isThumbKey(key.rawKey())) { repeatThumbKey_ = fcitx::Key(); - else if (key.rawKey() == repeatCharKey_) { + } else if (key.rawKey() == repeatCharKey_) { repeatCharKey_ = fcitx::Key(); } } else if (isThumbKey(key.rawKey())) { @@ -363,8 +372,9 @@ bool NicolaConvertor::append(const fcitx::KeyEvent &key, std::string &result, stop(); emitKeyEvent(prevThumbKey_); } - if (emitKeyEvent(key)) + if (emitKeyEvent(key)) { return true; + } } FCITX_ANTHY_DEBUG() << "prev: " << prevCharKey_; @@ -372,9 +382,9 @@ bool NicolaConvertor::append(const fcitx::KeyEvent &key, std::string &result, return handleVoicedConsonant(result, pending); } -bool NicolaConvertor::append(const std::string &str, std::string &result, - std::string &) { - result = str; +bool NicolaConvertor::append(std::string_view raw, std::string &result, + std::string & /*pending*/) { + result = raw; pending_ = std::string(); return false; @@ -395,13 +405,13 @@ std::string NicolaConvertor::pending() const { return pending_; } std::string NicolaConvertor::flushPending() { return std::string(); } void NicolaConvertor::resetPending(const std::string &result, - const std::string &) { - VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table; + const std::string & /*raw*/) { + const auto &table = fcitx_anthy_voiced_consonant_table; pending_ = std::string(); - for (unsigned int i = 0; table[i].string; i++) { - if (result == table[i].string) { + for (const auto &item : table) { + if (result == item.string) { pending_ = result; return; } diff --git a/src/nicola.h b/src/nicola.h index 19ea15e..7d72f9e 100644 --- a/src/nicola.h +++ b/src/nicola.h @@ -10,7 +10,13 @@ #define __FCITX_ANTHY_NICOLA_H__ #include +#include +#include +#include +#include #include +#include +#include #include #include "key2kana_base.h" @@ -33,7 +39,7 @@ class NicolaConvertor : public Key2KanaConvertorBase { bool ignore_space = false) override; bool append(const fcitx::KeyEvent &key, std::string &result, std::string &pending, std::string &raw) override; - bool append(const std::string &raw, std::string &result, + bool append(std::string_view raw, std::string &result, std::string &pending) override; void clear() override; @@ -42,8 +48,6 @@ class NicolaConvertor : public Key2KanaConvertorBase { std::string flushPending() override; void resetPending(const std::string &result, const std::string &raw) override; - -public: void processTimeout(); private: @@ -61,7 +65,6 @@ class NicolaConvertor : public Key2KanaConvertorBase { bool stop(); int thumbKey(const fcitx::KeyEvent &key); -private: Key2KanaTableSet &tables_; // state diff --git a/src/preedit.cpp b/src/preedit.cpp index 1a1cd9d..a3fe2c0 100644 --- a/src/preedit.cpp +++ b/src/preedit.cpp @@ -7,13 +7,27 @@ */ #include "preedit.h" -#include "engine.h" +#include "config.h" +#include "conversion.h" +#include "default_tables.h" +#include "key2kana_table.h" +#include "reading.h" #include "state.h" #include "utils.h" +#include +#include +#include +#include +#include #include +#include +#include +#include -static ConvRule *get_period_rule(TypingMethod method, PeriodStyle period); -static ConvRule *get_comma_rule(TypingMethod method, CommaStyle period); +static const std::array *get_period_rule(TypingMethod method, + PeriodStyle period); +static const std::array *get_comma_rule(TypingMethod method, + CommaStyle period); Preedit::Preedit(AnthyState &anthy) : state_(anthy), reading_(anthy), conversion_(state_, reading_), @@ -25,45 +39,45 @@ Preedit::~Preedit() {} * getting status */ unsigned int Preedit::length() { - if (isConverting()) + if (isConverting()) { return conversion_.length(); - else - return reading_.length(); + } + return reading_.length(); } /* * getting status */ unsigned int Preedit::utf8Length() { - if (isConverting()) + if (isConverting()) { return conversion_.utf8Length(); - else - return reading_.utf8Length(); + } + return reading_.utf8Length(); } std::string Preedit::string() { if (isConverting()) { return conversion_.get(); - } else if (!source_.empty()) { + } + if (!source_.empty()) { return source_; - } else { - switch (inputMode_) { - case InputMode::KATAKANA: - return util::convert_to_katakana(reading_.getByChar()); + } + switch (inputMode_) { + case InputMode::KATAKANA: + return util::convert_to_katakana(reading_.getByChar()); - case InputMode::HALF_KATAKANA: - return util::convert_to_katakana(reading_.getByChar(), true); + case InputMode::HALF_KATAKANA: + return util::convert_to_katakana(reading_.getByChar(), true); - case InputMode::LATIN: - return reading_.getRawByChar(); + case InputMode::LATIN: + return reading_.getRawByChar(); - case InputMode::WIDE_LATIN: - return util::convert_to_wide(reading_.getRawByChar()); + case InputMode::WIDE_LATIN: + return util::convert_to_wide(reading_.getRawByChar()); - case InputMode::HIRAGANA: - default: - return reading_.getByChar(); - } + case InputMode::HIRAGANA: + default: + return reading_.getByChar(); } } @@ -91,12 +105,8 @@ void Preedit::updatePreedit() { } bool Preedit::isPreediting() { - if (reading_.length() > 0 || conversion_.isConverting() || - !source_.empty()) { - return true; - } else { - return false; - } + return reading_.length() > 0 || conversion_.isConverting() || + !source_.empty(); } bool Preedit::isConverting() { return conversion_.isConverting(); } @@ -113,14 +123,30 @@ bool Preedit::canProcessKeyEvent(const fcitx::KeyEvent &key) { } bool Preedit::processKeyEvent(const fcitx::KeyEvent &key) { - if (!reading_.canProcesKeyEvent(key)) + if (!reading_.canProcesKeyEvent(key)) { return false; + } bool retval = reading_.processKeyEvent(key); if (inputMode_ == InputMode::LATIN || inputMode_ == InputMode::WIDE_LATIN) { return true; } + // auto convert + unsigned int len = reading_.length(); + if (len > 0) { + std::string str = reading_.getRawByChar(len - 1, 1); + if (isCommaOrPeriod(str)) { + if (*state_.config().general->periodBehavior == + PeriodBehavior::Convert && + length() > 1) { + convert(); + } else if (*state_.config().general->periodBehavior == + PeriodBehavior::Commit) { + return true; + } + } + } return retval; } @@ -134,8 +160,9 @@ bool Preedit::append(const fcitx::Key &key, const std::string &string) { } void Preedit::erase(bool backward) { - if (reading_.utf8Length() <= 0) + if (reading_.utf8Length() <= 0) { return; + } // cancel conversion revert(); @@ -144,12 +171,15 @@ void Preedit::erase(bool backward) { TypingMethod method = typingMethod(); bool allow_split = method == TypingMethod::ROMAJI && *state_.config().general->romajiAllowSplit; - if (backward && reading_.caretPosByChar() == 0) + if (backward && reading_.caretPosByChar() == 0) { return; - if (!backward && reading_.caretPosByChar() >= reading_.utf8Length()) + } + if (!backward && reading_.caretPosByChar() >= reading_.utf8Length()) { return; - if (backward) + } + if (backward) { reading_.moveCaret(-1, allow_split); + } reading_.erase(reading_.caretPosByChar(), 1, allow_split); } @@ -159,10 +189,11 @@ void Preedit::finish() { reading_.finish(); } * manipulating conversion string */ void Preedit::convert(CandidateType type, bool single_segment) { - if (source_.empty()) + if (source_.empty()) { conversion_.convert(type, single_segment); - else + } else { conversion_.convert(source_, single_segment); + } } void Preedit::convert(const std::string &source, bool single_segment) { @@ -173,10 +204,12 @@ void Preedit::convert(const std::string &source, bool single_segment) { void Preedit::revert() { conversion_.clear(); } void Preedit::commit(int segment_id, bool learn) { - if (conversion_.isConverting()) + if (conversion_.isConverting()) { conversion_.commit(segment_id, learn); - if (!conversion_.isConverting()) + } + if (!conversion_.isConverting()) { clear(); + } } int Preedit::nrSegments() { return conversion_.nrSegments(); } @@ -221,29 +254,29 @@ void Preedit::selectCandidate(int candidate_id, int segment_id) { unsigned int Preedit::caretPos() { if (isConverting()) { return conversion_.segmentPosition(); - } else { - if (inputMode() == InputMode::HALF_KATAKANA) { - // FIXME! It's ad-hoc - std::string substr; - substr = reading_.getByChar(0, reading_.caretPosByChar(), - FCITX_ANTHY_STRING_HALF_KATAKANA); - return substr.length(); - } else { - return reading_.caretPos(); - } } + if (inputMode() == InputMode::HALF_KATAKANA) { + // FIXME! It's ad-hoc + std::string substr; + substr = reading_.getByChar(0, reading_.caretPosByChar(), + FCITX_ANTHY_STRING_HALF_KATAKANA); + return substr.length(); + } + return reading_.caretPos(); } void Preedit::setCaretPosByChar(unsigned int pos) { - if (isConverting()) + if (isConverting()) { return; + } reading_.setCaretPosByChar(pos); } void Preedit::moveCaret(int step) { - if (isConverting()) + if (isConverting()) { return; + } TypingMethod method = typingMethod(); bool allow_split = method == TypingMethod::ROMAJI && @@ -320,24 +353,26 @@ bool Preedit::isPseudoAsciiMode() { return reading_.isPseudoAsciiMode(); } void Preedit::resetPseudoAsciiMode() { reading_.resetPseudoAsciiMode(); } -bool Preedit::isCommaOrPeriod(const std::string &str) { +bool Preedit::isCommaOrPeriod(const std::string &str) const { TypingMethod typing = typingMethod(); PeriodStyle period = periodStyle(); CommaStyle comma = commaStyle(); - ConvRule *period_rule = get_period_rule(typing, period); - ConvRule *comma_rule = get_comma_rule(typing, comma); + const auto *period_rule = get_period_rule(typing, period); + const auto *comma_rule = get_comma_rule(typing, comma); - for (unsigned int i = 0; period_rule && period_rule[i].string; i++) { - if (period_rule[i].string && - !strcmp(period_rule[i].string, str.c_str())) { - return true; + if (period_rule) { + for (const auto &item : *period_rule) { + if (item.string == str) { + return true; + } } } - for (unsigned int i = 0; comma_rule && comma_rule[i].string; i++) { - if (comma_rule[i].string && - !strcmp(comma_rule[i].string, str.c_str())) { - return true; + if (comma_rule) { + for (const auto &item : *comma_rule) { + if (item.string == str) { + return true; + } } } @@ -347,17 +382,18 @@ bool Preedit::isCommaOrPeriod(const std::string &str) { /* * utilities */ -static ConvRule *get_period_rule(TypingMethod method, PeriodStyle period) { +static const std::array *get_period_rule(TypingMethod method, + PeriodStyle period) { switch (method) { case TypingMethod::KANA: switch (period) { case PeriodStyle::WIDE: - return fcitx_anthy_kana_wide_period_rule; + return &fcitx_anthy_kana_wide_period_rule; case PeriodStyle::HALF: - return fcitx_anthy_kana_half_period_rule; + return &fcitx_anthy_kana_half_period_rule; case PeriodStyle::JAPANESE: default: - return fcitx_anthy_kana_ja_period_rule; + return &fcitx_anthy_kana_ja_period_rule; }; break; @@ -365,12 +401,12 @@ static ConvRule *get_period_rule(TypingMethod method, PeriodStyle period) { default: switch (period) { case PeriodStyle::WIDE: - return fcitx_anthy_romaji_wide_period_rule; + return &fcitx_anthy_romaji_wide_period_rule; case PeriodStyle::HALF: - return fcitx_anthy_romaji_half_period_rule; + return &fcitx_anthy_romaji_half_period_rule; case PeriodStyle::JAPANESE: default: - return fcitx_anthy_romaji_ja_period_rule; + return &fcitx_anthy_romaji_ja_period_rule; }; break; }; @@ -378,17 +414,18 @@ static ConvRule *get_period_rule(TypingMethod method, PeriodStyle period) { return nullptr; } -static ConvRule *get_comma_rule(TypingMethod method, CommaStyle period) { +static const std::array *get_comma_rule(TypingMethod method, + CommaStyle period) { switch (method) { case TypingMethod::KANA: switch (period) { case CommaStyle::WIDE: - return fcitx_anthy_kana_wide_comma_rule; + return &fcitx_anthy_kana_wide_comma_rule; case CommaStyle::HALF: - return fcitx_anthy_kana_half_comma_rule; + return &fcitx_anthy_kana_half_comma_rule; case CommaStyle::JAPANESE: default: - return fcitx_anthy_kana_ja_comma_rule; + return &fcitx_anthy_kana_ja_comma_rule; }; break; @@ -396,12 +433,12 @@ static ConvRule *get_comma_rule(TypingMethod method, CommaStyle period) { default: switch (period) { case CommaStyle::WIDE: - return fcitx_anthy_romaji_wide_comma_rule; + return &fcitx_anthy_romaji_wide_comma_rule; case CommaStyle::HALF: - return fcitx_anthy_romaji_half_comma_rule; + return &fcitx_anthy_romaji_half_comma_rule; case CommaStyle::JAPANESE: default: - return fcitx_anthy_romaji_ja_comma_rule; + return &fcitx_anthy_romaji_ja_comma_rule; }; break; }; diff --git a/src/preedit.h b/src/preedit.h index 8b47a6a..44ce646 100644 --- a/src/preedit.h +++ b/src/preedit.h @@ -8,10 +8,16 @@ #ifndef _FCITX5_ANTHY_PREEDIT_H_ #define _FCITX5_ANTHY_PREEDIT_H_ +#include "config.h" #include "conversion.h" +#include "key2kana_table.h" #include "reading.h" #include +#include #include +#include +#include +#include #define FCITX_ANTHY_PSEUDO_ASCII_TRIGGERED_CAPITALIZED (1 << 0) #define FCITX_ANTHY_PSEUDO_ASCII_TRIGGERED_COUPLE_OF_CAPITAL (1 << 1) @@ -48,7 +54,7 @@ class Preedit { bool single_segment = false); void convert(const std::string &source, bool single_segment = false); void revert(); - void commit(int segment_id = -1, bool lean = true); + void commit(int segment_id = -1, bool learn = true); // for prediction void predict(); @@ -69,7 +75,7 @@ class Preedit { // for handling the caret unsigned int caretPos(); void setCaretPosByChar(unsigned int pos); - void moveCaret(int len); + void moveCaret(int step); // clear all or part of the string. void clear(int segment_id = -1); @@ -94,9 +100,8 @@ class Preedit { void resetPseudoAsciiMode(); private: - bool isCommaOrPeriod(const std::string &str); + bool isCommaOrPeriod(const std::string &str) const; -private: AnthyState &state_; // converter objects diff --git a/src/reading.cpp b/src/reading.cpp index 29039dc..d739cea 100644 --- a/src/reading.cpp +++ b/src/reading.cpp @@ -7,64 +7,69 @@ */ #include "reading.h" +#include "config.h" +#include "default_tables.h" #include "engine.h" +#include "key2kana_table.h" #include "state.h" #include "utils.h" +#include #include +#include +#include +#include ReadingSegment::ReadingSegment() {} ReadingSegment::~ReadingSegment() {} -static const char *find_romaji(std::string c) { - ConvRule *table = fcitx_anthy_romaji_typing_rule; - - for (unsigned int i = 0; table[i].string; i++) { - std::string kana = table[i].result; - if (c == kana) - return table[i].string; +static std::string_view find_romaji(std::string_view c) { + for (const auto &item : fcitx_anthy_romaji_typing_rule) { + if (c == item.result) { + return item.string; + } } - return ""; + return {}; } -static void to_half(std::string &dest, std::string &src) { - WideRule *table = fcitx_anthy_wide_table; +static void to_half(std::string &dest, std::string_view src) { + const auto &table = fcitx_anthy_wide_table; - for (unsigned int i = 0; i < fcitx::utf8::length(src); i++) { + for (auto kana : fcitx::utf8::MakeUTF8StringViewRange(src)) { bool found = false; - std::string kana1 = util::utf8_string_substr(src, i, 1); - for (unsigned int i = 0; table[i].code; i++) { - std::string kana2 = table[i].wide; - if (kana1 == kana2) { - dest += table[i].code; + for (const auto &item : table) { + if (kana == item.wide) { + dest += item.code; found = true; break; } } - if (!found) - dest += kana1; + if (!found) { + dest += kana; + } } } // Only a romaji string can be splited with raw key string. // Other typing method aren't supported splitting raw key string. void ReadingSegment::split(ReadingSegments &segments) { - if (fcitx::utf8::length(kana) <= 1) + if (fcitx::utf8::length(kana) <= 1) { segments.push_back(*this); + } std::string half; to_half(half, kana); bool same_with_raw = half == raw; - for (unsigned int i = 0; i < fcitx::utf8::length(kana); i++) { - std::string c = util::utf8_string_substr(kana, i, 1); + for (auto c : fcitx::utf8::MakeUTF8StringViewRange(kana)) { ReadingSegment seg; seg.kana = c; - if (same_with_raw) + if (same_with_raw) { to_half(seg.raw, c); - else + } else { seg.raw = find_romaji(c); + } segments.push_back(seg); } } @@ -79,15 +84,17 @@ Reading::Reading(AnthyState &anthy) Reading::~Reading() {} bool Reading::canProcesKeyEvent(const fcitx::KeyEvent &key) { - if (kana_.canAppend(key)) + if (kana_.canAppend(key)) { return true; + } return key2kana_->canAppend(key); } bool Reading::processKeyEvent(const fcitx::KeyEvent &key) { - if (!canProcesKeyEvent(key)) + if (!canProcesKeyEvent(key)) { return false; + } if (caretOffset_ != 0) { splitSegment(segmentPos_); @@ -95,18 +102,21 @@ bool Reading::processKeyEvent(const fcitx::KeyEvent &key) { } bool was_pending; - if (kana_.canAppend(key)) + if (kana_.canAppend(key)) { was_pending = kana_.isPending(); - else + } else { was_pending = key2kana_->isPending(); + } std::string raw; - std::string result, pending; + std::string result; + std::string pending; bool need_commiting; - if (kana_.canAppend(key)) + if (kana_.canAppend(key)) { need_commiting = kana_.append(key, result, pending, raw); - else + } else { need_commiting = key2kana_->append(key, result, pending, raw); + } ReadingSegments::iterator begin = segments_.begin(); @@ -146,8 +156,9 @@ bool Reading::processKeyEvent(const fcitx::KeyEvent &key) { } void Reading::finish() { - if (!key2kana_->isPending()) + if (!key2kana_->isPending()) { return; + } std::string result = key2kana_->flushPending(); if (!result.empty()) { @@ -166,14 +177,17 @@ void Reading::clear() { std::string Reading::getByChar(unsigned int start, int len, StringType type) { std::string str; - unsigned int pos = 0, end = len > 0 ? start + len : utf8Length() - start; + unsigned int pos = 0; + unsigned int end = len > 0 ? (start + len) : (utf8Length() - start); std::string kana; std::string raw; - if (start >= end) + if (start >= end) { return str; - if (start >= utf8Length()) + } + if (start >= utf8Length()) { return str; + } switch (type) { case FCITX_ANTHY_STRING_LATIN: @@ -190,28 +204,30 @@ std::string Reading::getByChar(unsigned int start, int len, StringType type) { break; } - for (unsigned int i = 0; i < segments_.size(); i++) { - if (pos >= start || - pos + fcitx::utf8::length(segments_[i].kana) > start) { - unsigned int startstart = 0, len; + for (auto &segment : segments_) { + if (pos >= start || pos + fcitx::utf8::length(segment.kana) > start) { + unsigned int startstart = 0; + unsigned int len; - if (pos >= start) + if (pos >= start) { startstart = 0; - else + } else { startstart = pos - start; + } - if (pos + fcitx::utf8::length(segments_[i].kana) > end) + if (pos + fcitx::utf8::length(segment.kana) > end) { len = end - start; - else - len = fcitx::utf8::length(segments_[i].kana); + } else { + len = fcitx::utf8::length(segment.kana); + } - kana += - util::utf8_string_substr(segments_[i].kana, startstart, len); + kana += util::utf8_string_substr(segment.kana, startstart, len); } - pos += fcitx::utf8::length(segments_[i].kana); - if (pos >= end) + pos += fcitx::utf8::length(segment.kana); + if (pos >= end) { break; + } } switch (type) { @@ -236,48 +252,54 @@ std::string Reading::getByChar(unsigned int start, int len, StringType type) { std::string Reading::getRawByChar(unsigned int start, int len) { std::string str; - unsigned int pos = 0, end = len > 0 ? start + len : utf8Length() - start; + unsigned int pos = 0; + unsigned int end = len > 0 ? (start + len) : (utf8Length() - start); - if (start >= end) + if (start >= end) { return str; + } - for (unsigned int i = 0; i < segments_.size(); i++) { - if (pos >= start || - pos + fcitx::utf8::length(segments_[i].kana) > start) { + for (auto &segment : segments_) { + if (pos >= start || pos + fcitx::utf8::length(segment.kana) > start) { // FIXME! - str += segments_[i].raw; + str += segment.raw; } - pos += fcitx::utf8::length(segments_[i].kana); + pos += fcitx::utf8::length(segment.kana); - if (pos >= end) + if (pos >= end) { break; + } } return str; } void Reading::splitSegment(unsigned int seg_id) { - if (seg_id >= segments_.size()) + if (seg_id >= segments_.size()) { return; + } unsigned int pos = 0; - for (unsigned int i = 0; i < seg_id && i < segments_.size(); i++) + for (unsigned int i = 0; i < seg_id && i < segments_.size(); i++) { pos += segments_[i].kana.length(); + } unsigned int caret = caretPos(); unsigned int seg_len = segments_[seg_id].kana.length(); bool caret_was_in_the_segment = false; - if (caret > pos && caret < pos + seg_len) + if (caret > pos && caret < pos + seg_len) { caret_was_in_the_segment = true; + } ReadingSegments segments; segments_[seg_id].split(segments); segments_.erase(segments_.begin() + seg_id); for (int j = segments.size() - 1; j >= 0; j--) { segments_.insert(segments_.begin() + seg_id, segments[j]); - if (segmentPos_ > seg_id) + if (segmentPos_ > seg_id) { segmentPos_++; + } } if (caret_was_in_the_segment) { @@ -288,28 +310,32 @@ void Reading::splitSegment(unsigned int seg_id) { bool Reading::append(const fcitx::KeyEvent &key, const std::string &string) { bool was_pending; - std::string result, pending; + std::string result; + std::string pending; bool need_commiting; - if (!kana_.canAppend(key, true) && !key2kana_->canAppend(key, true)) + if (!kana_.canAppend(key, true) && !key2kana_->canAppend(key, true)) { return false; + } if (caretOffset_ != 0) { splitSegment(segmentPos_); resetPending(); } - if (kana_.canAppend(key)) + if (kana_.canAppend(key)) { was_pending = kana_.isPending(); - else + } else { was_pending = key2kana_->isPending(); + } - if (kana_.canAppend(key)) + if (kana_.canAppend(key)) { need_commiting = kana_.append(string, result, pending); - else + } else { need_commiting = key2kana_->append(string, result, pending); + } - ReadingSegments::iterator begin = segments_.begin(); + auto begin = segments_.begin(); // fix previous segment and prepare next segment if needed if (!result.empty() || !pending.empty()) { @@ -347,14 +373,17 @@ bool Reading::append(const fcitx::KeyEvent &key, const std::string &string) { } void Reading::erase(unsigned int start, int len, bool allow_split) { - if (segments_.size() <= 0) + if (segments_.size() <= 0) { return; + } - if (utf8Length() < start) + if (utf8Length() < start) { return; + } - if (len < 0) + if (len < 0) { len = utf8Length() - start; + } // erase unsigned int pos = 0; @@ -362,16 +391,18 @@ void Reading::erase(unsigned int start, int len, bool allow_split) { if (pos < start) { // we have not yet reached start position. - if (i == (int)segments_.size()) + if (i == (int)segments_.size()) { break; + } pos += fcitx::utf8::length(segments_[i].kana); } else if (pos == start) { // we have reached start position. - if (i == (int)segments_.size()) + if (i == (int)segments_.size()) { break; + } if (allow_split && pos + fcitx::utf8::length(segments_[i].kana) > start + len) { @@ -383,8 +414,9 @@ void Reading::erase(unsigned int start, int len, bool allow_split) { // This segment is completely in the rage, erase it! len -= fcitx::utf8::length(segments_[i].kana); segments_.erase(segments_.begin() + i); - if ((int)segmentPos_ > i) + if ((int)segmentPos_ > i) { segmentPos_--; + } } // retry from the same position @@ -407,8 +439,9 @@ void Reading::erase(unsigned int start, int len, bool allow_split) { len -= pos - start; pos -= fcitx::utf8::length(segments_[i - 1].kana); segments_.erase(segments_.begin() + i - 1); - if ((int)segmentPos_ > i - 1) + if ((int)segmentPos_ > i - 1) { segmentPos_--; + } // retry from the previous position i -= 2; @@ -417,8 +450,9 @@ void Reading::erase(unsigned int start, int len, bool allow_split) { // Now all letters in the range are removed. // Exit the loop. - if (len <= 0) + if (len <= 0) { break; + } } // reset values @@ -430,13 +464,16 @@ void Reading::erase(unsigned int start, int len, bool allow_split) { } void Reading::resetPending() { - if (key2kana_->isPending()) + if (key2kana_->isPending()) { key2kana_->clear(); - if (kana_.isPending()) + } + if (kana_.isPending()) { kana_.clear(); + } - if (segmentPos_ <= 0) + if (segmentPos_ <= 0) { return; + } key2kana_->resetPending(segments_[segmentPos_ - 1].kana, segments_[segmentPos_ - 1].raw); @@ -452,15 +489,17 @@ void Reading::resetPending() { unsigned int Reading::length() { unsigned int len = 0; - for (unsigned int i = 0; i < segments_.size(); i++) - len += segments_[i].kana.length(); + for (auto &segment : segments_) { + len += segment.kana.length(); + } return len; } unsigned int Reading::utf8Length() { unsigned int len = 0; - for (unsigned int i = 0; i < segments_.size(); i++) - len += fcitx::utf8::length(segments_[i].kana); + for (auto &segment : segments_) { + len += fcitx::utf8::length(segment.kana); + } return len; } @@ -495,8 +534,9 @@ unsigned int Reading::caretPos() { // FIXME! add "allow_split" argument. void Reading::setCaretPosByChar(unsigned int pos) { - if (pos == caretPosByChar()) + if (pos == caretPosByChar()) { return; + } key2kana_->clear(); kana_.clear(); @@ -508,10 +548,12 @@ void Reading::setCaretPosByChar(unsigned int pos) { segmentPos_ = 0; } else { - unsigned int i, tmp_pos = 0; + unsigned int i; + unsigned int tmp_pos = 0; - for (i = 0; tmp_pos <= pos; i++) + for (i = 0; tmp_pos <= pos; i++) { tmp_pos += fcitx::utf8::length(segments_[i].kana); + } if (tmp_pos == pos) { segmentPos_ = i + 1; @@ -526,8 +568,9 @@ void Reading::setCaretPosByChar(unsigned int pos) { } void Reading::moveCaret(int step, bool allow_split) { - if (step == 0) + if (step == 0) { return; + } key2kana_->clear(); kana_.clear(); @@ -552,10 +595,9 @@ void Reading::moveCaret(int step, bool allow_split) { if (pos + fcitx::utf8::length(it->kana) > new_pos) { caretOffset_ = new_pos - pos; break; - } else { - segmentPos_++; - pos += fcitx::utf8::length(it->kana); } + segmentPos_++; + pos += fcitx::utf8::length(it->kana); } } @@ -599,10 +641,10 @@ void Reading::setTypingMethod(TypingMethod method) { } TypingMethod Reading::typingMethod() const { - if (key2kana_ == &nicola_) + if (key2kana_ == &nicola_) { return TypingMethod::NICOLA; - else - return key2kanaTables_.typingMethod(); + } + return key2kanaTables_.typingMethod(); } void Reading::setPeriodStyle(PeriodStyle style) { diff --git a/src/reading.h b/src/reading.h index df68aa5..ace48e5 100644 --- a/src/reading.h +++ b/src/reading.h @@ -9,24 +9,29 @@ #ifndef __FCITX_ANTHY_READING_H__ #define __FCITX_ANTHY_READING_H__ -#include "engine.h" +#include "config.h" #include "kana.h" #include "key2kana.h" +#include "key2kana_base.h" +#include "key2kana_table.h" #include "nicola.h" +#include +#include +#include class AnthyState; -typedef enum { +enum StringType { FCITX_ANTHY_STRING_LATIN, FCITX_ANTHY_STRING_WIDE_LATIN, FCITX_ANTHY_STRING_HIRAGANA, FCITX_ANTHY_STRING_KATAKANA, FCITX_ANTHY_STRING_HALF_KATAKANA, -} StringType; +}; class Reading; class ReadingSegment; -typedef std::vector ReadingSegments; +using ReadingSegments = std::vector; class ReadingSegment { friend class Reading; @@ -91,7 +96,6 @@ class Reading { void resetPending(); void splitSegment(unsigned int seg_id); -private: AnthyState &state_; // tables diff --git a/src/state.cpp b/src/state.cpp index bee5053..9351b07 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -12,28 +12,39 @@ * SPDX-FileCopyrightText: 2004 James Su */ -#include -#include -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "engine.h" #include "state.h" +#include "action.h" +#include "config.h" +#include "conversion.h" +#include "engine.h" +#include "key2kana_table.h" +#include "preedit.h" #include "utils.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include #include #include - -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include AnthyState::AnthyState(fcitx::InputContext *ic, AnthyEngine *engine, fcitx::Instance *instance) @@ -46,9 +57,10 @@ AnthyState::AnthyState(fcitx::InputContext *ic, AnthyEngine *engine, AnthyState::~AnthyState() {} // FIXME! -bool AnthyState::isNicolaThumbShiftKey(const fcitx::KeyEvent &key) { - if (typingMethod() != TypingMethod::NICOLA) +bool AnthyState::isNicolaThumbShiftKey(const fcitx::KeyEvent &key) const { + if (typingMethod() != TypingMethod::NICOLA) { return false; + } if (util::match_key_event(*config().key->leftThumbKeys, key.rawKey(), fcitx::KeyStates(0xFFFF)) || @@ -103,10 +115,10 @@ bool AnthyState::processKeyEventInput(const fcitx::KeyEvent &key) { } bool AnthyState::processKeyEventLookupKeybind(const fcitx::KeyEvent &key) { - decltype(actions_)::iterator it; - if (key.isRelease()) + if (key.isRelease()) { return false; + } lastKey_ = key.rawKey(); @@ -116,17 +128,16 @@ bool AnthyState::processKeyEventLookupKeybind(const fcitx::KeyEvent &key) { if (pseudoAsciiMode() != 0 && *config().general->romajiPseudoAsciiBlankBehavior && preedit_.isPseudoAsciiMode()) { - it = std::find_if(actions_.begin(), actions_.end(), - [](const Action &action) { - return action.name() == "INSERT_SPACE"; - }); - if (it != actions_.end() && it->perform(this, key)) { + auto it = std::ranges::find_if(actions_, [](const Action &action) { + return action.name() == "INSERT_SPACE"; + }); + if (it != actions_.end() && it->perform(key)) { return true; } } - for (it = actions_.begin(); it != actions_.end(); it++) { - if (it->perform(this, key)) { + for (auto &action : actions_) { + if (action.perform(key)) { lastKey_ = fcitx::Key(); return true; } @@ -148,31 +159,32 @@ bool AnthyState::processKeyEventLookupKeybind(const fcitx::KeyEvent &key) { } bool AnthyState::processKeyEventLatinMode(const fcitx::KeyEvent &key) { - if (key.isRelease()) + if (key.isRelease()) { return false; + } if (util::key_is_keypad(key.rawKey())) { std::string wide; auto str = util::keypad_to_string(key); - if (*config().general->tenKeyType == TenKeyType::WIDE) + if (*config().general->tenKeyType == TenKeyType::WIDE) { wide = util::convert_to_wide(str); - else + } else { wide = str; + } if (!wide.empty()) { commitString(wide); return true; - } else { - return false; } - } else { - // for Multi/Dead key return false; - } + + } // for Multi/Dead key + return false; } bool AnthyState::processKeyEventWideLatinMode(const fcitx::KeyEvent &key) { - if (key.isRelease()) + if (key.isRelease()) { return false; + } std::string wide; auto str = util::keypad_to_string(key); @@ -194,13 +206,15 @@ bool AnthyState::processKeyEvent(const fcitx::KeyEvent &key) { // FIXME! // for NICOLA thumb shift key if (typingMethod() == TypingMethod::NICOLA && isNicolaThumbShiftKey(key)) { - if (processKeyEventInput(key)) + if (processKeyEventInput(key)) { return true; + } } // lookup user defined key bindings - if (processKeyEventLookupKeybind(key)) + if (processKeyEventLookupKeybind(key)) { return true; + } if (key.rawKey().isDigit() && ic_->inputPanel().candidateList() && ic_->inputPanel().candidateList()->size()) { @@ -208,23 +222,23 @@ bool AnthyState::processKeyEvent(const fcitx::KeyEvent &key) { } // for Latin mode - if (preedit_.inputMode() == InputMode::LATIN) + if (preedit_.inputMode() == InputMode::LATIN) { return processKeyEventLatinMode(key); + } // for wide Latin mode - if (preedit_.inputMode() == InputMode::WIDE_LATIN) + if (preedit_.inputMode() == InputMode::WIDE_LATIN) { return processKeyEventWideLatinMode(key); + } // for other mode if (typingMethod() != TypingMethod::NICOLA || !isNicolaThumbShiftKey(key)) { - if (processKeyEventInput(key)) + if (processKeyEventInput(key)) { return true; + } } - if (preedit_.isPreediting()) - return true; - else - return false; + return preedit_.isPreediting(); } void AnthyState::movePreeditCaret(unsigned int pos) { @@ -234,8 +248,9 @@ void AnthyState::movePreeditCaret(unsigned int pos) { } void AnthyState::selectCandidateNoDirect(unsigned int item) { - if (preedit_.isPredicting() && !preedit_.isConverting()) + if (preedit_.isPredicting() && !preedit_.isConverting()) { action_predict(); + } // update lookup table cursorPos_ = item; @@ -247,8 +262,9 @@ void AnthyState::selectCandidateNoDirect(unsigned int item) { setLookupTable(); // update aux string - if (*config().general->showCandidatesLabel) + if (*config().general->showCandidatesLabel) { setAuxString(); + } } void AnthyState::selectCandidate(unsigned int item) { @@ -287,10 +303,11 @@ void AnthyState::updateUI() { void AnthyState::setAuxString() { if (!ic_->inputPanel().candidateList() || - !ic_->inputPanel().candidateList()->size()) + !ic_->inputPanel().candidateList()->size()) { return; + } - if (auto bulk = ic_->inputPanel().candidateList()->toBulk()) { + if (auto *bulk = ic_->inputPanel().candidateList()->toBulk()) { char buf[256]; sprintf(buf, _("(%d / %d)"), cursorPos_ + 1, bulk->totalSize()); updateAuxString(buf); @@ -303,8 +320,9 @@ std::shared_ptr AnthyState::setLookupTable() { if (isRealtimeConversion() && preedit_.selectedSegment() < 0) { // select latest segment int n = preedit_.nrSegments(); - if (n < 1) + if (n < 1) { return 0; + } preedit_.selectSegment(n - 1); } @@ -444,8 +462,9 @@ bool AnthyState::isSelectingCandidates() { void AnthyState::deactivate() {} bool AnthyState::action_convert() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } if (!preedit_.isConverting()) { // show conversion string @@ -461,14 +480,17 @@ bool AnthyState::action_convert() { } bool AnthyState::action_predict() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } - if (preedit_.isConverting()) + if (preedit_.isConverting()) { return false; + } - if (!preedit_.isPredicting()) + if (!preedit_.isPredicting()) { preedit_.predict(); + } preedit_.selectCandidate(0); setPreedition(); @@ -487,8 +509,9 @@ bool AnthyState::action_revert() { return true; } - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } if (!preedit_.isConverting()) { reset(); @@ -507,26 +530,31 @@ bool AnthyState::action_revert() { } bool AnthyState::action_cancel_all() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } reset(); return true; } bool AnthyState::action_commit(bool learn, bool do_real_commit) { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } if (preedit_.isConverting()) { - if (do_real_commit) + if (do_real_commit) { commitString(preedit_.string()); - if (learn) + } + if (learn) { preedit_.commit(); + } } else { preedit_.finish(); - if (do_real_commit) + if (do_real_commit) { commitString(preedit_.string()); + } } reset(); @@ -543,13 +571,15 @@ bool AnthyState::action_commit_reverse_preference() { } bool AnthyState::action_back() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } if (preedit_.isConverting()) { action_revert(); - if (!isRealtimeConversion()) + if (!isRealtimeConversion()) { return true; + } } preedit_.erase(); @@ -568,13 +598,15 @@ bool AnthyState::action_back() { } bool AnthyState::action_delete() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } if (preedit_.isConverting()) { action_revert(); - if (!isRealtimeConversion()) + if (!isRealtimeConversion()) { return true; + } } preedit_.erase(false); @@ -594,20 +626,19 @@ bool AnthyState::action_delete() { bool AnthyState::action_insert_space() { std::string str; - bool is_wide = false, retval = false; + bool is_wide = false; + bool retval = false; if (preedit_.isPreediting() && - !*config().general->romajiPseudoAsciiBlankBehavior) + !*config().general->romajiPseudoAsciiBlankBehavior) { return false; + } if (*config().general->spaceType == SpaceType::FOLLOWMODE) { - InputMode mode = inputMode(); - if (mode == InputMode::LATIN || mode == InputMode::HALF_KATAKANA || - preedit_.isPseudoAsciiMode()) { - is_wide = false; - } else { - is_wide = true; - } + const InputMode mode = inputMode(); + is_wide = + (mode != InputMode::LATIN && mode != InputMode::HALF_KATAKANA && + !preedit_.isPseudoAsciiMode()); } else if (*config().general->spaceType == SpaceType::WIDE) { is_wide = true; } @@ -641,16 +672,14 @@ bool AnthyState::action_insert_space() { bool AnthyState::action_insert_alternative_space() { bool is_wide = false; - if (preedit_.isPreediting()) + if (preedit_.isPreediting()) { return false; + } if (*config().general->spaceType == SpaceType::FOLLOWMODE) { - InputMode mode = inputMode(); - if (mode == InputMode::LATIN || mode == InputMode::HALF_KATAKANA) { - is_wide = true; - } else { - is_wide = false; - } + const InputMode mode = inputMode(); + is_wide = + (mode == InputMode::LATIN || mode == InputMode::HALF_KATAKANA); } else if (*config().general->spaceType != SpaceType::WIDE) { is_wide = true; } @@ -658,10 +687,11 @@ bool AnthyState::action_insert_alternative_space() { if (is_wide) { commitString("\xE3\x80\x80"); return true; - } else if (typingMethod() == TypingMethod::NICOLA || // FIXME! it's a ad-hoc - // solution. - (lastKey_.sym() != FcitxKey_space && - lastKey_.sym() != FcitxKey_KP_Space)) { + } + if (typingMethod() == TypingMethod::NICOLA || // FIXME! it's a ad-hoc + // solution. + (lastKey_.sym() != FcitxKey_space && + lastKey_.sym() != FcitxKey_KP_Space)) { commitString(" "); return true; } @@ -670,8 +700,9 @@ bool AnthyState::action_insert_alternative_space() { } bool AnthyState::action_insert_half_space() { - if (preedit_.isPreediting()) + if (preedit_.isPreediting()) { return false; + } if (lastKey_.sym() != FcitxKey_space && lastKey_.sym() != FcitxKey_KP_Space) { @@ -683,8 +714,9 @@ bool AnthyState::action_insert_half_space() { } bool AnthyState::action_insert_wide_space() { - if (preedit_.isPreediting()) + if (preedit_.isPreediting()) { return false; + } commitString("\xE3\x80\x80"); @@ -692,10 +724,12 @@ bool AnthyState::action_insert_wide_space() { } bool AnthyState::action_move_caret_backward() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; - if (preedit_.isConverting()) + } + if (preedit_.isConverting()) { return false; + } preedit_.moveCaret(-1); setPreedition(); @@ -704,10 +738,12 @@ bool AnthyState::action_move_caret_backward() { } bool AnthyState::action_move_caret_forward() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; - if (preedit_.isConverting()) + } + if (preedit_.isConverting()) { return false; + } preedit_.moveCaret(1); setPreedition(); @@ -716,10 +752,12 @@ bool AnthyState::action_move_caret_forward() { } bool AnthyState::action_move_caret_first() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; - if (preedit_.isConverting()) + } + if (preedit_.isConverting()) { return false; + } preedit_.setCaretPosByChar(0); setPreedition(); @@ -728,10 +766,12 @@ bool AnthyState::action_move_caret_first() { } bool AnthyState::action_move_caret_last() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; - if (preedit_.isConverting()) + } + if (preedit_.isConverting()) { return false; + } preedit_.setCaretPosByChar(preedit_.utf8Length()); setPreedition(); @@ -740,16 +780,18 @@ bool AnthyState::action_move_caret_last() { } bool AnthyState::action_select_prev_segment() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } unsetLookupTable(); int idx = preedit_.selectedSegment(); if (idx - 1 < 0) { int n = preedit_.nrSegments(); - if (n <= 0) + if (n <= 0) { return false; + } preedit_.selectSegment(n - 1); } else { preedit_.selectSegment(idx - 1); @@ -760,8 +802,9 @@ bool AnthyState::action_select_prev_segment() { } bool AnthyState::action_select_next_segment() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } unsetLookupTable(); @@ -770,12 +813,14 @@ bool AnthyState::action_select_next_segment() { preedit_.selectSegment(0); } else { int n = preedit_.nrSegments(); - if (n <= 0) + if (n <= 0) { return false; - if (idx + 1 >= n) + } + if (idx + 1 >= n) { preedit_.selectSegment(0); - else + } else { preedit_.selectSegment(idx + 1); + } } setPreedition(); @@ -783,8 +828,9 @@ bool AnthyState::action_select_next_segment() { } bool AnthyState::action_select_first_segment() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } unsetLookupTable(); @@ -795,12 +841,14 @@ bool AnthyState::action_select_first_segment() { } bool AnthyState::action_select_last_segment() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } int n = preedit_.nrSegments(); - if (n <= 0) + if (n <= 0) { return false; + } unsetLookupTable(); @@ -811,8 +859,9 @@ bool AnthyState::action_select_last_segment() { } bool AnthyState::action_shrink_segment() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } unsetLookupTable(); @@ -823,8 +872,9 @@ bool AnthyState::action_shrink_segment() { } bool AnthyState::action_expand_segment() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } unsetLookupTable(); @@ -838,18 +888,18 @@ bool AnthyState::action_commit_first_segment() { if (!preedit_.isConverting()) { if (preedit_.isPreediting()) { return action_commit(*config().general->learnOnManualCommit); - } else { - return false; } + return false; } unsetLookupTable(); commitString(preedit_.segmentString(0)); - if (*config().general->learnOnManualCommit) + if (*config().general->learnOnManualCommit) { preedit_.commit(0); - else + } else { preedit_.clear(0); + } setPreedition(); @@ -860,19 +910,20 @@ bool AnthyState::action_commit_selected_segment() { if (!preedit_.isConverting()) { if (preedit_.isPreediting()) { return action_commit(*config().general->learnOnManualCommit); - } else { - return false; } + return false; } unsetLookupTable(); - for (int i = 0; i <= preedit_.selectedSegment(); i++) + for (int i = 0; i <= preedit_.selectedSegment(); i++) { commitString(preedit_.segmentString(i)); - if (*config().general->learnOnManualCommit) + } + if (*config().general->learnOnManualCommit) { preedit_.commit(preedit_.selectedSegment()); - else + } else { preedit_.clear(preedit_.selectedSegment()); + } setPreedition(); @@ -883,18 +934,18 @@ bool AnthyState::action_commit_first_segment_reverse_preference() { if (!preedit_.isConverting()) { if (preedit_.isPreediting()) { return action_commit(!*config().general->learnOnManualCommit); - } else { - return false; } + return false; } unsetLookupTable(); commitString(preedit_.segmentString(0)); - if (!*config().general->learnOnManualCommit) + if (!*config().general->learnOnManualCommit) { preedit_.commit(0); - else + } else { preedit_.clear(0); + } setPreedition(); @@ -905,19 +956,20 @@ bool AnthyState::action_commit_selected_segment_reverse_preference() { if (!preedit_.isConverting()) { if (preedit_.isPreediting()) { return action_commit(!*config().general->learnOnManualCommit); - } else { - return false; } + return false; } unsetLookupTable(); - for (int i = 0; i <= preedit_.selectedSegment(); i++) + for (int i = 0; i <= preedit_.selectedSegment(); i++) { commitString(preedit_.segmentString(i)); - if (!*config().general->learnOnManualCommit) + } + if (!*config().general->learnOnManualCommit) { preedit_.commit(preedit_.selectedSegment()); - else + } else { preedit_.clear(preedit_.selectedSegment()); + } setPreedition(); @@ -925,8 +977,9 @@ bool AnthyState::action_commit_selected_segment_reverse_preference() { } bool AnthyState::action_select_next_candidate() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } // if (!is_selecting_candidates ()) auto candList = setLookupTable(); @@ -938,8 +991,9 @@ bool AnthyState::action_select_next_candidate() { } bool AnthyState::action_select_prev_candidate() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; + } // if (!is_selecting_candidates ()) auto candList = setLookupTable(); nConvKeyPressed_++; @@ -951,10 +1005,12 @@ bool AnthyState::action_select_prev_candidate() { } bool AnthyState::action_select_first_candidate() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; - if (!isSelectingCandidates()) + } + if (!isSelectingCandidates()) { return false; + } cursorPos_ = 0; nConvKeyPressed_++; @@ -963,14 +1019,15 @@ bool AnthyState::action_select_first_candidate() { } bool AnthyState::action_select_last_candidate() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; - if (!isSelectingCandidates()) + } + if (!isSelectingCandidates()) { return false; + } int end = ic_->inputPanel().candidateList()->toBulk()->totalSize() - 1; - if (end < 0) - end = 0; + end = std::max(end, 0); cursorPos_ = end; nConvKeyPressed_++; selectCandidateNoDirect(cursorPos_); @@ -978,14 +1035,17 @@ bool AnthyState::action_select_last_candidate() { } bool AnthyState::action_candidates_page_up() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; - if (!isSelectingCandidates()) + } + if (!isSelectingCandidates()) { return false; - if (!lookupTableVisible_) + } + if (!lookupTableVisible_) { return false; + } - if (auto pageable = ic_->inputPanel().candidateList()->toPageable(); + if (auto *pageable = ic_->inputPanel().candidateList()->toPageable(); pageable && pageable->hasPrev()) { pageable->prev(); } @@ -994,14 +1054,17 @@ bool AnthyState::action_candidates_page_up() { } bool AnthyState::action_candidates_page_down() { - if (!preedit_.isConverting()) + if (!preedit_.isConverting()) { return false; - if (!isSelectingCandidates()) + } + if (!isSelectingCandidates()) { return false; - if (!lookupTableVisible_) + } + if (!lookupTableVisible_) { return false; + } - if (auto pageable = ic_->inputPanel().candidateList()->toPageable(); + if (auto *pageable = ic_->inputPanel().candidateList()->toPageable(); pageable && pageable->hasNext()) { pageable->next(); } @@ -1011,15 +1074,17 @@ bool AnthyState::action_candidates_page_down() { bool AnthyState::actionSelectCandidate(unsigned int i) { // FIXME! m_lookup_table_visible should be set as true also on predicting - if (!lookupTableVisible_ && !preedit_.isPredicting()) + if (!lookupTableVisible_ && !preedit_.isPredicting()) { return false; + } if (preedit_.isPredicting() && !preedit_.isConverting() && *config().general->useDirectKeyOnPredict) { ic_->inputPanel().setCandidateList(preedit_.candidates()); selectCandidate(i); return true; - } else if (preedit_.isConverting() && isSelectingCandidates()) { + } + if (preedit_.isConverting() && isSelectingCandidates()) { selectCandidate(i); return true; } @@ -1120,10 +1185,12 @@ bool AnthyState::action_half_katakana_mode() { } bool AnthyState::action_cancel_pseudo_ascii_mode() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; - if (!preedit_.isPseudoAsciiMode()) + } + if (!preedit_.isPseudoAsciiMode()) { return false; + } preedit_.resetPseudoAsciiMode(); @@ -1131,11 +1198,13 @@ bool AnthyState::action_cancel_pseudo_ascii_mode() { } bool AnthyState::convertKana(CandidateType type) { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } - if (preedit_.isReconverting()) + if (preedit_.isReconverting()) { return false; + } unsetLookupTable(); @@ -1183,8 +1252,9 @@ bool AnthyState::action_convert_to_wide_latin() { } bool AnthyState::action_convert_char_type_forward() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } unsetLookupTable(); @@ -1228,8 +1298,9 @@ bool AnthyState::action_convert_char_type_forward() { } bool AnthyState::action_convert_char_type_backward() { - if (!preedit_.isPreediting()) + if (!preedit_.isPreediting()) { return false; + } unsetLookupTable(); @@ -1273,8 +1344,9 @@ bool AnthyState::action_convert_char_type_backward() { } bool AnthyState::action_reconvert() { - if (preedit_.isPreediting()) + if (preedit_.isPreediting()) { return false; + } if (!ic_->capabilityFlags().test(fcitx::CapabilityFlag::SurroundingText)) { return true; @@ -1327,13 +1399,13 @@ bool AnthyState::action_reconvert() { return true; } -bool AnthyState::action_add_word() { +bool AnthyState::action_add_word() const { util::launch_program(*config().command->addWordCommand); return true; } -bool AnthyState::action_launch_dict_admin_tool() { +bool AnthyState::action_launch_dict_admin_tool() const { util::launch_program(*config().command->dictAdminCommand); return true; @@ -1357,13 +1429,14 @@ bool AnthyState::isRealtimeConversion() { engine_->conversionMode() == ConversionMode::SINGLE_SEGMENT_IMMEDIATE); } -int AnthyState::pseudoAsciiMode() { +int AnthyState::pseudoAsciiMode() const { int retval = 0; TypingMethod m = typingMethod(); if (m == TypingMethod::ROMAJI) { - if (*config().general->romajiPseudoAsciiMode) + if (*config().general->romajiPseudoAsciiMode) { retval |= FCITX_ANTHY_PSEUDO_ASCII_TRIGGERED_CAPITALIZED; + } } return retval; @@ -1391,12 +1464,12 @@ void AnthyState::commitString(const std::string &str) { } void AnthyState::copyTo(fcitx::InputContextProperty *property) { - AnthyState *other = static_cast(property); + auto *other = static_cast(property); other->setInputMode(inputMode()); } void AnthyState::configure() { - auto keyProfile = engine_->keyProfile(); + auto *keyProfile = engine_->keyProfile(); // clear old actions actions_.clear(); @@ -1408,9 +1481,8 @@ void AnthyState::configure() { hk = &keyProfile->hk_##KEY; \ } else \ hk = &*config().key->hk_##KEY; \ - PMF f; \ - f = &AnthyState::func; \ - actions_.emplace_back(name, *hk, f); \ + actions_.emplace_back(name, *hk, \ + std::bind_front(&AnthyState::func, this)); \ } #include "action_defs.h" #undef FOREACH_ACTION @@ -1435,10 +1507,11 @@ void AnthyState::updateAuxString(const std::string &str) { } void AnthyState::resetCursor(int cursor) { - if (cursor >= 0) + if (cursor >= 0) { cursorPos_ = cursor; - else + } else { cursor = 0; + } } void AnthyState::autoCommit(fcitx::InputContextEvent &event) { diff --git a/src/state.h b/src/state.h index 88abda1..10912d7 100644 --- a/src/state.h +++ b/src/state.h @@ -15,15 +15,22 @@ #ifndef _FCITX5_ANTHY_STATE_H_ #define _FCITX5_ANTHY_STATE_H_ +#include "action.h" +#include "config.h" +#include "conversion.h" #include "engine.h" -#include "key2kana_table.h" #include "preedit.h" #include +#include +#include +#include #include #include #include #include -#include +#include +#include +#include class AnthyState : public fcitx::InputContextProperty { public: @@ -33,7 +40,7 @@ class AnthyState : public fcitx::InputContextProperty { bool needCopy() const override { return true; } - void copyTo(fcitx::InputContextProperty *) override; + void copyTo(fcitx::InputContextProperty *property) override; void configure(); void saveConfig() { engine_->saveConfig(); } @@ -46,7 +53,6 @@ class AnthyState : public fcitx::InputContextProperty { auto inputContext() { return ic_; } -public: /* actions */ bool action_convert(); bool action_predict(); @@ -106,13 +112,12 @@ class AnthyState : public fcitx::InputContextProperty { bool action_half_katakana_mode(); bool action_cancel_pseudo_ascii_mode(); - bool action_add_word(); - bool action_launch_dict_admin_tool(); + bool action_add_word() const; + bool action_launch_dict_admin_tool() const; /* void actoin_register_word (); */ -public: TypingMethod typingMethod() const; InputMode inputMode() const; // Only input mode is per-state. @@ -123,7 +128,7 @@ class AnthyState : public fcitx::InputContextProperty { void syncSymbolStyle(); void updateUI(); - int pseudoAsciiMode(); + int pseudoAsciiMode() const; const AnthyConfig &config() const { return engine_->config(); } auto engine() { return engine_; } fcitx::Instance *instance() { return instance_; } @@ -154,12 +159,10 @@ class AnthyState : public fcitx::InputContextProperty { bool isSingleSegment(); bool isRealtimeConversion(); -private: // FIXME! - bool isNicolaThumbShiftKey(const fcitx::KeyEvent &key); + bool isNicolaThumbShiftKey(const fcitx::KeyEvent &key) const; void commitString(const std::string &str); void updateAuxString(const std::string &str); -private: fcitx::InputContext *ic_; AnthyEngine *engine_; fcitx::Instance *instance_; diff --git a/src/style_file.cpp b/src/style_file.cpp index 028f603..0e801c2 100644 --- a/src/style_file.cpp +++ b/src/style_file.cpp @@ -7,10 +7,17 @@ */ #include "style_file.h" +#include #include #include +#include #include #include +#include +#include +#include +#include +#include namespace { const int MAX_LINE_LENGTH = 4096; @@ -40,8 +47,9 @@ std::string unescape(const std::string &str) { for (unsigned int i = 0; i < dest.size(); i++) { if (dest[i] == '\\') { dest.erase(i, 1); - if (i < dest.size() && dest[i] == '\\') + if (i < dest.size() && dest[i] == '\\') { i++; + } } } @@ -69,29 +77,29 @@ StyleLine::~StyleLine() {} StyleLineType StyleLine::type() const { return type_; } -bool StyleLine::get_section(std::string §ion) const { +std::string StyleLine::get_section() const { + std::string section; if (type() != StyleLineType::SECTION) { - return false; + return section; } auto result = fcitx::stringutils::trim(line_); // remove [ and ] result.pop_back(); result = result.substr(1); - section = std::move(result); - - return true; + return result; } -bool StyleLine::get_key(std::string &key) const { - if (type() != StyleLineType::KEY) - return false; +std::string StyleLine::get_key() const { + std::string key; + if (type() != StyleLineType::KEY) { + return key; + } // skip space ahead. auto spos = line_.find_first_not_of(FCITX_WHITESPACE); if (spos == std::string::npos) { - key = std::string(); - return true; + return key; } size_t epos = spos; @@ -104,17 +112,21 @@ bool StyleLine::get_key(std::string &key) const { break; } } - for (--epos; epos >= spos && fcitx::charutils::isspace(line_[epos]); epos--) + for (--epos; epos >= spos && fcitx::charutils::isspace(line_[epos]); + epos--) { ; - if (!fcitx::charutils::isspace(line_[epos])) + } + if (!fcitx::charutils::isspace(line_[epos])) { epos++; + } if (spos < epos && epos <= line_.length()) { key = unescape(line_.substr(spos, epos - spos)); - } else + } else { key = std::string(); + } - return true; + return key; } static int get_value_position(std::string_view str) { @@ -128,32 +140,34 @@ static int get_value_position(std::string_view str) { break; } } - if (spos >= str.length()) + if (spos >= str.length()) { return true; - else - spos++; - for (; spos < str.length() && fcitx::charutils::isspace(str[spos]); spos++) - ; + } + spos++; + for (; spos < str.length() && fcitx::charutils::isspace(str[spos]); + spos++) { + } return spos; } -bool StyleLine::get_value(std::string &value) const { - if (type() != StyleLineType::KEY) - return false; +std::string StyleLine::get_value() const { + std::string value; + if (type() != StyleLineType::KEY) { + return value; + } unsigned int spos = get_value_position(line_); unsigned int epos = line_.length(); - value = unescape(line_.substr(spos, epos - spos)); - - return true; + return unescape(line_.substr(spos, epos - spos)); } -bool StyleLine::get_value_array(std::vector &value) const { - if (type() != StyleLineType::KEY) - return false; - +std::vector StyleLine::get_value_array() const { + std::vector value; + if (type() != StyleLineType::KEY) { + return value; + } unsigned int spos = get_value_position(line_); unsigned int epos = line_.length(); @@ -166,17 +180,18 @@ bool StyleLine::get_value_array(std::vector &value) const { if (i == epos || line_[i] == ',') { std::string str; - if (head_of_element == epos) + if (head_of_element == epos) { str = std::string(); - else + } else { str = unescape( line_.substr(head_of_element, i - head_of_element)); + } value.push_back(str); head_of_element = i + 1; } } - return true; + return value; } StyleFile::StyleFile() { setupDefaultEntries(); } @@ -186,20 +201,22 @@ bool StyleFile::load(const std::string &filename) { setupDefaultEntries(); std::ifstream in_file(filename); - if (!in_file) + if (!in_file) { return false; + } clear(); sections_.push_back(StyleLines()); - StyleLines *section = §ions_[0]; + StyleLines *section = sections_.data(); unsigned int section_id = 0; char buf[MAX_LINE_LENGTH]; do { in_file.getline(buf, MAX_LINE_LENGTH); - if (in_file.eof()) + if (in_file.eof()) { break; + } std::string dest = buf; StyleLine line(this, dest); @@ -214,10 +231,8 @@ bool StyleFile::load(const std::string &filename) { section->push_back(line); if (section_id == 0) { - std::string key; - line.get_key(key); - if (key == "Title") { - line.get_value(title_); + if (line.get_key() == "Title") { + title_ = line.get_value(); } } } while (!in_file.eof()); @@ -234,64 +249,61 @@ void StyleFile::clear() { const std::string &StyleFile::title() const { return title_; } -bool StyleFile::getString(std::string &value, std::string section, - std::string key) const { - for (auto it = sections_.begin(); it != sections_.end(); it++) { - if (it->size() <= 0) +std::optional StyleFile::getString(std::string_view section, + std::string_view key) const { + for (const auto &lines : sections_) { + if (lines.empty()) { continue; + } - std::string s, k; - (*it)[0].get_section(s); - - if (s != section) + if (lines[0].get_section() != section) { continue; + } - for (auto lit = it->begin(); lit != it->end(); lit++) { - lit->get_key(k); - if (k == key) { - lit->get_value(value); - return true; + for (const auto &line : lines) { + if (line.get_key() == key) { + return line.get_value(); } } } - return false; + return std::nullopt; } -bool StyleFile::getStringArray(std::vector &value, - std::string section, std::string key) const { +std::optional> +StyleFile::getStringArray(std::string_view section, + std::string_view key) const { const StyleLines *lines = findSection(section); - if (!lines) - return false; + if (!lines) { + return std::nullopt; + } // find entry - for (auto lit = lines->begin(); lit != lines->end(); lit++) { - std::string k; - lit->get_key(k); - if (k == key) { - lit->get_value_array(value); - return true; + for (const auto &line : *lines) { + if (line.get_key() == key) { + return line.get_value_array(); } } - return false; + return std::nullopt; } -bool StyleFile::getKeyList(std::vector &keys, - std::string section) const { +std::optional> +StyleFile::getKeyList(std::string_view section) const { const StyleLines *lines = findSection(section); - if (!lines) - return false; + if (!lines) { + return std::nullopt; + } - for (auto lit = lines->begin(); lit != lines->end(); lit++) { - if (lit->type() != StyleLineType::KEY) + std::vector keys; + for (const auto &line : *lines) { + if (line.type() != StyleLineType::KEY) { continue; + } - std::string key; - lit->get_key(key); - keys.push_back(key); + keys.push_back(line.get_key()); } - return true; + return {std::move(keys)}; } void StyleFile::setupDefaultEntries() { @@ -301,20 +313,19 @@ void StyleFile::setupDefaultEntries() { sections_.push_back(StyleLines()); StyleLines &newsec = sections_.back(); std::string str = std::string("Title") + std::string("=") + escape(title_); - newsec.push_back(StyleLine(this, str.c_str())); + newsec.push_back(StyleLine(this, str)); } -const StyleLines *StyleFile::findSection(const std::string §ion) const { +const StyleLines *StyleFile::findSection(std::string_view section) const { // find section - for (auto it = sections_.begin(); it != sections_.end(); it++) { - if (it->size() <= 0) + for (const auto &lines : sections_) { + if (lines.empty()) { continue; + } - std::string s; - (*it)[0].get_section(s); - - if (s == section) - return &(*it); + if (lines[0].get_section() == section) { + return &lines; + } } return nullptr; diff --git a/src/style_file.h b/src/style_file.h index eae62ef..1eac5ee 100644 --- a/src/style_file.h +++ b/src/style_file.h @@ -9,16 +9,18 @@ #define _FCITX5_ANTHY_STYLE_FILE_H_ #include +#include #include +#include #include class StyleLine; class StyleSection; class StyleFile; -typedef std::vector StyleLines; -typedef std::vector StyleSections; -typedef std::vector StyleFiles; +using StyleLines = std::vector; +using StyleSections = std::vector; +using StyleFiles = std::vector; enum class StyleLineType { UNKNOWN, @@ -33,13 +35,12 @@ class StyleLine { StyleLine(StyleFile *style_file, std::string line); ~StyleLine(); -public: StyleLineType type() const; std::string line() { return line_; } - bool get_section(std::string §ion) const; - bool get_key(std::string &key) const; - bool get_value(std::string &value) const; - bool get_value_array(std::vector &value) const; + std::string get_section() const; + std::string get_key() const; + std::string get_value() const; + std::vector get_value_array() const; private: StyleFile *styleFile_; @@ -52,23 +53,22 @@ class StyleFile { StyleFile(); FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITHOUT_SPEC(StyleFile); -public: bool load(const std::string &filename); const std::string &title() const; - bool getKeyList(std::vector &keys, std::string section) const; - bool getString(std::string &value, std::string section, - std::string key) const; - bool getStringArray(std::vector &value, std::string section, - std::string key) const; + std::optional> + getKeyList(std::string_view section) const; + std::optional getString(std::string_view section, + std::string_view key) const; + std::optional> + getStringArray(std::string_view section, std::string_view key) const; private: void clear(); void setupDefaultEntries(); - const StyleLines *findSection(const std::string §ion) const; + const StyleLines *findSection(std::string_view section) const; -private: std::string title_; StyleSections sections_; }; diff --git a/src/utils.cpp b/src/utils.cpp index 6fd90db..47eb64a 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -6,15 +6,26 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ +#include "utils.h" +#include "default_tables.h" +#include "fcitx-utils/keysym.h" +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include #include #include #include - -#include "default_tables.h" -#include "utils.h" -#include +#include std::string util::utf8_string_substr(const std::string &s, size_t start, size_t len) { @@ -24,97 +35,75 @@ std::string util::utf8_string_substr(const std::string &s, size_t start, return result; } -bool util::match_key_event(const fcitx::KeyList &hotkey, const fcitx::Key &_key, +bool util::match_key_event(const fcitx::KeyList &list, const fcitx::Key &key, fcitx::KeyStates ignore_mask) { - fcitx::Key key = fcitx::Key(_key.sym(), _key.states() & ~ignore_mask); - return key.checkKeyList(hotkey); + fcitx::Key normKey = fcitx::Key(key.sym(), key.states() & ~ignore_mask); + return normKey.checkKeyList(list); } -void util::split_string(std::string &str, std::vector &str_list, - char *delim, int num) { - std::string::size_type start = 0, end; - - for (int i = 0; (num > 0 && i < num) || start < str.length(); i++) { - end = str.find(delim, start); - if ((num > 0 && i == num - 1) || (end == std::string::npos)) - end = str.length(); - - if (start < str.length()) { - str_list.push_back(str.substr(start, end - start)); - start = end + strlen(delim); - } else { - str_list.push_back(std::string()); - } - } -} - -std::string util::convert_to_wide(const std::string &str) { +std::string util::convert_to_wide(std::string_view str) { std::string wide; - for (unsigned int i = 0; i < str.length(); i++) { - int c = str[i]; + for (const auto c : str) { char cc[2]; cc[0] = c; cc[1] = '\0'; bool found = false; - for (unsigned int j = 0; fcitx_anthy_wide_table[j].code; j++) { - if (fcitx_anthy_wide_table[j].code && - *fcitx_anthy_wide_table[j].code == c) { - wide += fcitx_anthy_wide_table[j].wide; + for (const auto &item : fcitx_anthy_wide_table) { + if (item.code == cc) { + wide += item.wide; found = true; break; } } - if (!found) + if (!found) { wide += cc; + } } return wide; } std::string util::convert_to_half(const std::string &str) { std::string half; - for (unsigned int i = 0; i < fcitx::utf8::length(str); i++) { - std::string wide = util::utf8_string_substr(str, i, 1); + for (auto wide : fcitx::utf8::MakeUTF8StringViewRange(str)) { bool found = false; - for (unsigned int j = 0; fcitx_anthy_wide_table[j].code; j++) { - if (fcitx_anthy_wide_table[j].wide && - wide == fcitx_anthy_wide_table[j].wide) { - half += fcitx_anthy_wide_table[j].code; + for (const auto &item : fcitx_anthy_wide_table) { + if (wide == item.wide) { + half += item.code; found = true; break; } } - if (!found) + if (!found) { half += wide; + } } return half; } std::string util::convert_to_katakana(const std::string &hira, bool half) { std::string kata; - for (unsigned int i = 0; i < fcitx::utf8::length(hira); i++) { - std::string tmpwide; + for (auto chr : fcitx::utf8::MakeUTF8StringViewRange(hira)) { bool found = false; - HiraganaKatakanaRule *table = fcitx_anthy_hiragana_katakana_table; - - for (unsigned int j = 0; table[j].hiragana; j++) { - tmpwide = table[j].hiragana; - if (util::utf8_string_substr(hira, i, 1) == tmpwide) { - if (half) - kata += table[j].half_katakana; - else - kata += table[j].katakana; + for (const auto &item : fcitx_anthy_hiragana_katakana_table) { + if (chr == item.hiragana) { + if (half) { + kata += item.half_katakana; + } else { + kata += item.katakana; + } found = true; break; } } - if (!found) - kata += util::utf8_string_substr(hira, i, 1); + if (!found) { + kata += chr; + } } return kata; } @@ -198,28 +187,30 @@ std::string util::keypad_to_string(const fcitx::KeyEvent &key) { return raw; } -void util::launch_program(std::string command) { - if (command.empty()) +void util::launch_program(std::string_view command) { + if (command.empty()) { return; + } /* split string */ auto array = fcitx::stringutils::split(command, FCITX_WHITESPACE); - if (array.size() <= 0) + if (array.size() <= 0) { return; + } fcitx::startProcess(array); } bool util::surrounding_get_safe_delta(uint from, uint to, int32_t *delta) { const int64_t kInt32AbsMax = - llabs(static_cast(std::numeric_limits::max())); + std::llabs(static_cast(std::numeric_limits::max())); const int64_t kInt32AbsMin = - llabs(static_cast(std::numeric_limits::min())); + std::llabs(static_cast(std::numeric_limits::min())); const int64_t kInt32SafeAbsMax = std::min(kInt32AbsMax, kInt32AbsMin); const int64_t diff = static_cast(from) - static_cast(to); - if (llabs(diff) > kInt32SafeAbsMax) { + if (std::llabs(diff) > kInt32SafeAbsMax) { return false; } diff --git a/src/utils.h b/src/utils.h index 62327dc..4a781a7 100644 --- a/src/utils.h +++ b/src/utils.h @@ -8,9 +8,13 @@ #ifndef _FCITX5_ANTHY_UTILS_H_ #define _FCITX5_ANTHY_UTILS_H_ +#include +#include #include +#include #include #include +#include namespace util { @@ -18,15 +22,13 @@ std::string utf8_string_substr(const std::string &s, size_t start, size_t len); bool match_key_event(const fcitx::KeyList &list, const fcitx::Key &key, fcitx::KeyStates ignore_mask = fcitx::KeyStates()); -void split_string(std::string &str, std::vector &str_list, - char *delim, int num); -std::string convert_to_wide(const std::string &str); +std::string convert_to_wide(std::string_view str); std::string convert_to_half(const std::string &str); std::string convert_to_katakana(const std::string &hira, bool half = false); bool key_is_keypad(const fcitx::Key &key); std::string keypad_to_string(const fcitx::KeyEvent &key); -void launch_program(std::string command); +void launch_program(std::string_view command); bool surrounding_get_safe_delta(unsigned int from, unsigned int to, int32_t *delta); diff --git a/test/testanthy.cpp b/test/testanthy.cpp index ef910ad..57bd858 100644 --- a/test/testanthy.cpp +++ b/test/testanthy.cpp @@ -6,19 +6,21 @@ */ #include "testdir.h" #include "testfrontend_public.h" +#include #include +#include #include -#include +#include #include #include +#include #include #include -#include using namespace fcitx; void scheduleEvent(EventDispatcher *dispatcher, Instance *instance) { - dispatcher->schedule([dispatcher, instance]() { + dispatcher->schedule([instance]() { auto *anthy = instance->addonManager().addon("anthy", true); FCITX_ASSERT(anthy); diff --git a/test/teststylefile.cpp b/test/teststylefile.cpp index f715258..b13c32f 100644 --- a/test/teststylefile.cpp +++ b/test/teststylefile.cpp @@ -5,16 +5,20 @@ */ #include "style_file.h" #include "testdir.h" +#include #include +#include +#include +#include #include int main() { StyleFile style; style.load(TESTING_SOURCE_DIR "/profile/101kana.sty"); FCITX_ASSERT(style.title() == "101英語キーボード用かな配列"); - std::vector keys; - std::string section = "KanaTable/FundamentalTable"; - FCITX_ASSERT(style.getKeyList(keys, section)); + constexpr std::string_view section = "KanaTable/FundamentalTable"; + auto keys = style.getKeyList(section); + FCITX_ASSERT(keys); std::vector>> expectedValues = { {"~", {"ろ"}}, {"1", {"ぬ"}}, {"2", {"", "ふ"}}, @@ -50,14 +54,14 @@ int main() { {"M", {"も"}}, {"?", {"・"}}, }; - FCITX_ASSERT(expectedValues.size() == keys.size()); - for (size_t i = 0; i < keys.size(); i++) { - FCITX_ASSERT(keys[i] == std::get<0>(expectedValues[i])) - << keys[i] << " " << expectedValues[i]; - std::vector values; - FCITX_ASSERT(style.getStringArray(values, section, keys[i])); - FCITX_ASSERT(values == std::get<1>(expectedValues[i])); + FCITX_ASSERT(expectedValues.size() == keys->size()); + for (size_t i = 0; i < keys->size(); i++) { + FCITX_ASSERT((*keys)[i] == std::get<0>(expectedValues[i])) + << (*keys)[i] << " " << expectedValues[i]; + auto values = style.getStringArray(section, (*keys)[i]); + FCITX_ASSERT(values); + FCITX_ASSERT(*values == std::get<1>(expectedValues[i])); } return 0; -} \ No newline at end of file +}