From a2c9412461f68a5293cec24609076951e28a3b27 Mon Sep 17 00:00:00 2001
From: Anoop <46913894+anoopmsivadas@users.noreply.github.com>
Date: Tue, 9 Jul 2024 20:34:51 +0530
Subject: [PATCH] Enhancements and minor bug fixes (#8)
* Enhancements and minor bug fixes
* Closes #4.
* Closes #7.
* Handled word break characters properly.
* Added basic meson workflow.
* Use Ubuntu:22.04.
---
.github/workflows/meson_cpp.yml | 55 ++++
.gitignore | 7 +-
README.md | 14 +-
...t.Fcitx5.Addon.varnamfcitx.metainfo.xml.in | 19 ++
meson.build | 27 +-
meson.options | 3 +-
src/meson.build | 8 +-
src/varnam_candidate.cpp | 14 +-
src/varnam_config.h | 20 +-
src/varnam_engine.cpp | 14 +-
src/varnam_state.cpp | 294 ++++++++++--------
src/varnam_state.h | 13 +-
src/varnamfcitx-addon.conf | 9 -
src/varnamfcitx-addon.conf.in | 4 +-
14 files changed, 317 insertions(+), 184 deletions(-)
create mode 100644 .github/workflows/meson_cpp.yml
create mode 100644 com.varnamproject.Fcitx5.Addon.varnamfcitx.metainfo.xml.in
delete mode 100644 src/varnamfcitx-addon.conf
diff --git a/.github/workflows/meson_cpp.yml b/.github/workflows/meson_cpp.yml
new file mode 100644
index 0000000..82d28a4
--- /dev/null
+++ b/.github/workflows/meson_cpp.yml
@@ -0,0 +1,55 @@
+name: Meson Build and Test
+on:
+ push:
+ branches: [main]
+ paths:
+ - "**.cpp"
+ - "**.h"
+ - "**.build"
+ pull_request:
+ branches: [main]
+ paths:
+ - "**.cpp"
+ - "**.h"
+ - "**.build"
+
+jobs:
+ build:
+ name: Build and Test on ${{ matrix.os }} with Meson v${{ matrix.meson_version }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-22.04]
+ meson_version: ["1.4.1"]
+ steps:
+ - name: Set up Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: 1.16
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.x'
+ - name: Install Fcitx5 dev packages
+ run: sudo apt install -y fcitx5-modules-dev
+ - name: Build and install Varnam
+ run: |
+ cd ../
+ git clone https://github.com/varnamproject/govarnam.git govarnam
+ cd govarnam
+ make
+ sudo make install
+ - name: Install Meson
+ run: python -m pip install meson==${{ matrix.meson_version }} ninja
+ - name: Checkout code
+ uses: actions/checkout@v4
+ - name: Configure Project
+ run: meson setup builddir/
+ env:
+ CC: g++
+ - name: Run Build
+ run: |
+ cd builddir
+ meson compile
+ - name: Run Tests
+ run: meson test -C builddir/ -v
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 08c50f7..9e867ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,12 @@ builddir/
*.o
*.a
+**/varnamfcitx-addon.conf
**/CMakeLists.txt
**/CMakeCache.txt
CMakeFiles/
-meson_options.txt
\ No newline at end of file
+meson_options.txt
+
+compile_commands.json
+.cache/
+.vscode/
\ No newline at end of file
diff --git a/README.md b/README.md
index b42a7b6..3e2d968 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,12 @@ A wrapper to add Varnam Input Method Engine support in Fcitx5 Input Method.
Install `fcitx5-modules-dev` if you're building it on a debian based distribution.
-## Build & Install
+## Installation
+
+### Build & Install
+
+> [!IMPORTANT]
+> Please Uninstall the older version first, to avoid conflicts.
```bash
git clone https://github.com/varnamproject/varnam-fcitx5.git
@@ -43,12 +48,17 @@ If meson version is less than `1.1` run the following command before `meson setu
mv meson.options meson_options.txt
```
-## Uninstall
+
+### Uninstall
```
cd buildir
sudo ninja uninstall
```
+---
+
+[![Packaging status](https://repology.org/badge/vertical-allrepos/varnam-fcitx5.svg)](https://repology.org/project/varnam-fcitx5/versions)
+* Thank you [@mohammedbilalns](https://github.com/mohammedbilalns) for the Arch Linux Package([AUR](https://aur.archlinux.org/packages/varnam-fcitx5-git))
## Configuration
Varnam Fcitx can be configured using `fcitx5-configtool`. Please refer the [official documentation](https://fcitx-im.org/wiki/Configtool_(Fcitx_5)).
diff --git a/com.varnamproject.Fcitx5.Addon.varnamfcitx.metainfo.xml.in b/com.varnamproject.Fcitx5.Addon.varnamfcitx.metainfo.xml.in
new file mode 100644
index 0000000..be3d048
--- /dev/null
+++ b/com.varnamproject.Fcitx5.Addon.varnamfcitx.metainfo.xml.in
@@ -0,0 +1,19 @@
+
+
+ com.varnamproject.Fcitx5.Addon.varnamfcitx
+ org.fcitx.Fcitx5
+ CC0-1.0
+ GPL-3.0+
+ Varnam Fcitx5
+ Varnam Engine for Fcitx5
+
+ The Varnam Project
+
+ https://varnamproject.com/
+ https://github.com/varnamproject/varnam-fcitx5/issues
+ https://github.com/varnamproject/varnam-fcitx5
+ Fcitx
+
+
+
+
\ No newline at end of file
diff --git a/meson.build b/meson.build
index 0f81489..1a2ef28 100644
--- a/meson.build
+++ b/meson.build
@@ -28,19 +28,30 @@ else
lib_dir = get_option('libdir')
endif
-if (fs.exists('/usr/local/share/fcitx5/inputmethod'))
- data_dir = '/usr/local/share'
-elif (fs.exists('/usr/share/fcitx5/inputmethod'))
- data_dir = '/usr/share/'
-else
- data_dir = get_option('datadir')
-endif
+data_dir = get_option('datadir')
if get_option('varnam_debug')
add_global_arguments('-DDEBUG_MODE', language: 'cpp')
endif
+config_data = configuration_data()
+if (get_option('version') != '')
+ config_data.set('version', get_option('version'))
+elif (run_command('git', 'describe', check: false).stdout().strip() == '')
+ config_data.set('version', meson.project_version())
+else
+ git_tag = run_command('git', 'describe', '--always', '--dirty', check: false).stdout().strip()
+ config_data.set('version', git_tag.strip('v'))
+endif
+
# source
subdir('src')
# icons
-subdir('icons')
\ No newline at end of file
+subdir('icons')
+
+# install AppStream Metadata file
+install_data(
+ 'com.varnamproject.Fcitx5.Addon.varnamfcitx.metainfo.xml.in',
+ rename: 'com.varnamproject.Fcitx5.Addon.varnamfcitx.metainfo.xml',
+ install_dir: data_dir + '/metainfo',
+)
\ No newline at end of file
diff --git a/meson.options b/meson.options
index 7f46fa4..507eafe 100644
--- a/meson.options
+++ b/meson.options
@@ -1 +1,2 @@
-option('varnam_debug', type: 'boolean', value: false)
\ No newline at end of file
+option('varnam_debug', type: 'boolean', value: false)
+option('version', type: 'string', value: '')
\ No newline at end of file
diff --git a/src/meson.build b/src/meson.build
index bc1e683..db60f47 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -12,7 +12,6 @@ shared_library(
dependencies: [fcitx5_core_dep, fcitx5_module_dep, varnam_dep],
install: true,
install_dir: lib_dir + '/fcitx5',
- name_prefix: '',
)
# Input Method registration file
@@ -22,8 +21,9 @@ install_data(
)
# Addon config file
-install_data(
- 'varnamfcitx-addon.conf.in',
- rename: 'varnamfcitx.conf',
+configure_file(
+ configuration: config_data,
+ input: 'varnamfcitx-addon.conf.in',
+ output: 'varnamfcitx.conf',
install_dir: data_dir + '/fcitx5/addon',
)
\ No newline at end of file
diff --git a/src/varnam_candidate.cpp b/src/varnam_candidate.cpp
index a20e555..a8f7ddb 100644
--- a/src/varnam_candidate.cpp
+++ b/src/varnam_candidate.cpp
@@ -1,5 +1,4 @@
#include "varnam_candidate.h"
-#include "varnam_utils.h"
#include "varnam_config.h"
#include "varnam_state.h"
@@ -20,12 +19,15 @@ VarnamCandidateList::VarnamCandidateList(VarnamEngine *engine, InputContext *ic)
: engine_(engine), ic_(ic) {
const VarnamEngineConfig *config =
static_cast(engine_->getConfig());
+ CandidateLayoutHint layout;
if (!config) {
VARNAM_WARN() << "Invalid configuration";
- throw std::runtime_error("invalid config");
+ layout = CandidateLayoutHint::Vertical;
+ } else {
+ layout = config->candidateLayout.value();
}
setPageable(this);
- setLayoutHint(config->candidateLayout.value());
+ setLayoutHint(layout);
}
void VarnamCandidateList::prev() {
@@ -55,8 +57,9 @@ void VarnamCandidateList::prevCandidate() {
if (index >= pageSize() && (currentPage() > 0)) {
setPage(currentPage());
}
- state->selectCandidate(cursorIndex());
setGlobalCursorIndex(index);
+ state->selectCandidate(cursorIndex());
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
}
void VarnamCandidateList::nextCandidate() {
@@ -66,8 +69,9 @@ void VarnamCandidateList::nextCandidate() {
if (index >= pageSize() && (currentPage() < totalPages())) {
setPage(currentPage());
}
- state->selectCandidate(cursorIndex());
setGlobalCursorIndex(index);
+ state->selectCandidate(cursorIndex());
+ ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
}
} // namespace fcitx
\ No newline at end of file
diff --git a/src/varnam_config.h b/src/varnam_config.h
index eb59d53..b8a903d 100644
--- a/src/varnam_config.h
+++ b/src/varnam_config.h
@@ -29,14 +29,13 @@ FCITX_CONFIGURATION(
IntConstrain(3, 10)};
// Enable Learning Words on commit
- Option shouldLearnWords{this, "Learn Words",
- _("Enable Learning New Words"), true};
-
+ Option shouldLearnWords{this, "Learn Words", _("Learn New Words"),
+ true};
// Strictly Follow Schema
Option strictlyFollowScheme{
this, "Strictly Follow Scheme",
_("Strictly Follow Scheme For Dictionary Results"), false};
-
+
// Dictionary Suggestions Limit
Option dictionarySuggestionsLimit{
this, "Dictionary Suggestions Limit", _("Dictionary Suggestions Limit"),
@@ -57,7 +56,7 @@ FCITX_CONFIGURATION(
this,
"PrevCandidate",
_("Previous Candidate"),
- {Key("Alt+Up")},
+ {Key("Up")},
KeyListConstrain(KeyConstrainFlag::AllowModifierLess)};
// Next Candidate Shortcut
@@ -65,7 +64,7 @@ FCITX_CONFIGURATION(
this,
"NextCandidate",
_("Next Candidate"),
- {Key("Alt+Down")},
+ {Key("Down")},
KeyListConstrain(KeyConstrainFlag::AllowModifierLess)};
// Previous Page
@@ -73,17 +72,16 @@ FCITX_CONFIGURATION(
this,
"PrevPage",
_("Previous Page"),
- {Key("Alt+Left")},
- KeyListConstrain(KeyConstrainFlag::AllowModifierLess)};
+ {Key("Alt+Up")},
+ KeyListConstrain(KeyConstrainFlag::AllowModifierOnly)};
// Next Page
KeyListOption nextPage{
this,
"NextPage",
_("Next Page"),
- {Key("Alt+Right")},
- KeyListConstrain(KeyConstrainFlag::AllowModifierLess)};
-);
+ {Key("Alt+Down")},
+ KeyListConstrain(KeyConstrainFlag::AllowModifierOnly)};);
} // namespace fcitx
#endif
\ No newline at end of file
diff --git a/src/varnam_engine.cpp b/src/varnam_engine.cpp
index 16b387b..f0110cb 100644
--- a/src/varnam_engine.cpp
+++ b/src/varnam_engine.cpp
@@ -4,6 +4,7 @@
#include
#include
+#include
extern "C" {
#include
@@ -14,7 +15,6 @@ namespace fcitx {
VarnamEngine::VarnamEngine(Instance *instance)
: instance_(instance),
factory_([this](InputContext &ic) { return new VarnamState(this, ic); }) {
- reloadConfig();
instance->inputContextManager().registerProperty("varnamState", &factory_);
}
@@ -30,6 +30,8 @@ VarnamEngine::~VarnamEngine() {
void VarnamEngine::activate(const InputMethodEntry &entry,
InputContextEvent &contextEvent) {
+ FCITX_UNUSED(contextEvent);
+ reloadConfig();
#ifdef DEBUG_MODE
VARNAM_INFO() << "activate scheme:" << entry.uniqueName();
#endif
@@ -39,7 +41,7 @@ void VarnamEngine::activate(const InputMethodEntry &entry,
VARNAM_WARN() << "Failed to initialize Varnam";
throw std::runtime_error("failed to initialize varnam");
}
-
+
varnam_config(varnam_handle, VARNAM_CONFIG_SET_DICTIONARY_MATCH_EXACT,
config_.strictlyFollowScheme.value());
varnam_config(varnam_handle, VARNAM_CONFIG_SET_DICTIONARY_SUGGESTIONS_LIMIT,
@@ -59,7 +61,7 @@ void VarnamEngine::deactivate(const InputMethodEntry &entry,
if (event.type() == EventType::InputContextSwitchInputMethod) {
auto ic = event.inputContext();
auto state = ic->propertyFor(&factory_);
- state->commitPreedit();
+ state->commitText();
state->updateUI();
}
reset(entry, event);
@@ -117,11 +119,9 @@ void VarnamEngine::reset(const InputMethodEntry &entry,
InputContextEvent &event) {
FCITX_UNUSED(entry);
auto ic = event.inputContext();
- auto state = event.inputContext()->propertyFor(&factory_);
+ auto state = ic->propertyFor(&factory_);
state->reset();
- ic->inputPanel().reset();
- ic->updatePreedit();
- ic->updateUserInterface(UserInterfaceComponent::InputPanel);
+ state->updateUI();
}
void VarnamEngine::setConfig(const RawConfig &config) {
diff --git a/src/varnam_state.cpp b/src/varnam_state.cpp
index c8c15be..1034e7b 100644
--- a/src/varnam_state.cpp
+++ b/src/varnam_state.cpp
@@ -3,13 +3,15 @@
#include "varnam_engine.h"
#include "varnam_utils.h"
-#include
+#include
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -17,11 +19,11 @@
namespace fcitx {
VarnamState::VarnamState(VarnamEngine *engine, InputContext &ic)
- : engine_(engine), ic_(&ic) {
+ : ic_(&ic), engine_(engine) {
result_ = nullptr;
- cursor = 0;
- bufferPos = 0;
- utfCharPos = 0;
+ cursor = std::numeric_limits::max();
+ candidateSelected = 0;
+ lastTypedCharIsDigit = false;
}
VarnamState::~VarnamState() {
@@ -41,8 +43,8 @@ std::string VarnamState::bufferToString() {
}
void VarnamState::updatePreeditCursor() {
- if (preedit_.textLength() < cursor) {
- return;
+ if (cursor > preedit_.textLength()) {
+ cursor = preedit_.textLength();
}
preedit_.setCursor(cursor);
if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) {
@@ -83,16 +85,13 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) {
}
// handle candidate selection through index key
- if (!buffer_.empty() && key.isDigit()) {
- if (auto candidateList = ic_->inputPanel().candidateList();
- candidateList && candidateList->size()) {
- auto idx = key.keyListIndex(selectionKeys);
- if (idx >= 0 && idx < candidateList->size()) {
- selectCandidate(idx);
- }
- keyEvent.filterAndAccept();
- return;
- }
+ if (!buffer_.empty() && key.isDigit() && !lastTypedCharIsDigit) {
+ auto idx = key.keyListIndex(selectionKeys);
+ selectCandidate(idx);
+ commitText(key.sym());
+ updateUI();
+ keyEvent.filterAndAccept();
+ return;
}
if (key.states().test(KeyState::Ctrl)) {
@@ -101,18 +100,23 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) {
return;
}
if (key.sym() == FcitxKey_Delete) {
- if (preedit_.empty()) {
+ auto candidates = ic_->inputPanel().candidateList();
+ std::string wordToUnlearn(
+ candidates->candidate(candidateSelected)
+ .text()
+ .toStringForCommit()); // TODO try unique_ptr
+ if (wordToUnlearn.empty()) {
keyEvent.filter();
return;
}
#ifdef DEBUG_MODE
- VARNAM_INFO() << "unlearn word:" << preedit_.toString();
+ VARNAM_INFO() << "unlearn word:" << wordToUnlearn;
#endif
- std::string wordToUnlearn(
- preedit_.toStringForCommit()); // [TODO] try unique_ptr
std::thread unlearnThread(varnam_unlearn_word, engine_->getVarnamHandle(),
std::move(wordToUnlearn));
unlearnThread.detach();
+ reset();
+ updateUI();
keyEvent.filterAndAccept();
return;
}
@@ -120,27 +124,47 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) {
return;
}
if (key.checkKeyList(engine_->getConfig()->nextCandidate.value())) {
+ if (buffer_.empty()) {
+ keyEvent.filter();
+ return;
+ }
updateLookupTable(NEXT_CANDIDATE);
keyEvent.filterAndAccept();
return;
}
if (key.checkKeyList(engine_->getConfig()->prevCandidate.value())) {
+ if (buffer_.empty()) {
+ keyEvent.filter();
+ return;
+ }
updateLookupTable(PREV_CANDIDATE);
keyEvent.filterAndAccept();
return;
}
if (key.checkKeyList(engine_->getConfig()->nextPage.value())) {
+ if (buffer_.empty()) {
+ keyEvent.filter();
+ return;
+ }
updateLookupTable(NEXT_PAGE);
keyEvent.filterAndAccept();
return;
}
if (key.checkKeyList(engine_->getConfig()->prevPage.value())) {
+ if (buffer_.empty()) {
+ keyEvent.filter();
+ return;
+ }
updateLookupTable(PREV_PAGE);
keyEvent.filterAndAccept();
return;
}
+ auto iterator = buffer_.begin();
+ iterator += cursor;
+
switch (key.sym()) {
+ case FcitxKey_Escape:
case FcitxKey_space:
case FcitxKey_Tab:
case FcitxKey_Return:
@@ -148,59 +172,28 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) {
keyEvent.filter();
return;
}
- commitPreedit(key.sym());
- updateUI();
- keyEvent.filterAndAccept();
- return;
- case FcitxKey_Escape:
- commitPreedit();
+ commitText(key.sym());
updateUI();
keyEvent.filterAndAccept();
return;
- case FcitxKey_Left: // [TODO] move cursor left
+ case FcitxKey_Left:
if (preedit_.empty()) {
keyEvent.filter();
return;
}
if (cursor > 0) {
- unsigned int offset = getNumOfUTFCharUnits(u32_preedit[utfCharPos]);
- if (cursor >= offset) {
- cursor -= offset;
- }
- if (bufferPos > 0) {
- --bufferPos;
- }
- if (utfCharPos > 0) {
- --utfCharPos;
- }
-#ifdef DEBUG_MODE
- VARNAM_INFO() << "[left] cursor at:" << cursor
- << " buffer pos:" << bufferPos
- << " preedit cursor: " << utfCharPos;
-#endif
+ --cursor;
}
updatePreeditCursor();
keyEvent.filterAndAccept();
return;
- case FcitxKey_Right: //[TODO] move cursor right
+ case FcitxKey_Right:
if (preedit_.empty()) {
keyEvent.filter();
return;
}
- if (bufferPos < (buffer_.size() - 1)) {
- ++bufferPos;
- }
- if (utfCharPos < (u32_preedit.size() - 1)) {
- ++utfCharPos;
- }
- if (cursor < preedit_.textLength()) {
-
- cursor += getNumOfUTFCharUnits(u32_preedit[utfCharPos]);
-#ifdef DEBUG_MODE
- VARNAM_INFO() << "[right] cursor at:" << cursor
- << " buffer pos:" << bufferPos
- << " preedit cursor: " << utfCharPos;
-#endif
+ if (cursor < (buffer_.size())) {
+ ++cursor;
}
updatePreeditCursor();
keyEvent.filterAndAccept();
@@ -214,28 +207,59 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) {
keyEvent.filter();
return;
}
- // [TODO] use cursor position to remove elements
- buffer_.pop_back();
+ if (cursor > 0) {
+ buffer_.erase(--iterator);
+ --cursor;
+ }
getVarnamResult();
updateUI();
keyEvent.filterAndAccept();
return;
case FcitxKey_Delete:
- keyEvent.filter();
+ if (buffer_.empty()) {
+ keyEvent.filter();
+ return;
+ }
+ if (cursor < buffer_.size()) {
+ buffer_.erase(iterator);
+ }
+ getVarnamResult();
+ updateUI();
+ keyEvent.filterAndAccept();
return;
case FcitxKey_Home:
- keyEvent.filter();
+ if (buffer_.empty()) {
+ keyEvent.filter();
+ return;
+ }
+ cursor = 0;
+ updatePreeditCursor();
+ keyEvent.filterAndAccept();
return;
case FcitxKey_End:
- keyEvent.filter();
+ if (buffer_.empty()) {
+ keyEvent.filter();
+ return;
+ }
+ cursor = preedit_.textLength();
+ updatePreeditCursor();
+ keyEvent.filterAndAccept();
return;
default:
break;
}
- if (result_) {
- varray_clear(result_);
+
+ if (key.isDigit()) {
+ lastTypedCharIsDigit = true;
} else {
- result_ = varray_init();
+ lastTypedCharIsDigit = false;
+ }
+
+ if (isWordBreak(keyEvent.key().sym())) {
+ commitText(keyEvent.key().sym());
+ updateUI();
+ keyEvent.filterAndAccept();
+ return;
}
if (key.sym() > 0x80) {
@@ -246,22 +270,23 @@ void VarnamState::processKeyEvent(KeyEvent &keyEvent) {
unsigned char input =
*(keyEvent.key().toString(KeyStringFormat::Localized).c_str());
#ifdef DEBUG_MODE
- VARNAM_INFO() << "cursor at:" << cursor << " buffer pos:" << bufferPos
- << " buf size:" << buffer_.size();
+ VARNAM_INFO() << "cursor at:" << cursor;
#endif
- auto iterator = buffer_.begin();
- iterator += bufferPos;
- if (bufferPos >= buffer_.size()) {
+ if (cursor >= buffer_.size()) {
buffer_.push_back(input);
- ++bufferPos;
+ cursor = buffer_.size();
} else {
buffer_.insert(iterator, input);
- ++bufferPos;
+ ++cursor;
}
- getVarnamResult();
- if (isWordBreak(keyEvent.key().sym())) {
- commitPreedit(keyEvent.key().sym());
+
+ if (result_) {
+ varray_clear(result_);
+ } else {
+ result_ = varray_init();
}
+
+ getVarnamResult();
updateUI();
keyEvent.filterAndAccept();
}
@@ -270,21 +295,33 @@ void VarnamState::setLookupTable() {
if (!result_) {
return;
}
- auto candidates_p = std::make_unique(engine_, ic_);
- candidates_p->setSelectionKey(selectionKeys);
- candidates_p->setCursorPositionAfterPaging(
+ auto candidates = std::make_unique(engine_, ic_);
+ candidates->setSelectionKey(selectionKeys);
+ candidates->setCursorPositionAfterPaging(
CursorPositionAfterPaging::ResetToFirst);
- candidates_p->setPageSize(engine_->getConfig()->pageSize.value());
+ candidates->setPageSize(engine_->getConfig()->pageSize.value());
+
int count = varray_length(result_);
+ char preeditAppended = 0;
for (int i = 0; i < count; i++) {
+ if ((candidates->pageSize() == 10) &&
+ ((i + (preeditAppended ? (1 + preeditAppended) : 1)) % 10 == 0)) {
+ // TODO ;}
+ candidates->append(engine_,
+ preedit_.toString().c_str(), i);
+ ++preeditAppended;
+ }
vword *word = static_cast(varray_get(result_, i));
- candidates_p->append(engine_, word->text, i);
+ candidates->append(engine_, word->text,
+ preeditAppended ? i + 1 : i);
+ }
+ if (!preeditAppended) {
+ candidates->append(
+ engine_, preedit_.toString().c_str(), ++count);
}
- std::string userInput = bufferToString();
- candidates_p->append(engine_, userInput.c_str(), count);
if (count) {
- candidates_p->setGlobalCursorIndex(0);
- ic_->inputPanel().setCandidateList(std::move(candidates_p));
+ candidates->setGlobalCursorIndex(0);
+ ic_->inputPanel().setCandidateList(std::move(candidates));
}
}
@@ -320,35 +357,35 @@ void VarnamState::selectCandidate(int index) {
if (!candidateList_ || candidateList_->size() <= index) {
return;
}
- const Text *candidate_ = &candidateList_->candidate(index).text();
- if (candidate_ == nullptr || candidate_->empty()) {
- return;
- }
- preedit_.clear();
- preedit_.append(candidate_->toString(), TextFormatFlag::HighLight);
- preedit_.setCursor(preedit_.textLength());
- if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) {
- ic_->inputPanel().setClientPreedit(preedit_);
+ if (index == 9) {
+ candidateSelected = 0;
} else {
- ic_->inputPanel().setPreedit(preedit_);
+ if (candidateList_->size() <= index) {
+ return;
+ }
+ candidateSelected = index;
}
- ic_->updatePreedit();
- ic_->updateUserInterface(UserInterfaceComponent::InputPanel);
}
-void VarnamState::commitPreedit(const FcitxKeySym &key) {
+void VarnamState::commitText(const FcitxKeySym &key) {
+ auto candidates = ic_->inputPanel().candidateList();
std::string stringToCommit;
- stringToCommit.assign(preedit_.toStringForCommit());
- if (!stringToCommit.empty() &&
- engine_->getConfig()->shouldLearnWords.value()) {
-#ifdef DEBUG_MODE
- VARNAM_INFO() << "learn word:" << preedit_.toString();
-#endif
- std::string wordToLearn(
- preedit_.toStringForCommit()); // [TODO] try unique_ptr
- std::thread learnThread(varnam_learn_word, engine_->getVarnamHandle(),
- std::move(wordToLearn), 0);
- learnThread.detach();
+
+ if (key == FcitxKey_Escape || key == FcitxKey_0 || candidates == nullptr ||
+ candidates->size() <= 1 || result_ == nullptr ||
+ varray_is_empty(result_) || lastTypedCharIsDigit) {
+
+ stringToCommit.assign(preedit_.toStringForCommit());
+ candidateSelected = 0;
+ } else if ((candidates->cursorIndex() <= 0) && !candidateSelected) {
+ vword *first_result = static_cast(varray_get(result_, 0));
+ if (first_result != nullptr) {
+ stringToCommit.assign(first_result->text);
+ candidateSelected = 1;
+ }
+ } else {
+ stringToCommit.assign(
+ candidates->candidate(candidateSelected).text().toStringForCommit());
}
if (isWordBreak(key)) {
@@ -359,11 +396,24 @@ void VarnamState::commitPreedit(const FcitxKeySym &key) {
<< getWordBreakChar(key);
#endif
ic_->commitString(stringToCommit);
+
+ if (stringToCommit.empty() || lastTypedCharIsDigit ||
+ ic_->capabilityFlags().test(CapabilityFlag::PasswordOrSensitive) ||
+ !engine_->getConfig()->shouldLearnWords.value() || !candidateSelected) {
+ reset();
+ return;
+ }
+#ifdef DEBUG_MODE
+ VARNAM_INFO() << "learn word:" << stringToCommit;
+#endif
+ std::string wordToLearn(stringToCommit); // [TODO] try unique_ptr
+ std::thread learnThread(varnam_learn_word, engine_->getVarnamHandle(),
+ std::move(wordToLearn), 0);
+ learnThread.detach();
reset();
}
void VarnamState::updateUI() {
- vword *first_res = nullptr;
ic_->inputPanel().reset();
if (buffer_.empty()) {
ic_->updatePreedit();
@@ -376,20 +426,12 @@ void VarnamState::updateUI() {
if (varray_length(result_) == 0x00) {
return;
}
- first_res = static_cast(varray_get(result_, 0));
- if (first_res == nullptr) {
- return;
- }
- std::string preedit_res(first_res->text);
- if (preedit_res.empty()) {
- return;
- }
- u32_preedit.clear();
- u32_preedit.assign(utf8_converter.from_bytes(preedit_res.c_str()));
- cursor = preedit_res.length();
- utfCharPos = u32_preedit.length() - 1;
+
preedit_.clear();
- preedit_.append(preedit_res, TextFormatFlag::HighLight);
+ preedit_.append(bufferToString(), TextFormatFlag::HighLight);
+ if (cursor > preedit_.textLength()) {
+ cursor = preedit_.textLength();
+ }
preedit_.setCursor(cursor);
if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) {
@@ -403,9 +445,9 @@ void VarnamState::updateUI() {
}
void VarnamState::reset() {
- cursor = 0;
- bufferPos = 0;
- utfCharPos = 0;
+ cursor = std::numeric_limits::max();
+ candidateSelected = 0;
+ lastTypedCharIsDigit = false;
buffer_.clear();
preedit_.clear();
if (result_) {
diff --git a/src/varnam_state.h b/src/varnam_state.h
index ac13048..0304270 100644
--- a/src/varnam_state.h
+++ b/src/varnam_state.h
@@ -3,7 +3,6 @@
#include "varnam_candidate.h"
-#include
#include
#include
@@ -20,14 +19,12 @@ class VarnamState : public InputContextProperty {
private:
// Private Variables
unsigned int cursor;
- unsigned int bufferPos;
- unsigned int utfCharPos;
+ char candidateSelected;
+ bool lastTypedCharIsDigit;
InputContext *ic_;
VarnamEngine *engine_;
Text preedit_;
- std::u32string u32_preedit;
- std::wstring_convert, char32_t> utf8_converter;
std::vector buffer_;
varray *result_;
@@ -51,8 +48,8 @@ class VarnamState : public InputContextProperty {
// Handle KeyEvents
void processKeyEvent(KeyEvent &);
- // Commit Preedit to text
- void commitPreedit(const FcitxKeySym &key = FcitxKey_None);
+ // Commit Selected Candidate to text
+ void commitText(const FcitxKeySym &key = FcitxKey_None);
// Generate Candidate List/Lookup tables
void setLookupTable();
@@ -71,4 +68,4 @@ class VarnamState : public InputContextProperty {
};
} // namespace fcitx
-#endif
\ No newline at end of file
+#endif // end of _FCITX5_VARNAM_STATE_H
\ No newline at end of file
diff --git a/src/varnamfcitx-addon.conf b/src/varnamfcitx-addon.conf
deleted file mode 100644
index ffe7281..0000000
--- a/src/varnamfcitx-addon.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-[Addon]
-Name=Varnam
-Comment=Varnam Engine for Fcitx5
-Category=InputMethod
-Version=0.0.1
-Library=varnamfcitx
-Type=SharedLibrary
-Configurable=True
-Enabled=True
diff --git a/src/varnamfcitx-addon.conf.in b/src/varnamfcitx-addon.conf.in
index 65a9b35..e6ae9c0 100644
--- a/src/varnamfcitx-addon.conf.in
+++ b/src/varnamfcitx-addon.conf.in
@@ -2,8 +2,8 @@
Name=Varnam
Comment=Varnam Engine for Fcitx5
Category=InputMethod
-Version=0.0.1
-Library=varnamfcitx
+Version=@version@
+Library=libvarnamfcitx
Type=SharedLibrary
Configurable=True
Enabled=True
\ No newline at end of file