diff --git a/CMakeLists.txt b/CMakeLists.txt
index f792863..f1a8525 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.4.0)
-project(fcitx5-zhuyin VERSION 5.1.0)
+project(fcitx5-zhuyin VERSION 5.1.1)
find_package(ECM 1.0.0 REQUIRED)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
diff --git a/org.fcitx.Fcitx5.Addon.Zhuyin.metainfo.xml.in b/org.fcitx.Fcitx5.Addon.Zhuyin.metainfo.xml.in
index e54fc9e..cb306a4 100644
--- a/org.fcitx.Fcitx5.Addon.Zhuyin.metainfo.xml.in
+++ b/org.fcitx.Fcitx5.Addon.Zhuyin.metainfo.xml.in
@@ -14,6 +14,7 @@
https://github.com/fcitx/fcitx5-zhuyin
Fcitx
+
diff --git a/src/zhuyinbuffer.cpp b/src/zhuyinbuffer.cpp
index 089e35d..a4aba0c 100644
--- a/src/zhuyinbuffer.cpp
+++ b/src/zhuyinbuffer.cpp
@@ -15,293 +15,291 @@ namespace fcitx {
ZhuyinBuffer::ZhuyinBuffer(ZhuyinProviderInterface *provider)
: provider_(provider), context_(provider->context()),
instance_(zhuyin_alloc_instance(context_)) {
- // Put a place holder.
- sections_.emplace_back(ZhuyinSectionType::Symbol, provider_, this);
- cursor_ = sections_.begin();
+ // Put a place holder.
+ sections_.emplace_back(ZhuyinSectionType::Symbol, provider_, this);
+ cursor_ = sections_.begin();
}
void ZhuyinBuffer::moveCursorToBeginning() { cursor_ = sections_.begin(); }
void ZhuyinBuffer::moveCursorToEnd() {
- cursor_ = std::prev(sections_.end());
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- cursor_->setCursor(cursor_->size());
- }
+ cursor_ = std::prev(sections_.end());
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
+ cursor_->setCursor(cursor_->size());
+ }
}
bool ZhuyinBuffer::moveCursorLeft() {
- if (cursor_ == sections_.begin()) {
- return false;
- }
- // Move within the section.
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- if (auto prevChar = cursor_->prevChar(); prevChar > 0) {
- cursor_->setCursor(prevChar);
- return true;
- }
+ if (cursor_ == sections_.begin()) {
+ return false;
+ }
+ // Move within the section.
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
+ if (auto prevChar = cursor_->prevChar(); prevChar > 0) {
+ cursor_->setCursor(prevChar);
+ return true;
}
+ }
- // Move across the section.
- cursor_ = std::prev(cursor_);
- // Fix the cursor within the section.
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- cursor_->setCursor(cursor_->size());
- }
- return true;
+ // Move across the section.
+ cursor_ = std::prev(cursor_);
+ // Fix the cursor within the section.
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
+ cursor_->setCursor(cursor_->size());
+ }
+ return true;
}
bool ZhuyinBuffer::moveCursorRight() {
- if (isCursorAtTheEnd()) {
- return false;
- }
- // Move within the section.
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin &&
- cursor_->cursor() < cursor_->size()) {
- cursor_->setCursor(cursor_->nextChar());
- return true;
- }
-
- cursor_ = std::next(cursor_);
- // Fix the cursor within the section.
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- cursor_->setCursor(0);
- cursor_->setCursor(cursor_->nextChar());
- }
+ if (isCursorAtTheEnd()) {
+ return false;
+ }
+ // Move within the section.
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin &&
+ cursor_->cursor() < cursor_->size()) {
+ cursor_->setCursor(cursor_->nextChar());
return true;
+ }
+
+ cursor_ = std::next(cursor_);
+ // Fix the cursor within the section.
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
+ cursor_->setCursor(0);
+ cursor_->setCursor(cursor_->nextChar());
+ }
+ return true;
}
bool ZhuyinBuffer::isCursorAtTheEnd() const {
- return std::next(cursor_) == sections_.end() && isCursorOnEdge(cursor_);
+ return std::next(cursor_) == sections_.end() && isCursorOnEdge(cursor_);
}
bool ZhuyinBuffer::isCursorOnEdge(SectionIterator cursor) {
- return cursor->size() == cursor->cursor();
+ return cursor->size() == cursor->cursor();
}
void ZhuyinBuffer::type(uint32_t c) {
- gchar **symbols = nullptr;
- if (c <= std::numeric_limits::max() &&
- ((provider_->isZhuyin() &&
- zhuyin_in_chewing_keyboard(instance_.get(), c, &symbols)) ||
- (!provider_->isZhuyin() &&
- (charutils::islower(c) || (c >= '1' && c <= '5'))))) {
- g_strfreev(symbols);
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- cursor_->type(c);
- if (isCursorOnEdge(cursor_) && c == ' ' &&
- cursor_->parsedZhuyinLength() != cursor_->size()) {
- backspace();
- auto next = std::next(cursor_);
- cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Symbol,
- provider_, this);
- }
- } else if (isCursorOnEdge(cursor_)) {
- auto next = std::next(cursor_);
- if (c == ' ') {
- cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Symbol,
- provider_, this);
- } else if (next == sections_.end() ||
- next->sectionType() != ZhuyinSectionType::Zhuyin) {
- cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Zhuyin,
- provider_, this);
- } else {
- next->setCursor(0);
- next->type(c);
- cursor_ = next;
- }
- }
- } else {
- if (isCursorOnEdge(cursor_)) {
- cursor_ =
- sections_.emplace(std::next(cursor_), c,
+ gchar **symbols = nullptr;
+ if (c <= std::numeric_limits::max() &&
+ ((provider_->isZhuyin() &&
+ zhuyin_in_chewing_keyboard(instance_.get(), c, &symbols)) ||
+ (!provider_->isZhuyin() &&
+ (charutils::islower(c) || (c >= '1' && c <= '5'))))) {
+ g_strfreev(symbols);
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
+ cursor_->type(c);
+ if (isCursorOnEdge(cursor_) && c == ' ' &&
+ cursor_->parsedZhuyinLength() != cursor_->size()) {
+ backspace();
+ auto next = std::next(cursor_);
+ cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Symbol,
+ provider_, this);
+ }
+ } else if (isCursorOnEdge(cursor_)) {
+ auto next = std::next(cursor_);
+ if (c == ' ') {
+ cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Symbol,
+ provider_, this);
+ } else if (next == sections_.end() ||
+ next->sectionType() != ZhuyinSectionType::Zhuyin) {
+ cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Zhuyin,
+ provider_, this);
+ } else {
+ next->setCursor(0);
+ next->type(c);
+ cursor_ = next;
+ }
+ }
+ } else {
+ if (isCursorOnEdge(cursor_)) {
+ cursor_ = sections_.emplace(std::next(cursor_), c,
ZhuyinSectionType::Symbol, provider_, this);
- } else {
- assert((cursor_)->sectionType() == ZhuyinSectionType::Zhuyin);
- assert(cursor_->cursor() != 0);
+ } else {
+ assert((cursor_)->sectionType() == ZhuyinSectionType::Zhuyin);
+ assert(cursor_->cursor() != 0);
- auto next = std::next(cursor_);
- auto offset = cursor_->cursorByChar();
- auto subText = cursor_->userInput().substr(offset);
+ auto next = std::next(cursor_);
+ auto offset = cursor_->cursorByChar();
+ auto subText = cursor_->userInput().substr(offset);
- cursor_->erase(offset, cursor_->size());
+ cursor_->erase(offset, cursor_->size());
- // Add new symbol.
- cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Symbol,
- provider_, this);
- // Add split section.
- auto subZhuyin = sections_.emplace(next, ZhuyinSectionType::Zhuyin,
- provider_, this);
- subZhuyin->type(subText);
- }
+ // Add new symbol.
+ cursor_ = sections_.emplace(next, c, ZhuyinSectionType::Symbol, provider_,
+ this);
+ // Add split section.
+ auto subZhuyin =
+ sections_.emplace(next, ZhuyinSectionType::Zhuyin, provider_, this);
+ subZhuyin->type(subText);
}
+ }
}
void ZhuyinBuffer::backspace() {
- if (cursor_ == sections_.begin()) {
- return;
+ if (cursor_ == sections_.begin()) {
+ return;
+ }
+
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
+ assert(cursor_->cursor() != 0);
+ auto prevChar = cursor_->prevChar();
+ cursor_->erase(prevChar, cursor_->cursor());
+ // Remove this section.
+ if (cursor_->empty()) {
+ auto newCursor = std::prev(cursor_);
+ sections_.erase(cursor_);
+ cursor_ = newCursor;
+ } else if (cursor_->cursor() == 0) {
+ cursor_ = std::prev(cursor_);
+ } else {
+ return;
}
+ // Fix the cursor within the section.
if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- assert(cursor_->cursor() != 0);
- auto prevChar = cursor_->prevChar();
- cursor_->erase(prevChar, cursor_->cursor());
- // Remove this section.
- if (cursor_->empty()) {
- auto newCursor = std::prev(cursor_);
- sections_.erase(cursor_);
- cursor_ = newCursor;
- } else if (cursor_->cursor() == 0) {
- cursor_ = std::prev(cursor_);
- } else {
- return;
- }
-
- // Fix the cursor within the section.
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- cursor_->setCursor(cursor_->size());
- }
- return;
+ cursor_->setCursor(cursor_->size());
}
+ return;
+ }
- auto newCursor = std::prev(cursor_);
- sections_.erase(cursor_);
- cursor_ = newCursor;
- if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
- cursor_->setCursor(cursor_->size());
- auto next = std::next(cursor_);
- if (next != sections_.end() &&
- next->sectionType() == ZhuyinSectionType::Zhuyin) {
- // Merge cursor_ and next.
- auto currentSize = cursor_->size();
- cursor_->type(next->userInput());
- cursor_->setCursor(currentSize);
- sections_.erase(next);
- }
+ auto newCursor = std::prev(cursor_);
+ sections_.erase(cursor_);
+ cursor_ = newCursor;
+ if (cursor_->sectionType() == ZhuyinSectionType::Zhuyin) {
+ cursor_->setCursor(cursor_->size());
+ auto next = std::next(cursor_);
+ if (next != sections_.end() &&
+ next->sectionType() == ZhuyinSectionType::Zhuyin) {
+ // Merge cursor_ and next.
+ auto currentSize = cursor_->size();
+ cursor_->type(next->userInput());
+ cursor_->setCursor(currentSize);
+ sections_.erase(next);
}
+ }
}
void ZhuyinBuffer::del() {
- if (moveCursorRight()) {
- backspace();
- }
+ if (moveCursorRight()) {
+ backspace();
+ }
}
Text ZhuyinBuffer::preedit() const {
- Text text;
- text.setCursor(0);
- for (auto iter = std::next(sections_.begin()), end = sections_.end();
- iter != end; ++iter) {
- auto [preedit, cursor] = iter->preeditWithCursor();
- if (cursor_ == iter) {
- text.setCursor(text.textLength() + cursor);
- }
- text.append(preedit, TextFormatFlag::Underline);
+ Text text;
+ text.setCursor(0);
+ for (auto iter = std::next(sections_.begin()), end = sections_.end();
+ iter != end; ++iter) {
+ auto [preedit, cursor] = iter->preeditWithCursor();
+ if (cursor_ == iter) {
+ text.setCursor(text.textLength() + cursor);
}
- return text;
+ text.append(preedit, TextFormatFlag::Underline);
+ }
+ return text;
}
std::string ZhuyinBuffer::rawText() const {
- std::string result;
- for (auto iter = std::next(sections_.begin()), end = sections_.end();
- iter != end; ++iter) {
- result.append(iter->userInput());
- }
- return result;
+ std::string result;
+ for (auto iter = std::next(sections_.begin()), end = sections_.end();
+ iter != end; ++iter) {
+ result.append(iter->userInput());
+ }
+ return result;
}
void ZhuyinBuffer::learn() {
- for (auto iter = std::next(sections_.begin()), end = sections_.end();
- iter != end; ++iter) {
- iter->learn();
- }
+ for (auto iter = std::next(sections_.begin()), end = sections_.end();
+ iter != end; ++iter) {
+ iter->learn();
+ }
}
void ZhuyinBuffer::reset() {
- sections_.erase(std::next(sections_.begin()), sections_.end());
- cursor_ = sections_.begin();
+ sections_.erase(std::next(sections_.begin()), sections_.end());
+ cursor_ = sections_.begin();
}
void ZhuyinBuffer::showCandidate(
const std::function)> &callback) {
- auto callbackWrapper =
- [this, &callback](std::unique_ptr candidate) {
- if (candidate->isZhuyin()) {
- auto *zhuyinCandidate =
- static_cast(candidate.get());
- zhuyinCandidate->connect(
- [this](SectionIterator iter) {
- cursor_ = iter;
- if (cursor_->cursor() == 0 &&
- cursor_ != sections_.begin()) {
- cursor_ = std::prev(cursor_);
- cursor_->setCursor(cursor_->size());
- }
- });
- }
- callback(std::move(candidate));
- };
- if (isCursorAtTheEnd()) {
- cursor_->showCandidate(callbackWrapper, cursor_, cursor_->prevChar());
- } else if (isCursorOnEdge(cursor_)) {
- auto section = std::next(cursor_);
- section->showCandidate(callbackWrapper, section, 0);
- } else {
- cursor_->showCandidate(callbackWrapper, cursor_, cursor_->cursor());
- }
+ auto callbackWrapper =
+ [this, &callback](std::unique_ptr candidate) {
+ if (candidate->isZhuyin()) {
+ auto *zhuyinCandidate =
+ static_cast(candidate.get());
+ zhuyinCandidate->connect(
+ [this](SectionIterator iter) {
+ cursor_ = iter;
+ if (cursor_->cursor() == 0 && cursor_ != sections_.begin()) {
+ cursor_ = std::prev(cursor_);
+ cursor_->setCursor(cursor_->size());
+ }
+ });
+ }
+ callback(std::move(candidate));
+ };
+ if (isCursorAtTheEnd()) {
+ cursor_->showCandidate(callbackWrapper, cursor_, cursor_->prevChar());
+ } else if (isCursorOnEdge(cursor_)) {
+ auto section = std::next(cursor_);
+ section->showCandidate(callbackWrapper, section, 0);
+ } else {
+ cursor_->showCandidate(callbackWrapper, cursor_, cursor_->cursor());
+ }
}
void ZhuyinBuffer::setZhuyinSymbolTo(SectionIterator iter, size_t offset,
std::string symbol) {
- assert(iter->sectionType() == ZhuyinSectionType::Zhuyin);
- if (offset >= iter->size()) {
- return;
- }
- auto next = std::next(iter);
- auto beforeSize = offset;
- auto chr = iter->charAt(offset);
- auto after = iter->userInput().substr(offset + 1);
- if (beforeSize == 0) {
- sections_.erase(iter);
- } else {
- iter->erase(offset, iter->size());
- }
- auto newSymbol = sections_.emplace(next, chr, ZhuyinSectionType::Symbol,
- provider_, this);
- newSymbol->setSymbol(std::move(symbol));
- if (!after.empty()) {
- auto newSection =
- sections_.emplace(next, ZhuyinSectionType::Zhuyin, provider_, this);
- newSection->type(after);
- }
- cursor_ = newSymbol;
+ assert(iter->sectionType() == ZhuyinSectionType::Zhuyin);
+ if (offset >= iter->size()) {
+ return;
+ }
+ auto next = std::next(iter);
+ auto beforeSize = offset;
+ auto chr = iter->charAt(offset);
+ auto after = iter->userInput().substr(offset + 1);
+ if (beforeSize == 0) {
+ sections_.erase(iter);
+ } else {
+ iter->erase(offset, iter->size());
+ }
+ auto newSymbol =
+ sections_.emplace(next, chr, ZhuyinSectionType::Symbol, provider_, this);
+ newSymbol->setSymbol(std::move(symbol));
+ if (!after.empty()) {
+ auto newSection =
+ sections_.emplace(next, ZhuyinSectionType::Zhuyin, provider_, this);
+ newSection->type(after);
+ }
+ cursor_ = newSymbol;
}
std::string ZhuyinBuffer::dump() const {
- bool first = true;
- std::stringstream sstream;
- sstream << "ZhuyinBuffer(";
- for (const auto §ion : sections_) {
- if (first) {
- first = false;
- continue;
- }
- sstream << "";
+ bool first = true;
+ std::stringstream sstream;
+ sstream << "ZhuyinBuffer(";
+ for (const auto §ion : sections_) {
+ if (first) {
+ first = false;
+ continue;
+ }
+ sstream << "";
+ }
+ auto preeditText = preedit();
+ sstream << "Preedit:" << preeditText.toString() << "," << preeditText.cursor()
+ << ")";
- return sstream.str();
+ return sstream.str();
}
} // namespace fcitx
diff --git a/src/zhuyinbuffer.h b/src/zhuyinbuffer.h
index a64437a..e480043 100644
--- a/src/zhuyinbuffer.h
+++ b/src/zhuyinbuffer.h
@@ -23,9 +23,9 @@ class ZhuyinSection;
// Helper class to separate the data needed from engine.
class ZhuyinProviderInterface {
public:
- virtual zhuyin_context_t *context() = 0;
- virtual bool isZhuyin() const = 0;
- virtual const ZhuyinSymbol &symbol() const = 0;
+ virtual zhuyin_context_t *context() = 0;
+ virtual bool isZhuyin() const = 0;
+ virtual const ZhuyinSymbol &symbol() const = 0;
};
// Class that manages a list of ZhuyinSection.
@@ -34,45 +34,45 @@ class ZhuyinProviderInterface {
// to simplify the code need to handle the section logic.
class ZhuyinBuffer {
public:
- ZhuyinBuffer(ZhuyinProviderInterface *provider);
- // Type a single character into the buffer.
- void type(uint32_t c);
- bool empty() const { return sections_.size() == 1; }
- // Clear the buffer.
- void reset();
+ ZhuyinBuffer(ZhuyinProviderInterface *provider);
+ // Type a single character into the buffer.
+ void type(uint32_t c);
+ bool empty() const { return sections_.size() == 1; }
+ // Clear the buffer.
+ void reset();
- std::string text() const { return preedit().toStringForCommit(); }
- std::string rawText() const;
- bool isCursorAtTheEnd() const;
+ std::string text() const { return preedit().toStringForCommit(); }
+ std::string rawText() const;
+ bool isCursorAtTheEnd() const;
- Text preedit() const;
+ Text preedit() const;
- bool moveCursorLeft();
- bool moveCursorRight();
- void moveCursorToBeginning();
- void moveCursorToEnd();
- void del();
- void backspace();
- void learn();
+ bool moveCursorLeft();
+ bool moveCursorRight();
+ void moveCursorToBeginning();
+ void moveCursorToEnd();
+ void del();
+ void backspace();
+ void learn();
- void showCandidate(
- const std::function)> &callback);
- void setZhuyinSymbolTo(SectionIterator iter, size_t offset,
- std::string symbol);
+ void showCandidate(
+ const std::function)> &callback);
+ void setZhuyinSymbolTo(SectionIterator iter, size_t offset,
+ std::string symbol);
- std::string dump() const;
+ std::string dump() const;
- auto instance() const { return instance_.get(); }
+ auto instance() const { return instance_.get(); }
private:
- static bool isCursorOnEdge(SectionIterator cursor);
+ static bool isCursorOnEdge(SectionIterator cursor);
- ZhuyinProviderInterface *provider_;
- zhuyin_context_t *context_;
- // Dummy instance for query.
- UniqueCPtr instance_;
- SectionIterator cursor_;
- std::list sections_;
+ ZhuyinProviderInterface *provider_;
+ zhuyin_context_t *context_;
+ // Dummy instance for query.
+ UniqueCPtr instance_;
+ SectionIterator cursor_;
+ std::list sections_;
};
} // namespace fcitx
diff --git a/src/zhuyincandidate.cpp b/src/zhuyincandidate.cpp
index 5adf9e7..4cd18fd 100644
--- a/src/zhuyincandidate.cpp
+++ b/src/zhuyincandidate.cpp
@@ -13,41 +13,41 @@ ZhuyinSectionCandidate::ZhuyinSectionCandidate(SectionIterator section,
unsigned int i)
: section_(section), index_(i) {
- lookup_candidate_t *candidate = NULL;
- if (!zhuyin_get_candidate(section->instance(), i, &candidate)) {
- throw std::runtime_error("Failed to get candidate");
- }
-
- const gchar *word = NULL;
- if (!zhuyin_get_candidate_string(section->instance(), candidate, &word)) {
- throw std::runtime_error("Failed to get string");
- }
- setText(Text(word));
+ lookup_candidate_t *candidate = NULL;
+ if (!zhuyin_get_candidate(section->instance(), i, &candidate)) {
+ throw std::runtime_error("Failed to get candidate");
+ }
+
+ const gchar *word = NULL;
+ if (!zhuyin_get_candidate_string(section->instance(), candidate, &word)) {
+ throw std::runtime_error("Failed to get string");
+ }
+ setText(Text(word));
}
void ZhuyinSectionCandidate::select(InputContext *) const {
- lookup_candidate_t *candidate = NULL;
- if (!zhuyin_get_candidate(section_->instance(), index_, &candidate)) {
- return;
- }
- auto newOffset = zhuyin_choose_candidate(section_->instance(),
- section_->prevChar(), candidate);
- zhuyin_guess_sentence(section_->instance());
- section_->setCursor(newOffset);
- emit(section_);
- emit();
+ lookup_candidate_t *candidate = NULL;
+ if (!zhuyin_get_candidate(section_->instance(), index_, &candidate)) {
+ return;
+ }
+ auto newOffset = zhuyin_choose_candidate(section_->instance(),
+ section_->prevChar(), candidate);
+ zhuyin_guess_sentence(section_->instance());
+ section_->setCursor(newOffset);
+ emit(section_);
+ emit();
}
SymbolSectionCandidate::SymbolSectionCandidate(SectionIterator section,
std::string symbol)
: section_(section), symbol_(std::move(symbol)) {
- setText(Text(symbol_));
+ setText(Text(symbol_));
}
void SymbolSectionCandidate::select(InputContext *) const {
- section_->setSymbol(symbol_);
- emit();
+ section_->setSymbol(symbol_);
+ emit();
}
SymbolZhuyinSectionCandidate::SymbolZhuyinSectionCandidate(
@@ -56,8 +56,8 @@ SymbolZhuyinSectionCandidate::SymbolZhuyinSectionCandidate(
: SymbolSectionCandidate(section, std::move(symbol)), offset_(offset) {}
void SymbolZhuyinSectionCandidate::select(InputContext *) const {
- section_->buffer()->setZhuyinSymbolTo(section_, offset_, symbol_);
- emit();
+ section_->buffer()->setZhuyinSymbolTo(section_, offset_, symbol_);
+ emit();
}
} // namespace fcitx
diff --git a/src/zhuyincandidate.h b/src/zhuyincandidate.h
index a3cbedf..451b57f 100644
--- a/src/zhuyincandidate.h
+++ b/src/zhuyincandidate.h
@@ -16,49 +16,48 @@ namespace fcitx {
// Base class for Zhuyin candidate.
class ZhuyinCandidate : public CandidateWord, public ConnectableObject {
public:
- virtual bool isZhuyin() const { return false; };
- FCITX_DECLARE_SIGNAL(ZhuyinCandidate, selected, void());
+ virtual bool isZhuyin() const { return false; };
+ FCITX_DECLARE_SIGNAL(ZhuyinCandidate, selected, void());
private:
- FCITX_DEFINE_SIGNAL(ZhuyinCandidate, selected);
+ FCITX_DEFINE_SIGNAL(ZhuyinCandidate, selected);
};
// Candidate for zhuyin section.
class ZhuyinSectionCandidate : public ZhuyinCandidate {
public:
- ZhuyinSectionCandidate(SectionIterator section, unsigned int i);
- bool isZhuyin() const override { return true; }
- void select(InputContext *) const override;
- FCITX_DECLARE_SIGNAL(ZhuyinSectionCandidate, selected,
- void(SectionIterator));
+ ZhuyinSectionCandidate(SectionIterator section, unsigned int i);
+ bool isZhuyin() const override { return true; }
+ void select(InputContext *) const override;
+ FCITX_DECLARE_SIGNAL(ZhuyinSectionCandidate, selected, void(SectionIterator));
private:
- FCITX_DEFINE_SIGNAL(ZhuyinSectionCandidate, selected);
- SectionIterator section_;
- unsigned int index_;
+ FCITX_DEFINE_SIGNAL(ZhuyinSectionCandidate, selected);
+ SectionIterator section_;
+ unsigned int index_;
};
// Candidate for symbol section.
class SymbolSectionCandidate : public ZhuyinCandidate {
public:
- SymbolSectionCandidate(SectionIterator section, std::string symbol);
- void select(InputContext *) const override;
+ SymbolSectionCandidate(SectionIterator section, std::string symbol);
+ void select(InputContext *) const override;
protected:
- FCITX_DEFINE_SIGNAL(ZhuyinSectionCandidate, selected);
- SectionIterator section_;
- std::string symbol_;
+ FCITX_DEFINE_SIGNAL(ZhuyinSectionCandidate, selected);
+ SectionIterator section_;
+ std::string symbol_;
};
// Candidate for symbol section.
class SymbolZhuyinSectionCandidate : public SymbolSectionCandidate {
public:
- SymbolZhuyinSectionCandidate(SectionIterator section, std::string symbol,
- size_t offset);
- void select(InputContext *) const override;
+ SymbolZhuyinSectionCandidate(SectionIterator section, std::string symbol,
+ size_t offset);
+ void select(InputContext *) const override;
private:
- size_t offset_;
+ size_t offset_;
};
} // namespace fcitx
diff --git a/src/zhuyinengine.cpp b/src/zhuyinengine.cpp
index b061258..454200d 100644
--- a/src/zhuyinengine.cpp
+++ b/src/zhuyinengine.cpp
@@ -29,496 +29,488 @@ ZhuyinState::ZhuyinState(ZhuyinEngine *engine, InputContext *ic)
: engine_(engine), buffer_(engine), ic_(ic) {}
void ZhuyinState::reset() {
- buffer_.reset();
- updateUI();
+ buffer_.reset();
+ updateUI();
}
void ZhuyinState::commit() {
- ic_->commitString(buffer_.text());
- buffer_.learn();
- reset();
+ ic_->commitString(buffer_.text());
+ buffer_.learn();
+ reset();
}
void ZhuyinState::keyEvent(KeyEvent &keyEvent) {
- auto *ic = keyEvent.inputContext();
- auto key = keyEvent.key();
- if (keyEvent.isRelease()) {
- return;
+ auto *ic = keyEvent.inputContext();
+ auto key = keyEvent.key();
+ if (keyEvent.isRelease()) {
+ return;
+ }
+
+ if (auto candidateList = ic->inputPanel().candidateList();
+ candidateList && candidateList->size()) {
+ auto idx = key.keyListIndex(engine_->selectionKeys());
+ if (idx >= 0) {
+ candidateList->candidate(idx).select(ic);
+ return keyEvent.filterAndAccept();
}
- if (auto candidateList = ic->inputPanel().candidateList();
- candidateList && candidateList->size()) {
- auto idx = key.keyListIndex(engine_->selectionKeys());
- if (idx >= 0) {
- candidateList->candidate(idx).select(ic);
- return keyEvent.filterAndAccept();
- }
-
- if (candidateList->cursorIndex() >= 0 &&
- (key.check(FcitxKey_space) || key.check(FcitxKey_Return))) {
- candidateList->candidate(candidateList->cursorIndex()).select(ic);
- return keyEvent.filterAndAccept();
- }
-
- if (key.checkKeyList(*engine_->config().prevPage)) {
- candidateList->toPageable()->prev();
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
- return keyEvent.filterAndAccept();
- }
-
- if (key.checkKeyList(*engine_->config().nextPage)) {
- candidateList->toPageable()->next();
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
- return keyEvent.filterAndAccept();
- }
-
- if (key.checkKeyList(*engine_->config().prevCandidate)) {
- candidateList->toCursorMovable()->prevCandidate();
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
- return keyEvent.filterAndAccept();
- }
-
- if (key.checkKeyList(*engine_->config().nextCandidate)) {
- candidateList->toCursorMovable()->nextCandidate();
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
- return keyEvent.filterAndAccept();
- }
-
- if (key.check(FcitxKey_Escape)) {
- ic->inputPanel().setCandidateList(nullptr);
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_Home)) {
- candidateList->toPageable()->setPage(0);
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_End)) {
- candidateList->toPageable()->setPage(
- candidateList->toPageable()->totalPages() - 1);
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
- return keyEvent.filterAndAccept();
- }
-
- return keyEvent.filterAndAccept();
+ if (candidateList->cursorIndex() >= 0 &&
+ (key.check(FcitxKey_space) || key.check(FcitxKey_Return))) {
+ candidateList->candidate(candidateList->cursorIndex()).select(ic);
+ return keyEvent.filterAndAccept();
}
- if (!buffer_.empty()) {
- if (key.check(FcitxKey_Home)) {
- buffer_.moveCursorToBeginning();
- updateUI();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_End)) {
- buffer_.moveCursorToEnd();
- updateUI();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_Escape)) {
- reset();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_BackSpace)) {
- buffer_.backspace();
- updateUI();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_Delete)) {
- buffer_.del();
- updateUI();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_Return)) {
- commit();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_Left)) {
- buffer_.moveCursorLeft();
- updateUI();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_Right)) {
- buffer_.moveCursorRight();
- updateUI();
- return keyEvent.filterAndAccept();
- }
- if (key.check(FcitxKey_Return, KeyState::Shift)) {
- ic->commitString(buffer_.rawText());
- reset();
- return keyEvent.filterAndAccept();
- }
-
- if (key.check(FcitxKey_Down)) {
- updateUI(true);
- }
-
- if (key.isCursorMove()) {
- return keyEvent.filterAndAccept();
- }
+ if (key.checkKeyList(*engine_->config().prevPage)) {
+ candidateList->toPageable()->prev();
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ return keyEvent.filterAndAccept();
}
- auto c = Key::keySymToUnicode(key.sym());
- if (buffer_.empty()) {
- if (key.check(*engine_->config().quickphraseKey) &&
- engine_->quickphrase()) {
- std::string keyString;
- std::string output, altOutput;
- if (c) {
- keyString = utf8::UCS4ToUTF8(c);
- altOutput = keyString;
- } else {
- keyString = engine_->config().quickphraseKey->toString(
- KeyStringFormat::Localized);
- }
- output = *engine_->config().quickphraseKeySymbol;
- if (output.empty()) {
- output = altOutput;
- altOutput.clear();
- }
-
- if (!output.empty() && !altOutput.empty()) {
- std::string text =
- fmt::format(_("Press {} for {} and Return for {}"),
- keyString, output, altOutput);
- engine_->quickphrase()->call(
- ic, text, "", output, altOutput,
- *engine_->config().quickphraseKey);
- } else if (!output.empty()) {
- std::string text =
- fmt::format(_("Press {} for {}"), keyString, output);
- engine_->quickphrase()->call(
- ic, text, "", output, altOutput,
- *engine_->config().quickphraseKey);
- } else {
- engine_->quickphrase()->call(
- ic, "", "", "", "", Key());
- }
-
- keyEvent.filterAndAccept();
- return;
- }
+ if (key.checkKeyList(*engine_->config().nextPage)) {
+ candidateList->toPageable()->next();
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ return keyEvent.filterAndAccept();
}
- if (key.hasModifier()) {
- return;
+ if (key.checkKeyList(*engine_->config().prevCandidate)) {
+ candidateList->toCursorMovable()->prevCandidate();
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ return keyEvent.filterAndAccept();
}
- if (c <= std::numeric_limits::max() &&
- !charutils::isprint(c)) {
- if (!buffer_.empty()) {
- keyEvent.filterAndAccept();
- }
- return;
+ if (key.checkKeyList(*engine_->config().nextCandidate)) {
+ candidateList->toCursorMovable()->nextCandidate();
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ return keyEvent.filterAndAccept();
}
- if (c) {
- buffer_.type(c);
- if (utf8::length(buffer_.preedit().toStringForCommit()) >
- MAX_INPUT_LENGTH) {
- ic->commitString(buffer_.text());
- buffer_.learn();
- reset();
- } else {
- updateUI();
- }
- keyEvent.filterAndAccept();
+ if (key.check(FcitxKey_Escape)) {
+ ic->inputPanel().setCandidateList(nullptr);
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_Home)) {
+ candidateList->toPageable()->setPage(0);
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_End)) {
+ candidateList->toPageable()->setPage(
+ candidateList->toPageable()->totalPages() - 1);
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ return keyEvent.filterAndAccept();
}
-}
-void ZhuyinState::updateUI(bool showCandidate) {
- ic_->inputPanel().reset();
- Text preedit(buffer_.preedit());
- if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) {
- ic_->inputPanel().setClientPreedit(preedit);
- ic_->updatePreedit();
+ return keyEvent.filterAndAccept();
+ }
+
+ if (!buffer_.empty()) {
+ if (key.check(FcitxKey_Home)) {
+ buffer_.moveCursorToBeginning();
+ updateUI();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_End)) {
+ buffer_.moveCursorToEnd();
+ updateUI();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_Escape)) {
+ reset();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_BackSpace)) {
+ buffer_.backspace();
+ updateUI();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_Delete)) {
+ buffer_.del();
+ updateUI();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_Return)) {
+ commit();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_Left)) {
+ buffer_.moveCursorLeft();
+ updateUI();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_Right)) {
+ buffer_.moveCursorRight();
+ updateUI();
+ return keyEvent.filterAndAccept();
+ }
+ if (key.check(FcitxKey_Return, KeyState::Shift)) {
+ ic->commitString(buffer_.rawText());
+ reset();
+ return keyEvent.filterAndAccept();
+ }
+
+ if (key.check(FcitxKey_Down)) {
+ updateUI(true);
+ }
+
+ if (key.isCursorMove()) {
+ return keyEvent.filterAndAccept();
+ }
+ }
+
+ auto c = Key::keySymToUnicode(key.sym());
+ if (buffer_.empty()) {
+ if (key.check(*engine_->config().quickphraseKey) &&
+ engine_->quickphrase()) {
+ std::string keyString;
+ std::string output, altOutput;
+ if (c) {
+ keyString = utf8::UCS4ToUTF8(c);
+ altOutput = keyString;
+ } else {
+ keyString = engine_->config().quickphraseKey->toString(
+ KeyStringFormat::Localized);
+ }
+ output = *engine_->config().quickphraseKeySymbol;
+ if (output.empty()) {
+ output = altOutput;
+ altOutput.clear();
+ }
+
+ if (!output.empty() && !altOutput.empty()) {
+ std::string text = fmt::format(_("Press {} for {} and Return for {}"),
+ keyString, output, altOutput);
+ engine_->quickphrase()->call(
+ ic, text, "", output, altOutput, *engine_->config().quickphraseKey);
+ } else if (!output.empty()) {
+ std::string text = fmt::format(_("Press {} for {}"), keyString, output);
+ engine_->quickphrase()->call(
+ ic, text, "", output, altOutput, *engine_->config().quickphraseKey);
+ } else {
+ engine_->quickphrase()->call(ic, "", "", "", "",
+ Key());
+ }
+
+ keyEvent.filterAndAccept();
+ return;
+ }
+ }
+
+ if (key.hasModifier()) {
+ return;
+ }
+
+ if (c <= std::numeric_limits::max() && !charutils::isprint(c)) {
+ if (!buffer_.empty()) {
+ keyEvent.filterAndAccept();
+ }
+ return;
+ }
+
+ if (c) {
+ buffer_.type(c);
+ if (utf8::length(buffer_.preedit().toStringForCommit()) >
+ MAX_INPUT_LENGTH) {
+ ic->commitString(buffer_.text());
+ buffer_.learn();
+ reset();
} else {
- ic_->inputPanel().setPreedit(preedit);
+ updateUI();
}
+ keyEvent.filterAndAccept();
+ }
+}
- if (showCandidate) {
- auto candidateList = std::make_unique();
- candidateList->setCursorPositionAfterPaging(
- CursorPositionAfterPaging::SameAsLast);
- candidateList->setLayoutHint(CandidateLayoutHint::Vertical);
- candidateList->setPageSize(*engine_->config().pageSize);
- candidateList->setSelectionKey(engine_->selectionKeys());
- buffer_.showCandidate(
- [this, &candidateList](std::unique_ptr candidate) {
- candidate->connect(
- [this]() { updateUI(); });
- candidateList->append(std::move(candidate));
- });
- if (candidateList->size()) {
- candidateList->setGlobalCursorIndex(0);
- ic_->inputPanel().setCandidateList(std::move(candidateList));
- }
+void ZhuyinState::updateUI(bool showCandidate) {
+ ic_->inputPanel().reset();
+ Text preedit(buffer_.preedit());
+ if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) {
+ ic_->inputPanel().setClientPreedit(preedit);
+ ic_->updatePreedit();
+ } else {
+ ic_->inputPanel().setPreedit(preedit);
+ }
+
+ if (showCandidate) {
+ auto candidateList = std::make_unique();
+ candidateList->setCursorPositionAfterPaging(
+ CursorPositionAfterPaging::SameAsLast);
+ candidateList->setLayoutHint(CandidateLayoutHint::Vertical);
+ candidateList->setPageSize(*engine_->config().pageSize);
+ candidateList->setSelectionKey(engine_->selectionKeys());
+ buffer_.showCandidate([this, &candidateList](
+ std::unique_ptr candidate) {
+ candidate->connect([this]() { updateUI(); });
+ candidateList->append(std::move(candidate));
+ });
+ if (candidateList->size()) {
+ candidateList->setGlobalCursorIndex(0);
+ ic_->inputPanel().setCandidateList(std::move(candidateList));
}
+ }
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
}
ZhuyinEngine::ZhuyinEngine(Instance *instance)
: instance_(instance), factory_([this](InputContext &ic) {
- return new ZhuyinState(this, &ic);
+ return new ZhuyinState(this, &ic);
}) {
- auto userDir = stringutils::joinPath(
- StandardPath::global().userDirectory(StandardPath::Type::PkgData),
- "zhuyin");
- if (!fs::makePath(userDir)) {
- if (fs::isdir(userDir)) {
- ZHUYIN_DEBUG() << "Failed to create user directory: " << userDir;
- }
+ auto userDir = stringutils::joinPath(
+ StandardPath::global().userDirectory(StandardPath::Type::PkgData),
+ "zhuyin");
+ if (!fs::makePath(userDir)) {
+ if (fs::isdir(userDir)) {
+ ZHUYIN_DEBUG() << "Failed to create user directory: " << userDir;
}
- context_.reset(
- zhuyin_init(StandardPath::fcitxPath("pkgdatadir", "zhuyin").data(),
- userDir.data()));
+ }
+ context_.reset(zhuyin_init(
+ StandardPath::fcitxPath("pkgdatadir", "zhuyin").data(), userDir.data()));
- instance->inputContextManager().registerProperty("zhuyinState", &factory_);
- reloadConfig();
+ instance->inputContextManager().registerProperty("zhuyinState", &factory_);
+ reloadConfig();
}
void ZhuyinEngine::activate(const InputMethodEntry &,
InputContextEvent &event) {
- auto *inputContext = event.inputContext();
- // Request full width.
- fullwidth();
- chttrans();
- for (const auto *actionName : {"chttrans", "fullwidth"}) {
- if (auto *action =
- instance_->userInterfaceManager().lookupAction(actionName)) {
- inputContext->statusArea().addAction(StatusGroup::InputMethod,
- action);
- }
+ auto *inputContext = event.inputContext();
+ // Request full width.
+ fullwidth();
+ chttrans();
+ for (const auto *actionName : {"chttrans", "fullwidth"}) {
+ if (auto *action =
+ instance_->userInterfaceManager().lookupAction(actionName)) {
+ inputContext->statusArea().addAction(StatusGroup::InputMethod, action);
}
+ }
}
void ZhuyinEngine::deactivate(const InputMethodEntry &entry,
InputContextEvent &event) {
- auto *inputContext = event.inputContext();
- if (event.type() == EventType::InputContextSwitchInputMethod) {
- if (*config_.commitOnSwitch) {
- auto *state = event.inputContext()->propertyFor(&factory_);
- state->commit();
- }
+ auto *inputContext = event.inputContext();
+ if (event.type() == EventType::InputContextSwitchInputMethod) {
+ if (*config_.commitOnSwitch) {
+ auto *state = event.inputContext()->propertyFor(&factory_);
+ state->commit();
}
- reset(entry, event);
+ }
+ reset(entry, event);
}
void ZhuyinEngine::keyEvent(const InputMethodEntry &, KeyEvent &keyEvent) {
- auto *state = keyEvent.inputContext()->propertyFor(&factory_);
- state->keyEvent(keyEvent);
+ auto *state = keyEvent.inputContext()->propertyFor(&factory_);
+ state->keyEvent(keyEvent);
}
void ZhuyinEngine::reset(const InputMethodEntry &, InputContextEvent &event) {
- auto *state = event.inputContext()->propertyFor(&factory_);
- state->reset();
+ auto *state = event.inputContext()->propertyFor(&factory_);
+ state->reset();
}
void ZhuyinEngine::save() { zhuyin_save(context_.get()); }
void ZhuyinEngine::setConfig(const RawConfig &rawConfig) {
- config_.load(rawConfig, true);
- safeSaveAsIni(config_, "conf/zhuyin.conf");
- reloadConfig();
+ config_.load(rawConfig, true);
+ safeSaveAsIni(config_, "conf/zhuyin.conf");
+ reloadConfig();
}
const Configuration *ZhuyinEngine::getConfig() const { return &config_; }
void ZhuyinEngine::reloadConfig() {
- readAsIni(config_, "conf/zhuyin.conf");
- // Keep fd live before fclose.
- StandardPathFile fd;
- UniqueFilePtr file;
- if (*config_.useEasySymbol) {
- fd = StandardPath::global().open(StandardPath::Type::PkgData,
- "zhuyin/easysymbols.txt", O_RDONLY);
- if (fd.isValid()) {
- file.reset(fdopen(fd.fd(), "r"));
- if (file) {
- fd.release();
- }
- }
- }
- symbol_.load(file.get());
-
- isZhuyin_ = true;
- ZhuyinScheme scheme = ZHUYIN_STANDARD;
- FullPinyinScheme pyScheme = FULL_PINYIN_HANYU;
- switch (*config_.layout) {
- case Scheme::Standard:
- scheme = ZHUYIN_STANDARD;
- break;
- case Scheme::Hsu:
- scheme = ZHUYIN_HSU;
- break;
- case Scheme::IBM:
- scheme = ZHUYIN_IBM;
- break;
- case Scheme::GinYieh:
- scheme = ZHUYIN_GINYIEH;
- break;
- case Scheme::Eten:
- scheme = ZHUYIN_ETEN;
- break;
- case Scheme::Eten26:
- scheme = ZHUYIN_ETEN26;
- break;
- case Scheme::Dvorak:
- scheme = ZHUYIN_STANDARD_DVORAK;
- break;
- case Scheme::HsuDvorak:
- scheme = ZHUYIN_HSU_DVORAK;
- break;
- case Scheme::DachenCP26:
- scheme = ZHUYIN_DACHEN_CP26;
- break;
- case Scheme::Hanyu:
- pyScheme = FULL_PINYIN_HANYU;
- isZhuyin_ = false;
- break;
- case Scheme::Luoma:
- pyScheme = FULL_PINYIN_LUOMA;
- isZhuyin_ = false;
- break;
- case Scheme::SecondaryZhuyin:
- pyScheme = FULL_PINYIN_SECONDARY_ZHUYIN;
- isZhuyin_ = false;
- break;
- }
- if (isZhuyin_) {
- zhuyin_set_chewing_scheme(context_.get(), scheme);
- } else {
- zhuyin_set_full_pinyin_scheme(context_.get(), pyScheme);
- }
-
- constexpr KeySym syms[][10] = {
- {
- FcitxKey_1,
- FcitxKey_2,
- FcitxKey_3,
- FcitxKey_4,
- FcitxKey_5,
- FcitxKey_6,
- FcitxKey_7,
- FcitxKey_8,
- FcitxKey_9,
- FcitxKey_0,
- },
-
- {
- FcitxKey_a,
- FcitxKey_s,
- FcitxKey_d,
- FcitxKey_f,
- FcitxKey_g,
- FcitxKey_h,
- FcitxKey_j,
- FcitxKey_k,
- FcitxKey_l,
- FcitxKey_semicolon,
- },
-
- {
- FcitxKey_a,
- FcitxKey_s,
- FcitxKey_d,
- FcitxKey_f,
- FcitxKey_z,
- FcitxKey_x,
- FcitxKey_c,
- FcitxKey_v,
- FcitxKey_8,
- FcitxKey_9,
- },
-
- {
- FcitxKey_a,
- FcitxKey_s,
- FcitxKey_d,
- FcitxKey_f,
- FcitxKey_j,
- FcitxKey_k,
- FcitxKey_l,
- FcitxKey_7,
- FcitxKey_8,
- FcitxKey_9,
- },
-
- {
- FcitxKey_1,
- FcitxKey_2,
- FcitxKey_3,
- FcitxKey_4,
- FcitxKey_q,
- FcitxKey_w,
- FcitxKey_e,
- FcitxKey_r,
- FcitxKey_a,
- FcitxKey_s,
- },
- {
- FcitxKey_d,
- FcitxKey_s,
- FcitxKey_t,
- FcitxKey_n,
- FcitxKey_a,
- FcitxKey_e,
- FcitxKey_o,
- FcitxKey_7,
- FcitxKey_8,
- FcitxKey_9,
- },
- };
-
- KeyStates states = KeyState::NoState;
-
- for (auto sym : syms[static_cast(*config_.selectionKey)]) {
- selectionKeys_.emplace_back(sym, states);
- }
-
- pinyin_option_t options = USE_TONE | ZHUYIN_CORRECT_ALL;
- if (isZhuyin_ && *config_.needTone) {
- options |= FORCE_TONE;
- }
- if (*config_.fuzzy->fuzzyCCh) {
- options |= PINYIN_AMB_C_CH;
- }
- if (*config_.fuzzy->fuzzySSh) {
- options |= PINYIN_AMB_S_SH;
+ readAsIni(config_, "conf/zhuyin.conf");
+ // Keep fd live before fclose.
+ StandardPathFile fd;
+ UniqueFilePtr file;
+ if (*config_.useEasySymbol) {
+ fd = StandardPath::global().open(StandardPath::Type::PkgData,
+ "zhuyin/easysymbols.txt", O_RDONLY);
+ if (fd.isValid()) {
+ file.reset(fdopen(fd.fd(), "r"));
+ if (file) {
+ fd.release();
+ }
}
- if (*config_.fuzzy->fuzzyZZh) {
- options |= PINYIN_AMB_Z_ZH;
- }
- if (*config_.fuzzy->fuzzyFH) {
- options |= PINYIN_AMB_F_H;
- }
- if (*config_.fuzzy->fuzzyGK) {
- options |= PINYIN_AMB_G_K;
- }
- if (*config_.fuzzy->fuzzyLN) {
- options |= PINYIN_AMB_L_N;
- }
- if (*config_.fuzzy->fuzzyLR) {
- options |= PINYIN_AMB_L_R;
- }
- if (*config_.fuzzy->fuzzyAnAng) {
- options |= PINYIN_AMB_AN_ANG;
- }
- if (*config_.fuzzy->fuzzyEnEng) {
- options |= PINYIN_AMB_EN_ENG;
- }
- if (*config_.fuzzy->fuzzyInIng) {
- options |= PINYIN_AMB_IN_ING;
- }
-
- zhuyin_set_options(context_.get(), options);
-
- instance_->inputContextManager().foreach([this](InputContext *ic) {
- auto *state = ic->propertyFor(&factory_);
- state->reset();
- return true;
- });
+ }
+ symbol_.load(file.get());
+
+ isZhuyin_ = true;
+ ZhuyinScheme scheme = ZHUYIN_STANDARD;
+ FullPinyinScheme pyScheme = FULL_PINYIN_HANYU;
+ switch (*config_.layout) {
+ case Scheme::Standard:
+ scheme = ZHUYIN_STANDARD;
+ break;
+ case Scheme::Hsu:
+ scheme = ZHUYIN_HSU;
+ break;
+ case Scheme::IBM:
+ scheme = ZHUYIN_IBM;
+ break;
+ case Scheme::GinYieh:
+ scheme = ZHUYIN_GINYIEH;
+ break;
+ case Scheme::Eten:
+ scheme = ZHUYIN_ETEN;
+ break;
+ case Scheme::Eten26:
+ scheme = ZHUYIN_ETEN26;
+ break;
+ case Scheme::Dvorak:
+ scheme = ZHUYIN_STANDARD_DVORAK;
+ break;
+ case Scheme::HsuDvorak:
+ scheme = ZHUYIN_HSU_DVORAK;
+ break;
+ case Scheme::DachenCP26:
+ scheme = ZHUYIN_DACHEN_CP26;
+ break;
+ case Scheme::Hanyu:
+ pyScheme = FULL_PINYIN_HANYU;
+ isZhuyin_ = false;
+ break;
+ case Scheme::Luoma:
+ pyScheme = FULL_PINYIN_LUOMA;
+ isZhuyin_ = false;
+ break;
+ case Scheme::SecondaryZhuyin:
+ pyScheme = FULL_PINYIN_SECONDARY_ZHUYIN;
+ isZhuyin_ = false;
+ break;
+ }
+ if (isZhuyin_) {
+ zhuyin_set_chewing_scheme(context_.get(), scheme);
+ } else {
+ zhuyin_set_full_pinyin_scheme(context_.get(), pyScheme);
+ }
+
+ constexpr KeySym syms[][10] = {
+ {
+ FcitxKey_1,
+ FcitxKey_2,
+ FcitxKey_3,
+ FcitxKey_4,
+ FcitxKey_5,
+ FcitxKey_6,
+ FcitxKey_7,
+ FcitxKey_8,
+ FcitxKey_9,
+ FcitxKey_0,
+ },
+
+ {
+ FcitxKey_a,
+ FcitxKey_s,
+ FcitxKey_d,
+ FcitxKey_f,
+ FcitxKey_g,
+ FcitxKey_h,
+ FcitxKey_j,
+ FcitxKey_k,
+ FcitxKey_l,
+ FcitxKey_semicolon,
+ },
+
+ {
+ FcitxKey_a,
+ FcitxKey_s,
+ FcitxKey_d,
+ FcitxKey_f,
+ FcitxKey_z,
+ FcitxKey_x,
+ FcitxKey_c,
+ FcitxKey_v,
+ FcitxKey_8,
+ FcitxKey_9,
+ },
+
+ {
+ FcitxKey_a,
+ FcitxKey_s,
+ FcitxKey_d,
+ FcitxKey_f,
+ FcitxKey_j,
+ FcitxKey_k,
+ FcitxKey_l,
+ FcitxKey_7,
+ FcitxKey_8,
+ FcitxKey_9,
+ },
+
+ {
+ FcitxKey_1,
+ FcitxKey_2,
+ FcitxKey_3,
+ FcitxKey_4,
+ FcitxKey_q,
+ FcitxKey_w,
+ FcitxKey_e,
+ FcitxKey_r,
+ FcitxKey_a,
+ FcitxKey_s,
+ },
+ {
+ FcitxKey_d,
+ FcitxKey_s,
+ FcitxKey_t,
+ FcitxKey_n,
+ FcitxKey_a,
+ FcitxKey_e,
+ FcitxKey_o,
+ FcitxKey_7,
+ FcitxKey_8,
+ FcitxKey_9,
+ },
+ };
+
+ KeyStates states = KeyState::NoState;
+
+ for (auto sym : syms[static_cast(*config_.selectionKey)]) {
+ selectionKeys_.emplace_back(sym, states);
+ }
+
+ pinyin_option_t options = USE_TONE | ZHUYIN_CORRECT_ALL;
+ if (isZhuyin_ && *config_.needTone) {
+ options |= FORCE_TONE;
+ }
+ if (*config_.fuzzy->fuzzyCCh) {
+ options |= PINYIN_AMB_C_CH;
+ }
+ if (*config_.fuzzy->fuzzySSh) {
+ options |= PINYIN_AMB_S_SH;
+ }
+ if (*config_.fuzzy->fuzzyZZh) {
+ options |= PINYIN_AMB_Z_ZH;
+ }
+ if (*config_.fuzzy->fuzzyFH) {
+ options |= PINYIN_AMB_F_H;
+ }
+ if (*config_.fuzzy->fuzzyGK) {
+ options |= PINYIN_AMB_G_K;
+ }
+ if (*config_.fuzzy->fuzzyLN) {
+ options |= PINYIN_AMB_L_N;
+ }
+ if (*config_.fuzzy->fuzzyLR) {
+ options |= PINYIN_AMB_L_R;
+ }
+ if (*config_.fuzzy->fuzzyAnAng) {
+ options |= PINYIN_AMB_AN_ANG;
+ }
+ if (*config_.fuzzy->fuzzyEnEng) {
+ options |= PINYIN_AMB_EN_ENG;
+ }
+ if (*config_.fuzzy->fuzzyInIng) {
+ options |= PINYIN_AMB_IN_ING;
+ }
+
+ zhuyin_set_options(context_.get(), options);
+
+ instance_->inputContextManager().foreach ([this](InputContext *ic) {
+ auto *state = ic->propertyFor(&factory_);
+ state->reset();
+ return true;
+ });
- zhuyin_load_phrase_library(context_.get(), USER_DICTIONARY);
+ zhuyin_load_phrase_library(context_.get(), USER_DICTIONARY);
}
} // namespace fcitx
diff --git a/src/zhuyinengine.h b/src/zhuyinengine.h
index b0993eb..92f8aaa 100644
--- a/src/zhuyinengine.h
+++ b/src/zhuyinengine.h
@@ -23,28 +23,28 @@
namespace fcitx {
enum class Scheme {
- Standard,
- Hsu,
- IBM,
- GinYieh,
- Eten,
- Eten26,
- Dvorak,
- HsuDvorak,
- DachenCP26,
- Hanyu,
- Luoma,
- SecondaryZhuyin
+ Standard,
+ Hsu,
+ IBM,
+ GinYieh,
+ Eten,
+ Eten26,
+ Dvorak,
+ HsuDvorak,
+ DachenCP26,
+ Hanyu,
+ Luoma,
+ SecondaryZhuyin
};
enum class SelectionKey {
- Digit,
- asdfghjkl,
- asdfzxcv89,
- asdfjkl789,
- aoeuhtn789,
- _1234qweras,
- dstnaeo789
+ Digit,
+ asdfghjkl,
+ asdfzxcv89,
+ asdfjkl789,
+ aoeuhtn789,
+ _1234qweras,
+ dstnaeo789
};
FCITX_CONFIG_ENUM_NAME(SelectionKey, "1234567890", "asdfghjkl;", "asdfzxcv89",
@@ -116,64 +116,64 @@ class ZhuyinEngine;
class ZhuyinState final : public InputContextProperty {
public:
- ZhuyinState(ZhuyinEngine *engine, InputContext *ic);
+ ZhuyinState(ZhuyinEngine *engine, InputContext *ic);
- void keyEvent(KeyEvent &keyEvent);
- void reset();
- void commit();
+ void keyEvent(KeyEvent &keyEvent);
+ void reset();
+ void commit();
- void updateUI(bool showCandidate = false);
+ void updateUI(bool showCandidate = false);
private:
- ZhuyinEngine *engine_;
- ZhuyinBuffer buffer_;
- InputContext *ic_;
+ ZhuyinEngine *engine_;
+ ZhuyinBuffer buffer_;
+ InputContext *ic_;
};
class ZhuyinEngine : public InputMethodEngine, public ZhuyinProviderInterface {
public:
- explicit ZhuyinEngine(Instance *instance);
-
- void keyEvent(const fcitx::InputMethodEntry &entry,
- fcitx::KeyEvent &keyEvent) override;
- void activate(const fcitx::InputMethodEntry &,
- fcitx::InputContextEvent &) override;
- void deactivate(const fcitx::InputMethodEntry &entry,
- fcitx::InputContextEvent &event) override;
- void reset(const fcitx::InputMethodEntry &,
- fcitx::InputContextEvent &) override;
- const fcitx::Configuration *getConfig() const override;
- void setConfig(const fcitx::RawConfig &) override;
- void save() override;
- void reloadConfig() override;
-
- zhuyin_context_t *context() override { return context_.get(); }
- bool isZhuyin() const override { return isZhuyin_; }
- const auto &config() const { return config_; }
- const ZhuyinSymbol &symbol() const override { return symbol_; }
-
- const KeyList &selectionKeys() const { return selectionKeys_; }
-
- FCITX_ADDON_DEPENDENCY_LOADER(fullwidth, instance_->addonManager());
- FCITX_ADDON_DEPENDENCY_LOADER(chttrans, instance_->addonManager());
- FCITX_ADDON_DEPENDENCY_LOADER(quickphrase, instance_->addonManager());
+ explicit ZhuyinEngine(Instance *instance);
+
+ void keyEvent(const fcitx::InputMethodEntry &entry,
+ fcitx::KeyEvent &keyEvent) override;
+ void activate(const fcitx::InputMethodEntry &,
+ fcitx::InputContextEvent &) override;
+ void deactivate(const fcitx::InputMethodEntry &entry,
+ fcitx::InputContextEvent &event) override;
+ void reset(const fcitx::InputMethodEntry &,
+ fcitx::InputContextEvent &) override;
+ const fcitx::Configuration *getConfig() const override;
+ void setConfig(const fcitx::RawConfig &) override;
+ void save() override;
+ void reloadConfig() override;
+
+ zhuyin_context_t *context() override { return context_.get(); }
+ bool isZhuyin() const override { return isZhuyin_; }
+ const auto &config() const { return config_; }
+ const ZhuyinSymbol &symbol() const override { return symbol_; }
+
+ const KeyList &selectionKeys() const { return selectionKeys_; }
+
+ FCITX_ADDON_DEPENDENCY_LOADER(fullwidth, instance_->addonManager());
+ FCITX_ADDON_DEPENDENCY_LOADER(chttrans, instance_->addonManager());
+ FCITX_ADDON_DEPENDENCY_LOADER(quickphrase, instance_->addonManager());
private:
- Instance *instance_;
- UniqueCPtr context_;
- FactoryFor factory_;
- ZhuyinSymbol symbol_;
- ZhuyinConfig config_;
- KeyList selectionKeys_;
- bool isZhuyin_ = true;
+ Instance *instance_;
+ UniqueCPtr context_;
+ FactoryFor factory_;
+ ZhuyinSymbol symbol_;
+ ZhuyinConfig config_;
+ KeyList selectionKeys_;
+ bool isZhuyin_ = true;
};
class ZhuyinEngineFactory final : public AddonFactory {
public:
- fcitx::AddonInstance *create(fcitx::AddonManager *manager) override {
- registerDomain("fcitx5-zhuiyin", FCITX_INSTALL_LOCALEDIR);
- return new ZhuyinEngine(manager->instance());
- }
+ fcitx::AddonInstance *create(fcitx::AddonManager *manager) override {
+ registerDomain("fcitx5-zhuiyin", FCITX_INSTALL_LOCALEDIR);
+ return new ZhuyinEngine(manager->instance());
+ }
};
} // namespace fcitx
diff --git a/src/zhuyinsection.cpp b/src/zhuyinsection.cpp
index 4fa6e9e..e921057 100644
--- a/src/zhuyinsection.cpp
+++ b/src/zhuyinsection.cpp
@@ -27,199 +27,197 @@ ZhuyinSection::ZhuyinSection(uint32_t init, ZhuyinSectionType type,
ZhuyinProviderInterface *provider,
ZhuyinBuffer *buffer)
: ZhuyinSection(type, provider, buffer) {
- this->type(init);
+ this->type(init);
}
bool ZhuyinSection::typeImpl(const char *s, size_t length) {
- InputBuffer::typeImpl(s, length);
- if (!instance_) {
- const auto &candidates = provider_->symbol().lookup(userInput());
- if (candidates.empty()) {
- currentSymbol_ = userInput();
- } else {
- currentSymbol_ = candidates[0];
- }
- return true;
- }
- if (provider_->isZhuyin()) {
- zhuyin_parse_more_chewings(instance_.get(), userInput().data());
+ InputBuffer::typeImpl(s, length);
+ if (!instance_) {
+ const auto &candidates = provider_->symbol().lookup(userInput());
+ if (candidates.empty()) {
+ currentSymbol_ = userInput();
} else {
- zhuyin_parse_more_full_pinyins(instance_.get(), userInput().data());
+ currentSymbol_ = candidates[0];
}
- zhuyin_guess_sentence(instance_.get());
return true;
+ }
+ if (provider_->isZhuyin()) {
+ zhuyin_parse_more_chewings(instance_.get(), userInput().data());
+ } else {
+ zhuyin_parse_more_full_pinyins(instance_.get(), userInput().data());
+ }
+ zhuyin_guess_sentence(instance_.get());
+ return true;
}
size_t ZhuyinSection::prevChar() const {
- if (cursor() == 0 || !instance_) {
- return 0;
- }
-
- auto length = parsedZhuyinLength();
- if (cursor() > length) {
- return cursor() - 1;
- }
- size_t offset = 0;
- size_t prevCursor = cursor() - 1;
- zhuyin_get_zhuyin_offset(instance_.get(), prevCursor, &offset);
- return offset;
+ if (cursor() == 0 || !instance_) {
+ return 0;
+ }
+
+ auto length = parsedZhuyinLength();
+ if (cursor() > length) {
+ return cursor() - 1;
+ }
+ size_t offset = 0;
+ size_t prevCursor = cursor() - 1;
+ zhuyin_get_zhuyin_offset(instance_.get(), prevCursor, &offset);
+ return offset;
}
size_t ZhuyinSection::nextChar() const {
- if (cursor() == size()) {
- return cursor();
- }
-
- auto length = parsedZhuyinLength();
- if (cursor() + 1 >= length) {
- return cursor() + 1;
- }
- size_t offset = 0, right = 0;
- size_t nextCursor = cursor() + 1;
- zhuyin_get_zhuyin_offset(instance_.get(), nextCursor, &offset);
- zhuyin_get_right_zhuyin_offset(instance_.get(), offset, &right);
- return right;
+ if (cursor() == size()) {
+ return cursor();
+ }
+
+ auto length = parsedZhuyinLength();
+ if (cursor() + 1 >= length) {
+ return cursor() + 1;
+ }
+ size_t offset = 0, right = 0;
+ size_t nextCursor = cursor() + 1;
+ zhuyin_get_zhuyin_offset(instance_.get(), nextCursor, &offset);
+ zhuyin_get_right_zhuyin_offset(instance_.get(), offset, &right);
+ return right;
}
void ZhuyinSection::erase(size_t from, size_t to) {
- InputBuffer::erase(from, to);
- if (provider_->isZhuyin()) {
- zhuyin_parse_more_chewings(instance_.get(), userInput().data());
- } else {
- zhuyin_parse_more_full_pinyins(instance_.get(), userInput().data());
- }
- zhuyin_guess_sentence(instance_.get());
+ InputBuffer::erase(from, to);
+ if (provider_->isZhuyin()) {
+ zhuyin_parse_more_chewings(instance_.get(), userInput().data());
+ } else {
+ zhuyin_parse_more_full_pinyins(instance_.get(), userInput().data());
+ }
+ zhuyin_guess_sentence(instance_.get());
}
void ZhuyinSection::setSymbol(std::string symbol) {
- currentSymbol_ = std::move(symbol);
+ currentSymbol_ = std::move(symbol);
}
std::string ZhuyinSection::preedit() const { return preeditWithCursor().first; }
void ZhuyinSection::learn() {
- if (!instance_) {
- return;
- }
- zhuyin_train(instance_.get());
+ if (!instance_) {
+ return;
+ }
+ zhuyin_train(instance_.get());
}
std::pair ZhuyinSection::preeditWithCursor() const {
- std::string result;
- if (!instance_) {
- return {currentSymbol_, currentSymbol_.size()};
- }
-
- auto length = parsedZhuyinLength();
- char *sentence = nullptr;
- if (length) {
- zhuyin_get_sentence(instance_.get(), &sentence);
- }
-
+ std::string result;
+ if (!instance_) {
+ return {currentSymbol_, currentSymbol_.size()};
+ }
+
+ auto length = parsedZhuyinLength();
+ char *sentence = nullptr;
+ if (length) {
+ zhuyin_get_sentence(instance_.get(), &sentence);
+ }
+
+ if (sentence) {
+ result.append(sentence);
+ }
+
+ auto preeditCursor = cursor();
+ if (preeditCursor >= length) {
+ preeditCursor -= length;
if (sentence) {
- result.append(sentence);
+ preeditCursor += strlen(sentence);
}
+ } else {
+ size_t offset;
+ zhuyin_get_character_offset(instance_.get(), sentence, cursor(), &offset);
+ preeditCursor = utf8::ncharByteLength(sentence, offset);
+ }
- auto preeditCursor = cursor();
- if (preeditCursor >= length) {
- preeditCursor -= length;
- if (sentence) {
- preeditCursor += strlen(sentence);
- }
+ free(sentence);
+ for (; length < size(); length++) {
+ if (provider_->isZhuyin()) {
+ gchar **symbols = nullptr;
+ zhuyin_in_chewing_keyboard(instance_.get(), charAt(length), &symbols);
+ if (symbols && symbols[0]) {
+ result.append(symbols[0]);
+ }
+ g_strfreev(symbols);
} else {
- size_t offset;
- zhuyin_get_character_offset(instance_.get(), sentence, cursor(),
- &offset);
- preeditCursor = utf8::ncharByteLength(sentence, offset);
+ result.push_back(static_cast(charAt(length)));
}
- free(sentence);
- for (; length < size(); length++) {
- if (provider_->isZhuyin()) {
- gchar **symbols = nullptr;
- zhuyin_in_chewing_keyboard(instance_.get(), charAt(length),
- &symbols);
- if (symbols && symbols[0]) {
- result.append(symbols[0]);
- }
- g_strfreev(symbols);
- } else {
- result.push_back(static_cast(charAt(length)));
- }
-
- if (length + 1 == cursor()) {
- preeditCursor = result.size();
- }
+ if (length + 1 == cursor()) {
+ preeditCursor = result.size();
}
- return {result, preeditCursor};
+ }
+ return {result, preeditCursor};
}
size_t ZhuyinSection::parsedZhuyinLength() const {
- if (!instance_) {
- throw std::runtime_error("Bug in fcitx5-zhuyin");
- }
- return zhuyin_get_parsed_input_length(instance_.get());
+ if (!instance_) {
+ throw std::runtime_error("Bug in fcitx5-zhuyin");
+ }
+ return zhuyin_get_parsed_input_length(instance_.get());
}
void ZhuyinSection::showCandidate(
const std::function)> &callback,
SectionIterator iter, size_t offset) {
- assert(&*iter == this);
- if (!instance_) {
- if (size() == 1) {
- auto c = charAt(offset);
- gchar **symbols = nullptr;
- if (c < std::numeric_limits::max() &&
- zhuyin_in_chewing_keyboard(buffer_->instance(), c, &symbols)) {
- // Make sure we have two symbol.
- if (symbols[0] && symbols[1]) {
- for (size_t i = 0; symbols[i]; i++) {
- callback(std::make_unique(
- iter, symbols[i]));
- }
- }
- g_strfreev(symbols);
- return;
- }
- }
-
- auto candidates = provider_->symbol().lookup(userInput());
- if (candidates.empty()) {
- return;
- }
- for (const auto &symbol : candidates) {
- callback(std::make_unique(iter, symbol));
+ assert(&*iter == this);
+ if (!instance_) {
+ if (size() == 1) {
+ auto c = charAt(offset);
+ gchar **symbols = nullptr;
+ if (c < std::numeric_limits::max() &&
+ zhuyin_in_chewing_keyboard(buffer_->instance(), c, &symbols)) {
+ // Make sure we have two symbol.
+ if (symbols[0] && symbols[1]) {
+ for (size_t i = 0; symbols[i]; i++) {
+ callback(
+ std::make_unique(iter, symbols[i]));
+ }
}
+ g_strfreev(symbols);
return;
+ }
}
- if (offset >= parsedZhuyinLength()) {
- if (!provider_->isZhuyin() || offset >= size()) {
- return;
- }
- auto c = charAt(offset);
- gchar **symbols = nullptr;
- if (c < std::numeric_limits::max() &&
- zhuyin_in_chewing_keyboard(instance_.get(), c, &symbols)) {
- // Make sure we have two symbol.
- if (symbols[0] && symbols[1]) {
- for (size_t i = 0; symbols[i]; i++) {
- callback(std::make_unique(
- iter, symbols[i], offset));
- }
- }
- g_strfreev(symbols);
- }
- return;
+ auto candidates = provider_->symbol().lookup(userInput());
+ if (candidates.empty()) {
+ return;
}
+ for (const auto &symbol : candidates) {
+ callback(std::make_unique(iter, symbol));
+ }
+ return;
+ }
- zhuyin_get_zhuyin_offset(instance_.get(), offset, &offset);
- zhuyin_guess_candidates_after_cursor(instance_.get(), offset);
- guint len = 0;
- zhuyin_get_n_candidate(instance_.get(), &len);
- for (size_t i = 0; i < len; i++) {
- callback(std::make_unique(iter, i));
+ if (offset >= parsedZhuyinLength()) {
+ if (!provider_->isZhuyin() || offset >= size()) {
+ return;
}
+ auto c = charAt(offset);
+ gchar **symbols = nullptr;
+ if (c < std::numeric_limits::max() &&
+ zhuyin_in_chewing_keyboard(instance_.get(), c, &symbols)) {
+ // Make sure we have two symbol.
+ if (symbols[0] && symbols[1]) {
+ for (size_t i = 0; symbols[i]; i++) {
+ callback(std::make_unique(
+ iter, symbols[i], offset));
+ }
+ }
+ g_strfreev(symbols);
+ }
+ return;
+ }
+
+ zhuyin_get_zhuyin_offset(instance_.get(), offset, &offset);
+ zhuyin_guess_candidates_after_cursor(instance_.get(), offset);
+ guint len = 0;
+ zhuyin_get_n_candidate(instance_.get(), &len);
+ for (size_t i = 0; i < len; i++) {
+ callback(std::make_unique(iter, i));
+ }
}
} // namespace fcitx
diff --git a/src/zhuyinsection.h b/src/zhuyinsection.h
index 9e36c4e..0e941a7 100644
--- a/src/zhuyinsection.h
+++ b/src/zhuyinsection.h
@@ -22,47 +22,47 @@ class ZhuyinProviderInterface;
using SectionIterator = std::list::iterator;
enum class ZhuyinSectionType {
- Zhuyin,
- Symbol,
+ Zhuyin,
+ Symbol,
};
// A section of preedit, it can be either a single symbol, or a series of
// Zhuyin.
class ZhuyinSection : public InputBuffer {
public:
- ZhuyinSection(ZhuyinSectionType type, ZhuyinProviderInterface *provider,
- ZhuyinBuffer *buffer);
- ZhuyinSection(uint32_t init, ZhuyinSectionType type,
- ZhuyinProviderInterface *provider, ZhuyinBuffer *buffer);
+ ZhuyinSection(ZhuyinSectionType type, ZhuyinProviderInterface *provider,
+ ZhuyinBuffer *buffer);
+ ZhuyinSection(uint32_t init, ZhuyinSectionType type,
+ ZhuyinProviderInterface *provider, ZhuyinBuffer *buffer);
- ZhuyinSectionType sectionType() const { return type_; }
+ ZhuyinSectionType sectionType() const { return type_; }
- size_t parsedZhuyinLength() const;
+ size_t parsedZhuyinLength() const;
- std::string preedit() const;
- std::pair preeditWithCursor() const;
- size_t prevChar() const;
- size_t nextChar() const;
+ std::string preedit() const;
+ std::pair preeditWithCursor() const;
+ size_t prevChar() const;
+ size_t nextChar() const;
- void erase(size_t from, size_t to) override;
- void setSymbol(std::string symbol);
+ void erase(size_t from, size_t to) override;
+ void setSymbol(std::string symbol);
- void showCandidate(
- const std::function)> &callback,
- SectionIterator iter, size_t offset);
- void learn();
- auto instance() const { return instance_.get(); }
- auto buffer() const { return buffer_; }
+ void showCandidate(
+ const std::function)> &callback,
+ SectionIterator iter, size_t offset);
+ void learn();
+ auto instance() const { return instance_.get(); }
+ auto buffer() const { return buffer_; }
protected:
- bool typeImpl(const char *s, size_t length) override;
+ bool typeImpl(const char *s, size_t length) override;
private:
- ZhuyinProviderInterface *provider_;
- ZhuyinBuffer *buffer_;
- const ZhuyinSectionType type_;
- std::string currentSymbol_;
- UniqueCPtr instance_;
+ ZhuyinProviderInterface *provider_;
+ ZhuyinBuffer *buffer_;
+ const ZhuyinSectionType type_;
+ std::string currentSymbol_;
+ UniqueCPtr instance_;
};
} // namespace fcitx
diff --git a/src/zhuyinsymbol.cpp b/src/zhuyinsymbol.cpp
index f704e51..d84991e 100644
--- a/src/zhuyinsymbol.cpp
+++ b/src/zhuyinsymbol.cpp
@@ -19,247 +19,244 @@ ZhuyinSymbol::ZhuyinSymbol() { initBuiltin(); }
const std::vector &
ZhuyinSymbol::lookup(const std::string &key) const {
- if (auto iter = symbols_.find(key); iter != symbols_.end()) {
- return iter->second;
- }
- return empty;
+ if (auto iter = symbols_.find(key); iter != symbols_.end()) {
+ return iter->second;
+ }
+ return empty;
}
void ZhuyinSymbol::load(std::FILE *file) {
- symbols_.clear();
- initBuiltin();
+ symbols_.clear();
+ initBuiltin();
- if (!file) {
- for (char c = 'A'; c <= 'Z'; c++) {
- char latin[] = {c, '\0'};
- symbols_.erase(latin);
- }
- return;
+ if (!file) {
+ for (char c = 'A'; c <= 'Z'; c++) {
+ char latin[] = {c, '\0'};
+ symbols_.erase(latin);
+ }
+ return;
+ }
+ UniqueCPtr line;
+ size_t size = 0;
+ while (getline(line, &size, file) >= 0) {
+ auto trimmed = stringutils::trim(line.get());
+ if (trimmed.empty()) {
+ continue;
}
- UniqueCPtr line;
- size_t size = 0;
- while (getline(line, &size, file) >= 0) {
- auto trimmed = stringutils::trim(line.get());
- if (trimmed.empty()) {
- continue;
- }
- auto space = trimmed.find(' ');
- auto key = trimmed.substr(0, space);
- auto value = trimmed.substr(space + 1);
- if (key.empty() || value.empty()) {
- continue;
- }
+ auto space = trimmed.find(' ');
+ auto key = trimmed.substr(0, space);
+ auto value = trimmed.substr(space + 1);
+ if (key.empty() || value.empty()) {
+ continue;
+ }
- std::vector items;
- items.push_back(std::move(value));
- items.push_back(key);
- if (auto iter = symbolToGroup_.find(items[0]);
- iter != symbolToGroup_.end()) {
- for (const auto &item : groups_[iter->second]) {
- if (item != items[0]) {
- items.push_back(item);
- }
- }
+ std::vector items;
+ items.push_back(std::move(value));
+ items.push_back(key);
+ if (auto iter = symbolToGroup_.find(items[0]);
+ iter != symbolToGroup_.end()) {
+ for (const auto &item : groups_[iter->second]) {
+ if (item != items[0]) {
+ items.push_back(item);
}
- symbols_[key] = std::move(items);
+ }
}
+ symbols_[key] = std::move(items);
+ }
}
void ZhuyinSymbol::initBuiltin() {
- symbolToGroup_.clear();
- groups_.clear();
- constexpr const char *const symbolGroup[][50] = {
- {"0", "\xC3\xB8", nullptr},
- /* "ø" */
- {"[", "\xE3\x80\x8C", "\xE3\x80\x8E", "\xE3\x80\x8A", "\xE3\x80\x88",
- "\xE3\x80\x90", "\xE3\x80\x94", nullptr},
- /* "「", "『", "《", "〈", "【", "〔" */
- {"]", "\xE3\x80\x8D", "\xE3\x80\x8F", "\xE3\x80\x8B", "\xE3\x80\x89",
- "\xE3\x80\x91", "\xE3\x80\x95", nullptr},
- /* "」", "』", "》", "〉", "】", "〕" */
- {"{", "\xEF\xBD\x9B", nullptr},
- /* "{" */
- {"}", "\xEF\xBD\x9D", nullptr},
- /* "}" */
- {"<", "\xEF\xBC\x8C", "\xE2\x86\x90", nullptr},
- /* ",", "←" */
- {">", "\xE3\x80\x82", "\xE2\x86\x92", "\xEF\xBC\x8E", nullptr},
- /* "。", "→", "." */
- {"?", "\xEF\xBC\x9F", "\xC2\xBF", nullptr},
- /* "?", "¿" */
- {"!", "\xEF\xBC\x81", "\xE2\x85\xA0", "\xC2\xA1", nullptr},
- /* "!", "Ⅰ","¡" */
- {"@", "\xEF\xBC\xA0", "\xE2\x85\xA1", "\xE2\x8A\x95", "\xE2\x8A\x99",
- "\xE3\x8A\xA3", "\xEF\xB9\xAB", nullptr},
- /* "@", "Ⅱ", "⊕", "⊙", "㊣", "﹫" */
- {"#", "\xEF\xBC\x83", "\xE2\x85\xA2", "\xEF\xB9\x9F", nullptr},
- /* "#", "Ⅲ", "﹟" */
- {"$", "\xEF\xBC\x84", "\xE2\x85\xA3", "\xE2\x82\xAC", "\xEF\xB9\xA9",
- "\xEF\xBF\xA0", "\xE2\x88\xAE", "\xEF\xBF\xA1", "\xEF\xBF\xA5",
- nullptr},
- /* "$", "Ⅳ", "€", "﹩", "¢", "∮","£", "¥" */
- {"%", "\xEF\xBC\x85", "\xE2\x85\xA4", nullptr},
- /* "%", "Ⅴ" */
- {"^", "\xEF\xB8\xBF", "\xE2\x85\xA5", "\xEF\xB9\x80", "\xEF\xB8\xBD",
- "\xEF\xB8\xBE", nullptr},
- /* "︿", "Ⅵ", "﹀", "︽", "︾" */
- {"&", "\xEF\xBC\x86", "\xE2\x85\xA6", "\xEF\xB9\xA0", nullptr},
- /* "&", "Ⅶ", "﹠" */
- {"*", "\xEF\xBC\x8A", "\xE2\x85\xA7", "\xC3\x97", "\xE2\x80\xBB",
- "\xE2\x95\xB3", "\xEF\xB9\xA1", "\xE2\x98\xAF", "\xE2\x98\x86",
- "\xE2\x98\x85", nullptr},
- /* "*", "Ⅷ", "×", "※", "╳", "﹡", "☯", "☆", "★" */
- {"(", "\xEF\xBC\x88", "\xE2\x85\xA8", nullptr},
- /* "(", "Ⅸ" */
- {")", "\xEF\xBC\x89", "\xE2\x85\xA9", nullptr},
- /* ")", "Ⅹ" */
- {"_", "\xEF\xBC\xBF", "\xE2\x80\xA6", "\xE2\x80\xA5", "\xE2\x86\x90",
- "\xE2\x86\x92", "\xEF\xB9\x8D", "\xEF\xB9\x89", "\xCB\x8D",
- "\xEF\xBF\xA3", "\xE2\x80\x93", "\xE2\x80\x94", "\xC2\xAF",
- "\xEF\xB9\x8A", "\xEF\xB9\x8E", "\xEF\xB9\x8F", "\xEF\xB9\xA3",
- "\xEF\xBC\x8D", nullptr},
- /* "_", "…", "‥", "←", "→", "﹍", "﹉", "ˍ", " ̄"
- * "–", "—", "¯", "﹊", "﹎", "﹏", "﹣", "-" */
- {"+", "\xEF\xBC\x8B", "\xC2\xB1", "\xEF\xB9\xA2", nullptr},
- /* "+", "±", "﹢" */
- {"=", "\xEF\xBC\x9D", "\xE2\x89\x92", "\xE2\x89\xA0", "\xE2\x89\xA1",
- "\xE2\x89\xA6", "\xE2\x89\xA7", "\xEF\xB9\xA6", nullptr},
- /* "=", "≒", "≠", "≡", "≦", "≧", "﹦" */
- {"`", "\xE3\x80\x8F", "\xE3\x80\x8E", "\xE2\x80\xB2", "\xE2\x80\xB5",
- nullptr},
- /* "』", "『", "′", "‵" */
- {"~", "\xEF\xBD\x9E", nullptr},
- /* "~" */
- {":", "\xEF\xBC\x9A", "\xEF\xBC\x9B", "\xEF\xB8\xB0", "\xEF\xB9\x95",
- nullptr},
- /* ":", ";", "︰", "﹕" */
- {"\"", "\xEF\xBC\x9B", nullptr},
- /* ";" */
- {"\'", "\xE3\x80\x81", "\xE2\x80\xA6", "\xE2\x80\xA5", nullptr},
- /* "、", "…", "‥" */
- {"\\", "\xEF\xBC\xBC", "\xE2\x86\x96", "\xE2\x86\x98", "\xEF\xB9\xA8",
- nullptr},
- /* "\", "↖", "↘", "﹨" */
- {"-",
- "\xEF\xBC\x8D",
- "\xEF\xBC\xBF",
- "\xEF\xBF\xA3",
- "\xC2\xAF",
- "\xCB\x8D",
- "\xE2\x80\x93",
- "\xE2\x80\x94",
- "\xE2\x80\xA5",
- "\xE2\x80\xA6",
- "\xE2\x86\x90",
- "\xE2\x86\x92",
- "\xE2\x95\xB4",
- "\xEF\xB9\x89",
- "\xEF\xB9\x8A",
- "\xEF\xB9\x8D",
- "\xEF\xB9\x8E",
- "\xEF\xB9\x8F",
- "\xEF\xB9\xA3",
- nullptr},
- /* "-", "_", " ̄", "¯", "ˍ", "–", "—", "‥", "…"
- * "←", "→", "╴", "﹉", "﹊", "﹍", "﹎", "﹏", "﹣" */
- {"/", "\xEF\xBC\x8F", "\xC3\xB7", "\xE2\x86\x97", "\xE2\x86\x99",
- "\xE2\x88\x95", nullptr},
- /* "/","÷","↗","↙","∕" */
- {"|", "\xE2\x86\x91", "\xE2\x86\x93", "\xE2\x88\xA3", "\xE2\x88\xA5",
- "\xEF\xB8\xB1", "\xEF\xB8\xB3", "\xEF\xB8\xB4", 0},
- /* "↑", "↓", "∣", "∥", "︱", "︳", "︴" */
- {"A", "\xC3\x85", "\xCE\x91", "\xCE\xB1", "\xE2\x94\x9C",
- "\xE2\x95\xA0", "\xE2\x95\x9F", "\xE2\x95\x9E", nullptr},
- /* "Å","Α", "α", "├", "╠", "╟", "╞" */
- {"B", "\xCE\x92", "\xCE\xB2", "\xE2\x88\xB5", nullptr},
- /* "Β", "β","∵" */
- {"C", "\xCE\xA7", "\xCF\x87", "\xE2\x94\x98", "\xE2\x95\xAF",
- "\xE2\x95\x9D", "\xE2\x95\x9C", "\xE2\x95\x9B", "\xE3\x8F\x84",
- "\xE2\x84\x83", "\xE3\x8E\x9D", "\xE2\x99\xA3", "\xC2\xA9", nullptr},
- /* "Χ", "χ", "┘", "╯", "╝", "╜", "╛"
- * "㏄", "℃", "㎝", "♣", "©" */
- {"D", "\xCE\x94", "\xCE\xB4", "\xE2\x97\x87", "\xE2\x97\x86",
- "\xE2\x94\xA4", "\xE2\x95\xA3", "\xE2\x95\xA2", "\xE2\x95\xA1",
- "\xE2\x99\xA6", nullptr},
- /* "Δ", "δ", "◇", "◆", "┤", "╣", "╢", "╡","♦" */
- {"E", "\xCE\x95", "\xCE\xB5", "\xE2\x94\x90", "\xE2\x95\xAE",
- "\xE2\x95\x97", "\xE2\x95\x93", "\xE2\x95\x95", nullptr},
- /* "Ε", "ε", "┐", "╮", "╗", "╓", "╕" */
- {"F", "\xCE\xA6", "\xCF\x88", "\xE2\x94\x82", "\xE2\x95\x91",
- "\xE2\x99\x80", nullptr},
- /* "Φ", "ψ", "│", "║", "♀" */
- {"G", "\xCE\x93", "\xCE\xB3", nullptr},
- /* "Γ", "γ" */
- {"H", "\xCE\x97", "\xCE\xB7", "\xE2\x99\xA5", nullptr},
- /* "Η", "η","♥" */
- {"I", "\xCE\x99", "\xCE\xB9", nullptr},
- /* "Ι", "ι" */
- {"J", "\xCF\x86", nullptr},
- /* "φ" */
- {"K", "\xCE\x9A", "\xCE\xBA", "\xE3\x8E\x9E", "\xE3\x8F\x8E", nullptr},
- /* "Κ", "κ","㎞", "㏎" */
- {"L", "\xCE\x9B", "\xCE\xBB", "\xE3\x8F\x92", "\xE3\x8F\x91", nullptr},
- /* "Λ", "λ","㏒", "㏑" */
- {"M", "\xCE\x9C", "\xCE\xBC", "\xE2\x99\x82", "\xE2\x84\x93",
- "\xE3\x8E\x8E", "\xE3\x8F\x95", "\xE3\x8E\x9C", "\xE3\x8E\xA1",
- nullptr},
- /* "Μ", "μ", "♂", "ℓ", "㎎", "㏕", "㎜","㎡" */
- {"N", "\xCE\x9D", "\xCE\xBD", "\xE2\x84\x96", nullptr},
- /* "Ν", "ν","№" */
- {"O", "\xCE\x9F", "\xCE\xBF", nullptr},
- /* "Ο", "ο" */
- {"P", "\xCE\xA0", "\xCF\x80", nullptr},
- /* "Π", "π" */
- {"Q", "\xCE\x98", "\xCE\xB8", "\xD0\x94", "\xE2\x94\x8C",
- "\xE2\x95\xAD", "\xE2\x95\x94", "\xE2\x95\x93", "\xE2\x95\x92",
- nullptr},
- /* "Θ", "θ","Д","┌", "╭", "╔", "╓", "╒" */
- {"R", "\xCE\xA1", "\xCF\x81", "\xE2\x94\x80", "\xE2\x95\x90",
- "\xC2\xAE", nullptr},
- /* "Ρ", "ρ", "─", "═" ,"®" */
- {"S", "\xCE\xA3", "\xCF\x83", "\xE2\x88\xB4", "\xE2\x96\xA1",
- "\xE2\x96\xA0", "\xE2\x94\xBC", "\xE2\x95\xAC", "\xE2\x95\xAA",
- "\xE2\x95\xAB", "\xE2\x88\xAB", "\xC2\xA7", "\xE2\x99\xA0", nullptr},
- /* "Σ", "σ", "∴", "□", "■", "┼", "╬", "╪", "╫"
- * "∫", "§", "♠" */
- {"T", "\xCE\xA4", "\xCF\x84", "\xCE\xB8", "\xE2\x96\xB3",
- "\xE2\x96\xB2", "\xE2\x96\xBD", "\xE2\x96\xBC", "\xE2\x84\xA2",
- "\xE2\x8A\xBF", "\xE2\x84\xA2", nullptr},
- /* "Τ", "τ","θ","△","▲","▽","▼","™","⊿", "™" */
- {"U", "\xCE\xA5", "\xCF\x85", "\xCE\xBC", "\xE2\x88\xAA",
- "\xE2\x88\xA9", nullptr},
- /* "Υ", "υ","μ","∪", "∩" */
- {"V", "\xCE\xBD", nullptr},
- {"W", "\xE2\x84\xA6", "\xCF\x89", "\xE2\x94\xAC", "\xE2\x95\xA6",
- "\xE2\x95\xA4", "\xE2\x95\xA5", nullptr},
- /* "Ω", "ω", "┬", "╦", "╤", "╥" */
- {"X", "\xCE\x9E", "\xCE\xBE", "\xE2\x94\xB4", "\xE2\x95\xA9",
- "\xE2\x95\xA7", "\xE2\x95\xA8", nullptr},
- /* "Ξ", "ξ", "┴", "╩", "╧", "╨" */
- {"Y", "\xCE\xA8", nullptr},
- /* "Ψ" */
- {"Z", "\xCE\x96", "\xCE\xB6", "\xE2\x94\x94", "\xE2\x95\xB0",
- "\xE2\x95\x9A", "\xE2\x95\x99", "\xE2\x95\x98", nullptr},
- /* "Ζ", "ζ", "└", "╰", "╚", "╙", "╘" */
- };
+ symbolToGroup_.clear();
+ groups_.clear();
+ constexpr const char *const symbolGroup[][50] = {
+ {"0", "\xC3\xB8", nullptr},
+ /* "ø" */
+ {"[", "\xE3\x80\x8C", "\xE3\x80\x8E", "\xE3\x80\x8A", "\xE3\x80\x88",
+ "\xE3\x80\x90", "\xE3\x80\x94", nullptr},
+ /* "「", "『", "《", "〈", "【", "〔" */
+ {"]", "\xE3\x80\x8D", "\xE3\x80\x8F", "\xE3\x80\x8B", "\xE3\x80\x89",
+ "\xE3\x80\x91", "\xE3\x80\x95", nullptr},
+ /* "」", "』", "》", "〉", "】", "〕" */
+ {"{", "\xEF\xBD\x9B", nullptr},
+ /* "{" */
+ {"}", "\xEF\xBD\x9D", nullptr},
+ /* "}" */
+ {"<", "\xEF\xBC\x8C", "\xE2\x86\x90", nullptr},
+ /* ",", "←" */
+ {">", "\xE3\x80\x82", "\xE2\x86\x92", "\xEF\xBC\x8E", nullptr},
+ /* "。", "→", "." */
+ {"?", "\xEF\xBC\x9F", "\xC2\xBF", nullptr},
+ /* "?", "¿" */
+ {"!", "\xEF\xBC\x81", "\xE2\x85\xA0", "\xC2\xA1", nullptr},
+ /* "!", "Ⅰ","¡" */
+ {"@", "\xEF\xBC\xA0", "\xE2\x85\xA1", "\xE2\x8A\x95", "\xE2\x8A\x99",
+ "\xE3\x8A\xA3", "\xEF\xB9\xAB", nullptr},
+ /* "@", "Ⅱ", "⊕", "⊙", "㊣", "﹫" */
+ {"#", "\xEF\xBC\x83", "\xE2\x85\xA2", "\xEF\xB9\x9F", nullptr},
+ /* "#", "Ⅲ", "﹟" */
+ {"$", "\xEF\xBC\x84", "\xE2\x85\xA3", "\xE2\x82\xAC", "\xEF\xB9\xA9",
+ "\xEF\xBF\xA0", "\xE2\x88\xAE", "\xEF\xBF\xA1", "\xEF\xBF\xA5", nullptr},
+ /* "$", "Ⅳ", "€", "﹩", "¢", "∮","£", "¥" */
+ {"%", "\xEF\xBC\x85", "\xE2\x85\xA4", nullptr},
+ /* "%", "Ⅴ" */
+ {"^", "\xEF\xB8\xBF", "\xE2\x85\xA5", "\xEF\xB9\x80", "\xEF\xB8\xBD",
+ "\xEF\xB8\xBE", nullptr},
+ /* "︿", "Ⅵ", "﹀", "︽", "︾" */
+ {"&", "\xEF\xBC\x86", "\xE2\x85\xA6", "\xEF\xB9\xA0", nullptr},
+ /* "&", "Ⅶ", "﹠" */
+ {"*", "\xEF\xBC\x8A", "\xE2\x85\xA7", "\xC3\x97", "\xE2\x80\xBB",
+ "\xE2\x95\xB3", "\xEF\xB9\xA1", "\xE2\x98\xAF", "\xE2\x98\x86",
+ "\xE2\x98\x85", nullptr},
+ /* "*", "Ⅷ", "×", "※", "╳", "﹡", "☯", "☆", "★" */
+ {"(", "\xEF\xBC\x88", "\xE2\x85\xA8", nullptr},
+ /* "(", "Ⅸ" */
+ {")", "\xEF\xBC\x89", "\xE2\x85\xA9", nullptr},
+ /* ")", "Ⅹ" */
+ {"_", "\xEF\xBC\xBF", "\xE2\x80\xA6", "\xE2\x80\xA5", "\xE2\x86\x90",
+ "\xE2\x86\x92", "\xEF\xB9\x8D", "\xEF\xB9\x89", "\xCB\x8D",
+ "\xEF\xBF\xA3", "\xE2\x80\x93", "\xE2\x80\x94", "\xC2\xAF",
+ "\xEF\xB9\x8A", "\xEF\xB9\x8E", "\xEF\xB9\x8F", "\xEF\xB9\xA3",
+ "\xEF\xBC\x8D", nullptr},
+ /* "_", "…", "‥", "←", "→", "﹍", "﹉", "ˍ", " ̄"
+ * "–", "—", "¯", "﹊", "﹎", "﹏", "﹣", "-" */
+ {"+", "\xEF\xBC\x8B", "\xC2\xB1", "\xEF\xB9\xA2", nullptr},
+ /* "+", "±", "﹢" */
+ {"=", "\xEF\xBC\x9D", "\xE2\x89\x92", "\xE2\x89\xA0", "\xE2\x89\xA1",
+ "\xE2\x89\xA6", "\xE2\x89\xA7", "\xEF\xB9\xA6", nullptr},
+ /* "=", "≒", "≠", "≡", "≦", "≧", "﹦" */
+ {"`", "\xE3\x80\x8F", "\xE3\x80\x8E", "\xE2\x80\xB2", "\xE2\x80\xB5",
+ nullptr},
+ /* "』", "『", "′", "‵" */
+ {"~", "\xEF\xBD\x9E", nullptr},
+ /* "~" */
+ {":", "\xEF\xBC\x9A", "\xEF\xBC\x9B", "\xEF\xB8\xB0", "\xEF\xB9\x95",
+ nullptr},
+ /* ":", ";", "︰", "﹕" */
+ {"\"", "\xEF\xBC\x9B", nullptr},
+ /* ";" */
+ {"\'", "\xE3\x80\x81", "\xE2\x80\xA6", "\xE2\x80\xA5", nullptr},
+ /* "、", "…", "‥" */
+ {"\\", "\xEF\xBC\xBC", "\xE2\x86\x96", "\xE2\x86\x98", "\xEF\xB9\xA8",
+ nullptr},
+ /* "\", "↖", "↘", "﹨" */
+ {"-",
+ "\xEF\xBC\x8D",
+ "\xEF\xBC\xBF",
+ "\xEF\xBF\xA3",
+ "\xC2\xAF",
+ "\xCB\x8D",
+ "\xE2\x80\x93",
+ "\xE2\x80\x94",
+ "\xE2\x80\xA5",
+ "\xE2\x80\xA6",
+ "\xE2\x86\x90",
+ "\xE2\x86\x92",
+ "\xE2\x95\xB4",
+ "\xEF\xB9\x89",
+ "\xEF\xB9\x8A",
+ "\xEF\xB9\x8D",
+ "\xEF\xB9\x8E",
+ "\xEF\xB9\x8F",
+ "\xEF\xB9\xA3",
+ nullptr},
+ /* "-", "_", " ̄", "¯", "ˍ", "–", "—", "‥", "…"
+ * "←", "→", "╴", "﹉", "﹊", "﹍", "﹎", "﹏", "﹣" */
+ {"/", "\xEF\xBC\x8F", "\xC3\xB7", "\xE2\x86\x97", "\xE2\x86\x99",
+ "\xE2\x88\x95", nullptr},
+ /* "/","÷","↗","↙","∕" */
+ {"|", "\xE2\x86\x91", "\xE2\x86\x93", "\xE2\x88\xA3", "\xE2\x88\xA5",
+ "\xEF\xB8\xB1", "\xEF\xB8\xB3", "\xEF\xB8\xB4", 0},
+ /* "↑", "↓", "∣", "∥", "︱", "︳", "︴" */
+ {"A", "\xC3\x85", "\xCE\x91", "\xCE\xB1", "\xE2\x94\x9C", "\xE2\x95\xA0",
+ "\xE2\x95\x9F", "\xE2\x95\x9E", nullptr},
+ /* "Å","Α", "α", "├", "╠", "╟", "╞" */
+ {"B", "\xCE\x92", "\xCE\xB2", "\xE2\x88\xB5", nullptr},
+ /* "Β", "β","∵" */
+ {"C", "\xCE\xA7", "\xCF\x87", "\xE2\x94\x98", "\xE2\x95\xAF",
+ "\xE2\x95\x9D", "\xE2\x95\x9C", "\xE2\x95\x9B", "\xE3\x8F\x84",
+ "\xE2\x84\x83", "\xE3\x8E\x9D", "\xE2\x99\xA3", "\xC2\xA9", nullptr},
+ /* "Χ", "χ", "┘", "╯", "╝", "╜", "╛"
+ * "㏄", "℃", "㎝", "♣", "©" */
+ {"D", "\xCE\x94", "\xCE\xB4", "\xE2\x97\x87", "\xE2\x97\x86",
+ "\xE2\x94\xA4", "\xE2\x95\xA3", "\xE2\x95\xA2", "\xE2\x95\xA1",
+ "\xE2\x99\xA6", nullptr},
+ /* "Δ", "δ", "◇", "◆", "┤", "╣", "╢", "╡","♦" */
+ {"E", "\xCE\x95", "\xCE\xB5", "\xE2\x94\x90", "\xE2\x95\xAE",
+ "\xE2\x95\x97", "\xE2\x95\x93", "\xE2\x95\x95", nullptr},
+ /* "Ε", "ε", "┐", "╮", "╗", "╓", "╕" */
+ {"F", "\xCE\xA6", "\xCF\x88", "\xE2\x94\x82", "\xE2\x95\x91",
+ "\xE2\x99\x80", nullptr},
+ /* "Φ", "ψ", "│", "║", "♀" */
+ {"G", "\xCE\x93", "\xCE\xB3", nullptr},
+ /* "Γ", "γ" */
+ {"H", "\xCE\x97", "\xCE\xB7", "\xE2\x99\xA5", nullptr},
+ /* "Η", "η","♥" */
+ {"I", "\xCE\x99", "\xCE\xB9", nullptr},
+ /* "Ι", "ι" */
+ {"J", "\xCF\x86", nullptr},
+ /* "φ" */
+ {"K", "\xCE\x9A", "\xCE\xBA", "\xE3\x8E\x9E", "\xE3\x8F\x8E", nullptr},
+ /* "Κ", "κ","㎞", "㏎" */
+ {"L", "\xCE\x9B", "\xCE\xBB", "\xE3\x8F\x92", "\xE3\x8F\x91", nullptr},
+ /* "Λ", "λ","㏒", "㏑" */
+ {"M", "\xCE\x9C", "\xCE\xBC", "\xE2\x99\x82", "\xE2\x84\x93",
+ "\xE3\x8E\x8E", "\xE3\x8F\x95", "\xE3\x8E\x9C", "\xE3\x8E\xA1", nullptr},
+ /* "Μ", "μ", "♂", "ℓ", "㎎", "㏕", "㎜","㎡" */
+ {"N", "\xCE\x9D", "\xCE\xBD", "\xE2\x84\x96", nullptr},
+ /* "Ν", "ν","№" */
+ {"O", "\xCE\x9F", "\xCE\xBF", nullptr},
+ /* "Ο", "ο" */
+ {"P", "\xCE\xA0", "\xCF\x80", nullptr},
+ /* "Π", "π" */
+ {"Q", "\xCE\x98", "\xCE\xB8", "\xD0\x94", "\xE2\x94\x8C", "\xE2\x95\xAD",
+ "\xE2\x95\x94", "\xE2\x95\x93", "\xE2\x95\x92", nullptr},
+ /* "Θ", "θ","Д","┌", "╭", "╔", "╓", "╒" */
+ {"R", "\xCE\xA1", "\xCF\x81", "\xE2\x94\x80", "\xE2\x95\x90", "\xC2\xAE",
+ nullptr},
+ /* "Ρ", "ρ", "─", "═" ,"®" */
+ {"S", "\xCE\xA3", "\xCF\x83", "\xE2\x88\xB4", "\xE2\x96\xA1",
+ "\xE2\x96\xA0", "\xE2\x94\xBC", "\xE2\x95\xAC", "\xE2\x95\xAA",
+ "\xE2\x95\xAB", "\xE2\x88\xAB", "\xC2\xA7", "\xE2\x99\xA0", nullptr},
+ /* "Σ", "σ", "∴", "□", "■", "┼", "╬", "╪", "╫"
+ * "∫", "§", "♠" */
+ {"T", "\xCE\xA4", "\xCF\x84", "\xCE\xB8", "\xE2\x96\xB3", "\xE2\x96\xB2",
+ "\xE2\x96\xBD", "\xE2\x96\xBC", "\xE2\x84\xA2", "\xE2\x8A\xBF",
+ "\xE2\x84\xA2", nullptr},
+ /* "Τ", "τ","θ","△","▲","▽","▼","™","⊿", "™" */
+ {"U", "\xCE\xA5", "\xCF\x85", "\xCE\xBC", "\xE2\x88\xAA", "\xE2\x88\xA9",
+ nullptr},
+ /* "Υ", "υ","μ","∪", "∩" */
+ {"V", "\xCE\xBD", nullptr},
+ {"W", "\xE2\x84\xA6", "\xCF\x89", "\xE2\x94\xAC", "\xE2\x95\xA6",
+ "\xE2\x95\xA4", "\xE2\x95\xA5", nullptr},
+ /* "Ω", "ω", "┬", "╦", "╤", "╥" */
+ {"X", "\xCE\x9E", "\xCE\xBE", "\xE2\x94\xB4", "\xE2\x95\xA9",
+ "\xE2\x95\xA7", "\xE2\x95\xA8", nullptr},
+ /* "Ξ", "ξ", "┴", "╩", "╧", "╨" */
+ {"Y", "\xCE\xA8", nullptr},
+ /* "Ψ" */
+ {"Z", "\xCE\x96", "\xCE\xB6", "\xE2\x94\x94", "\xE2\x95\xB0",
+ "\xE2\x95\x9A", "\xE2\x95\x99", "\xE2\x95\x98", nullptr},
+ /* "Ζ", "ζ", "└", "╰", "╚", "╙", "╘" */
+ };
- for (size_t i = 0; i < FCITX_ARRAY_SIZE(symbolGroup); i++) {
- symbolToGroup_[symbolGroup[i][0]] = groups_.size();
+ for (size_t i = 0; i < FCITX_ARRAY_SIZE(symbolGroup); i++) {
+ symbolToGroup_[symbolGroup[i][0]] = groups_.size();
- std::vector items;
- std::vector items2;
- for (size_t j = 1; symbolGroup[i][j]; j++) {
- items.push_back(symbolGroup[i][j]);
- items2.push_back(symbolGroup[i][j]);
- symbolToGroup_[symbolGroup[i][j]] = groups_.size();
- if (j == 1) {
- items2.push_back(symbolGroup[i][0]);
- }
- }
- symbols_[symbolGroup[i][0]] = std::move(items2);
- groups_.push_back(std::move(items));
+ std::vector items;
+ std::vector items2;
+ for (size_t j = 1; symbolGroup[i][j]; j++) {
+ items.push_back(symbolGroup[i][j]);
+ items2.push_back(symbolGroup[i][j]);
+ symbolToGroup_[symbolGroup[i][j]] = groups_.size();
+ if (j == 1) {
+ items2.push_back(symbolGroup[i][0]);
+ }
}
+ symbols_[symbolGroup[i][0]] = std::move(items2);
+ groups_.push_back(std::move(items));
+ }
}
} // namespace fcitx
diff --git a/src/zhuyinsymbol.h b/src/zhuyinsymbol.h
index 3dcf40c..04dcb37 100644
--- a/src/zhuyinsymbol.h
+++ b/src/zhuyinsymbol.h
@@ -16,16 +16,16 @@ namespace fcitx {
class ZhuyinSymbol {
public:
- ZhuyinSymbol();
- void load(std::FILE *file);
- const std::vector &lookup(const std::string &key) const;
- void initBuiltin();
- void clear();
+ ZhuyinSymbol();
+ void load(std::FILE *file);
+ const std::vector &lookup(const std::string &key) const;
+ void initBuiltin();
+ void clear();
private:
- std::unordered_map> symbols_;
- std::unordered_map symbolToGroup_;
- std::vector> groups_;
+ std::unordered_map> symbols_;
+ std::unordered_map symbolToGroup_;
+ std::vector> groups_;
};
} // namespace fcitx
diff --git a/test/testzhuyinbuffer.cpp b/test/testzhuyinbuffer.cpp
index d5d169e..0c408b6 100644
--- a/test/testzhuyinbuffer.cpp
+++ b/test/testzhuyinbuffer.cpp
@@ -13,158 +13,157 @@ using namespace fcitx;
class TestZhuyinProvider : public ZhuyinProviderInterface {
public:
- TestZhuyinProvider() {
- context_.reset(
- zhuyin_init(TESTING_BINARY_DIR "/data", "/Invalid/Path"));
- zhuyin_set_options(context_.get(), USE_TONE | ZHUYIN_CORRECT_ALL |
- FORCE_TONE | DYNAMIC_ADJUST);
- zhuyin_set_chewing_scheme(context_.get(), ZHUYIN_STANDARD);
- }
+ TestZhuyinProvider() {
+ context_.reset(zhuyin_init(TESTING_BINARY_DIR "/data", "/Invalid/Path"));
+ zhuyin_set_options(context_.get(), USE_TONE | ZHUYIN_CORRECT_ALL |
+ FORCE_TONE | DYNAMIC_ADJUST);
+ zhuyin_set_chewing_scheme(context_.get(), ZHUYIN_STANDARD);
+ }
- zhuyin_context_t *context() override { return context_.get(); }
+ zhuyin_context_t *context() override { return context_.get(); }
- bool isZhuyin() const override { return true; }
- const ZhuyinSymbol &symbol() const override { return symbol_; }
+ bool isZhuyin() const override { return true; }
+ const ZhuyinSymbol &symbol() const override { return symbol_; }
private:
- ZhuyinSymbol symbol_;
- UniqueCPtr context_;
+ ZhuyinSymbol symbol_;
+ UniqueCPtr context_;
};
void test_basic() {
- TestZhuyinProvider provider;
- ZhuyinBuffer buffer(&provider);
- buffer.type('z');
- FCITX_INFO() << buffer.dump();
- buffer.type('p');
- FCITX_INFO() << buffer.dump();
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
+ TestZhuyinProvider provider;
+ ZhuyinBuffer buffer(&provider);
+ buffer.type('z');
+ FCITX_INFO() << buffer.dump();
+ buffer.type('p');
+ FCITX_INFO() << buffer.dump();
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
- buffer.backspace();
- FCITX_INFO() << buffer.dump();
+ buffer.backspace();
+ FCITX_INFO() << buffer.dump();
- buffer.reset();
+ buffer.reset();
- FCITX_INFO() << buffer.dump();
- buffer.type('z');
- buffer.type('\\');
- buffer.type('p');
- buffer.type('\\');
- buffer.type('p');
- buffer.type('a');
- FCITX_INFO() << buffer.dump();
+ FCITX_INFO() << buffer.dump();
+ buffer.type('z');
+ buffer.type('\\');
+ buffer.type('p');
+ buffer.type('\\');
+ buffer.type('p');
+ buffer.type('a');
+ FCITX_INFO() << buffer.dump();
- buffer.moveCursorLeft();
- buffer.type('b');
- buffer.type('c');
- FCITX_INFO() << buffer.dump();
- buffer.moveCursorLeft();
- buffer.moveCursorLeft();
- buffer.moveCursorLeft();
- buffer.moveCursorLeft();
- buffer.type('e');
- FCITX_INFO() << buffer.dump();
- buffer.moveCursorRight();
- buffer.type('e');
- FCITX_INFO() << buffer.dump();
- buffer.moveCursorLeft();
- buffer.del();
- FCITX_INFO() << buffer.dump();
- buffer.reset();
- buffer.type('z');
- buffer.type(0x263a);
- buffer.type('p');
- FCITX_INFO() << buffer.dump();
- buffer.backspace();
- buffer.backspace();
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
- buffer.reset();
- buffer.type('z');
- buffer.type('p');
- buffer.moveCursorLeft();
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
- buffer.moveCursorLeft();
- buffer.del();
- buffer.moveCursorRight();
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
- buffer.reset();
- buffer.type('z');
- buffer.type('p');
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
- buffer.type('z');
- buffer.type('p');
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
- buffer.moveCursorLeft();
- buffer.type('a');
- buffer.type('p');
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
- buffer.moveCursorRight();
- buffer.type('a');
- buffer.type('p');
- buffer.type(' ');
- FCITX_INFO() << buffer.dump();
- buffer.backspace();
- FCITX_INFO() << buffer.dump();
- buffer.backspace();
- FCITX_INFO() << buffer.dump();
- buffer.backspace();
- FCITX_INFO() << buffer.dump();
- buffer.backspace();
- FCITX_INFO() << buffer.dump();
- buffer.type('z');
- buffer.type('p');
- buffer.type(' ');
- buffer.type('z');
- buffer.type('p');
- buffer.type(' ');
- buffer.moveCursorToBeginning();
- FCITX_INFO() << buffer.dump();
- buffer.type('.');
- buffer.type('p');
- FCITX_INFO() << buffer.dump();
- buffer.backspace();
- FCITX_INFO() << buffer.dump();
- buffer.reset();
- buffer.type('z');
- buffer.type('p');
- buffer.type(' ');
- buffer.type('n');
- buffer.type('i');
- buffer.type('f');
- buffer.moveCursorToBeginning();
- buffer.moveCursorRight();
- buffer.del();
- FCITX_INFO() << buffer.dump();
+ buffer.moveCursorLeft();
+ buffer.type('b');
+ buffer.type('c');
+ FCITX_INFO() << buffer.dump();
+ buffer.moveCursorLeft();
+ buffer.moveCursorLeft();
+ buffer.moveCursorLeft();
+ buffer.moveCursorLeft();
+ buffer.type('e');
+ FCITX_INFO() << buffer.dump();
+ buffer.moveCursorRight();
+ buffer.type('e');
+ FCITX_INFO() << buffer.dump();
+ buffer.moveCursorLeft();
+ buffer.del();
+ FCITX_INFO() << buffer.dump();
+ buffer.reset();
+ buffer.type('z');
+ buffer.type(0x263a);
+ buffer.type('p');
+ FCITX_INFO() << buffer.dump();
+ buffer.backspace();
+ buffer.backspace();
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
+ buffer.reset();
+ buffer.type('z');
+ buffer.type('p');
+ buffer.moveCursorLeft();
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
+ buffer.moveCursorLeft();
+ buffer.del();
+ buffer.moveCursorRight();
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
+ buffer.reset();
+ buffer.type('z');
+ buffer.type('p');
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
+ buffer.type('z');
+ buffer.type('p');
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
+ buffer.moveCursorLeft();
+ buffer.type('a');
+ buffer.type('p');
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
+ buffer.moveCursorRight();
+ buffer.type('a');
+ buffer.type('p');
+ buffer.type(' ');
+ FCITX_INFO() << buffer.dump();
+ buffer.backspace();
+ FCITX_INFO() << buffer.dump();
+ buffer.backspace();
+ FCITX_INFO() << buffer.dump();
+ buffer.backspace();
+ FCITX_INFO() << buffer.dump();
+ buffer.backspace();
+ FCITX_INFO() << buffer.dump();
+ buffer.type('z');
+ buffer.type('p');
+ buffer.type(' ');
+ buffer.type('z');
+ buffer.type('p');
+ buffer.type(' ');
+ buffer.moveCursorToBeginning();
+ FCITX_INFO() << buffer.dump();
+ buffer.type('.');
+ buffer.type('p');
+ FCITX_INFO() << buffer.dump();
+ buffer.backspace();
+ FCITX_INFO() << buffer.dump();
+ buffer.reset();
+ buffer.type('z');
+ buffer.type('p');
+ buffer.type(' ');
+ buffer.type('n');
+ buffer.type('i');
+ buffer.type('f');
+ buffer.moveCursorToBeginning();
+ buffer.moveCursorRight();
+ buffer.del();
+ FCITX_INFO() << buffer.dump();
}
void test_candidate() {
- TestZhuyinProvider provider;
- ZhuyinBuffer buffer(&provider);
- auto printCandidate = [](std::unique_ptr candidate) {
- FCITX_INFO() << candidate->text().toString();
- };
- buffer.type('z');
- buffer.type('p');
- buffer.type(' ');
- buffer.type('a');
- buffer.type('p');
- buffer.type(' ');
- buffer.showCandidate(printCandidate);
- buffer.moveCursorLeft();
- buffer.showCandidate(printCandidate);
- buffer.moveCursorLeft();
- buffer.showCandidate(printCandidate);
+ TestZhuyinProvider provider;
+ ZhuyinBuffer buffer(&provider);
+ auto printCandidate = [](std::unique_ptr candidate) {
+ FCITX_INFO() << candidate->text().toString();
+ };
+ buffer.type('z');
+ buffer.type('p');
+ buffer.type(' ');
+ buffer.type('a');
+ buffer.type('p');
+ buffer.type(' ');
+ buffer.showCandidate(printCandidate);
+ buffer.moveCursorLeft();
+ buffer.showCandidate(printCandidate);
+ buffer.moveCursorLeft();
+ buffer.showCandidate(printCandidate);
}
int main() {
- test_basic();
- test_candidate();
- return 0;
+ test_basic();
+ test_candidate();
+ return 0;
}