Skip to content

Commit

Permalink
Use candidate comment in quick phrase candidate and add provider v2.
Browse files Browse the repository at this point in the history
  • Loading branch information
wengxt committed Jun 17, 2024
1 parent 51c37e7 commit 57f7769
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 31 deletions.
34 changes: 29 additions & 5 deletions src/modules/quickphrase/quickphrase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,30 @@
*/
#include "quickphrase.h"

#include <array>
#include <memory>
#include <string>
#include <utility>
#include "fcitx-config/iniparser.h"
#include "fcitx-utils/capabilityflags.h"
#include "fcitx-utils/handlertable.h"
#include "fcitx-utils/i18n.h"
#include "fcitx-utils/inputbuffer.h"
#include "fcitx-utils/key.h"
#include "fcitx-utils/keysym.h"
#include "fcitx-utils/textformatflags.h"
#include "fcitx/addonfactory.h"
#include "fcitx/addoninstance.h"
#include "fcitx/addonmanager.h"
#include "fcitx/candidatelist.h"
#include "fcitx/event.h"
#include "fcitx/inputcontextmanager.h"
#include "fcitx/inputpanel.h"
#include "fcitx/instance.h"
#include "fcitx/text.h"
#include "fcitx/userinterface.h"
#include "quickphrase_public.h"
#include "quickphraseprovider.h"

namespace fcitx {

Expand Down Expand Up @@ -326,9 +341,12 @@ class QuickPhraseCandidateWord : public CandidateWord {
public:
QuickPhraseCandidateWord(QuickPhrase *q, std::string commit,
const std::string &display,
const std::string &comment,
QuickPhraseAction action)
: CandidateWord(Text(display)), q_(q), commit_(std::move(commit)),
action_(action) {}
action_(action) {
setComment(Text(comment));
}

void select(InputContext *inputContext) const override {
auto *state = inputContext->propertyFor(&q_->factory());
Expand Down Expand Up @@ -412,9 +430,9 @@ void QuickPhrase::updateUI(InputContext *inputContext) {
if (!provider->populate(
inputContext, state->buffer_.userInput(),
[this, &candidateList, &selectionKeyAction, &autoCommit,
&autoCommitSet](const std::string &word,
const std::string &aux,
QuickPhraseAction action) {
&autoCommitSet](
const std::string &word, const std::string &aux,
const std::string &comment, QuickPhraseAction action) {
if (!autoCommitSet &&
action == QuickPhraseAction::AutoCommit) {
autoCommit = word;
Expand All @@ -426,7 +444,7 @@ void QuickPhrase::updateUI(InputContext *inputContext) {
}
if (!word.empty()) {
candidateList->append<QuickPhraseCandidateWord>(
this, word, aux, action);
this, word, aux, comment, action);
} else {
if (action == QuickPhraseAction::DigitSelection ||
action == QuickPhraseAction::AlphaSelection ||
Expand Down Expand Up @@ -485,11 +503,17 @@ void QuickPhrase::reloadConfig() {
builtinProvider_.reloadConfig();
readAsIni(config_, "conf/quickphrase.conf");
}

std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallback>>
QuickPhrase::addProvider(QuickPhraseProviderCallback callback) {
return callbackProvider_.addCallback(std::move(callback));
}

std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallbackV2>>
QuickPhrase::addProviderV2(QuickPhraseProviderCallbackV2 callback) {
return callbackProvider_.addCallback(std::move(callback));
}

void QuickPhrase::trigger(InputContext *ic, const std::string &text,
const std::string &prefix, const std::string &str,
const std::string &alt, const Key &key) {
Expand Down
10 changes: 10 additions & 0 deletions src/modules/quickphrase/quickphrase.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
#ifndef _FCITX_MODULES_QUICKPHRASE_QUICKPHRASE_H_
#define _FCITX_MODULES_QUICKPHRASE_QUICKPHRASE_H_

#include <memory>
#include <string>
#include <vector>
#include "fcitx-config/configuration.h"
#include "fcitx-config/enum.h"
#include "fcitx-config/iniparser.h"
#include "fcitx-config/option.h"
#include "fcitx-config/rawconfig.h"
#include "fcitx-utils/handlertable.h"
#include "fcitx-utils/i18n.h"
#include "fcitx-utils/key.h"
#include "fcitx/addoninstance.h"
Expand Down Expand Up @@ -76,9 +82,13 @@ class QuickPhrase final : public AddonInstance {
std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallback>>
addProvider(QuickPhraseProviderCallback);

std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallbackV2>>
addProviderV2(QuickPhraseProviderCallbackV2);

private:
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, trigger);
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, addProvider);
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, addProviderV2);
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, setBuffer);

void setSelectionKeys(QuickPhraseAction action);
Expand Down
14 changes: 14 additions & 0 deletions src/modules/quickphrase/quickphrase_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#define _FCITX_MODULES_QUICKPHRASE_QUICKPHRASE_PUBLIC_H_

#include <functional>
#include <memory>
#include <string>
#include <fcitx-utils/handlertable.h>
#include <fcitx-utils/key.h>
#include <fcitx-utils/metastring.h>
#include <fcitx/addoninstance.h>
Expand All @@ -32,6 +34,13 @@ using QuickPhraseProviderCallback =
std::function<bool(InputContext *ic, const std::string &,
const QuickPhraseAddCandidateCallback &)>;

using QuickPhraseAddCandidateCallbackV2 =
std::function<void(const std::string &, const std::string &,
const std::string &, QuickPhraseAction action)>;
using QuickPhraseProviderCallbackV2 =
std::function<bool(InputContext *ic, const std::string &,
const QuickPhraseAddCandidateCallbackV2 &)>;

} // namespace fcitx

/// Trigger quickphrase, with following format:
Expand All @@ -49,4 +58,9 @@ FCITX_ADDON_DECLARE_FUNCTION(
std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallback>>(
QuickPhraseProviderCallback));

FCITX_ADDON_DECLARE_FUNCTION(
QuickPhrase, addProviderV2,
std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallbackV2>>(
QuickPhraseProviderCallbackV2));

#endif // _FCITX_MODULES_QUICKPHRASE_QUICKPHRASE_PUBLIC_H_
24 changes: 16 additions & 8 deletions src/modules/quickphrase/quickphraseprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,15 @@ namespace fcitx {

bool BuiltInQuickPhraseProvider::populate(
InputContext *, const std::string &userInput,
const QuickPhraseAddCandidateCallback &addCandidate) {
const QuickPhraseAddCandidateCallbackV2 &addCandidate) {
auto start = map_.lower_bound(userInput);
auto end = map_.end();

for (; start != end; start++) {
if (!stringutils::startsWith(start->first, userInput)) {
break;
}
addCandidate(start->second,
stringutils::concat(start->second, " ",
start->first.substr(userInput.size())),
addCandidate(start->second, start->second, start->first,
QuickPhraseAction::Commit);
}
return true;
Expand Down Expand Up @@ -106,7 +104,7 @@ SpellQuickPhraseProvider::SpellQuickPhraseProvider(QuickPhrase *parent)

bool SpellQuickPhraseProvider::populate(
InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallback &addCandidate) {
const QuickPhraseAddCandidateCallbackV2 &addCandidate) {
if (!*parent_->config().enableSpell) {
return true;
}
Expand All @@ -125,19 +123,29 @@ bool SpellQuickPhraseProvider::populate(
const auto result = spell->call<ISpell::hint>(
lang, userInput, instance_->globalConfig().defaultPageSize());
for (const auto &word : result) {
addCandidate(word, word, QuickPhraseAction::Commit);
addCandidate(word, word, "", QuickPhraseAction::Commit);
}
return true;
}

bool CallbackQuickPhraseProvider::populate(
InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallback &addCandidate) {
for (const auto &callback : callback_.view()) {
const QuickPhraseAddCandidateCallbackV2 &addCandidate) {
for (const auto &callback : callbackV2_.view()) {
if (!callback(ic, userInput, addCandidate)) {
return false;
}
}
for (const auto &callback : callback_.view()) {
if (!callback(ic, userInput,
[&addCandidate](const std::string &word,
const std::string &aux,
QuickPhraseAction action) {
return addCandidate(word, aux, "", action);
})) {
return false;
}
}
return true;
}

Expand Down
23 changes: 16 additions & 7 deletions src/modules/quickphrase/quickphraseprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ class QuickPhraseProvider {
virtual ~QuickPhraseProvider() = default;
virtual bool
populate(InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallback &addCandidate) = 0;
const QuickPhraseAddCandidateCallbackV2 &addCandidate) = 0;
};

class BuiltInQuickPhraseProvider : public QuickPhraseProvider {
public:
bool populate(InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallback &addCandidate) override;
bool
populate(InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallbackV2 &addCandidate) override;
void reloadConfig();

private:
Expand All @@ -47,8 +48,9 @@ class SpellQuickPhraseProvider : public QuickPhraseProvider {
SpellQuickPhraseProvider(QuickPhrase *parent);
FCITX_ADDON_DEPENDENCY_LOADER(spell, instance_->addonManager());

bool populate(InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallback &addCandidate) override;
bool
populate(InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallbackV2 &addCandidate) override;

private:
QuickPhrase *parent_;
Expand All @@ -58,16 +60,23 @@ class SpellQuickPhraseProvider : public QuickPhraseProvider {
class CallbackQuickPhraseProvider : public QuickPhraseProvider,
public ConnectableObject {
public:
bool populate(InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallback &addCandidate) override;
bool
populate(InputContext *ic, const std::string &userInput,
const QuickPhraseAddCandidateCallbackV2 &addCandidate) override;

std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallback>>
addCallback(QuickPhraseProviderCallback callback) {
return callback_.add(std::move(callback));
}

std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallbackV2>>
addCallback(QuickPhraseProviderCallbackV2 callback) {
return callbackV2_.add(std::move(callback));
}

private:
HandlerTable<QuickPhraseProviderCallback> callback_;
HandlerTable<QuickPhraseProviderCallbackV2> callbackV2_;
};

} // namespace fcitx
Expand Down
61 changes: 50 additions & 11 deletions test/testquickphrase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#include <memory>
#include <string>
#include "fcitx-utils/eventdispatcher.h"
#include "fcitx-utils/handlertable.h"
#include "fcitx-utils/key.h"
#include "fcitx-utils/keysym.h"
#include "fcitx-utils/log.h"
#include "fcitx-utils/macros.h"
#include "fcitx-utils/testing.h"
#include "fcitx/addonmanager.h"
#include "fcitx/instance.h"
#include "fcitx/userinterface.h"
#include "quickphrase_public.h"
#include "testdir.h"
#include "testfrontend_public.h"
Expand All @@ -16,8 +24,8 @@ using namespace fcitx;

std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallback>> handle;

void scheduleEvent(EventDispatcher *dispatcher, Instance *instance) {
dispatcher->schedule([instance]() {
void testInit(Instance *instance) {
instance->eventDispatcher().schedule([instance]() {
auto *quickphrase = instance->addonManager().addon("quickphrase", true);
handle = quickphrase->call<IQuickPhrase::addProvider>(
[](InputContext *, const std::string &text,
Expand All @@ -31,7 +39,10 @@ void scheduleEvent(EventDispatcher *dispatcher, Instance *instance) {
});
FCITX_ASSERT(quickphrase);
});
dispatcher->schedule([dispatcher, instance]() {
}

void testBasic(Instance *instance) {
instance->eventDispatcher().schedule([instance]() {
auto *testfrontend = instance->addonManager().addon("testfrontend");
for (const auto *expectation :
{"TEST", "abc", "abcd", "DEF", "abcd", "DEF1", "test1", "CALLBACK",
Expand Down Expand Up @@ -150,12 +161,36 @@ void scheduleEvent(EventDispatcher *dispatcher, Instance *instance) {
testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("u"), false);
testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("t"), false);
testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("o"), false);
});
}

dispatcher->schedule([dispatcher, instance]() {
handle.reset();
dispatcher->detach();
instance->exit();
});
void testProviderV2(Instance *instance) {
instance->eventDispatcher().schedule([instance]() {
auto *testfrontend = instance->addonManager().addon("testfrontend");
testfrontend->call<ITestFrontend::pushCommitExpectation>("PROVIDERV2");
auto uuid =
testfrontend->call<ITestFrontend::createInputContext>("testapp");
testfrontend->call<ITestFrontend::keyEvent>(
uuid, Key(FcitxKey_BackSpace), false);
auto *quickphrase = instance->addonManager().addon("quickphrase", true);
auto handleV2 = quickphrase->call<IQuickPhrase::addProviderV2>(
[](InputContext *, const std::string &text,
const QuickPhraseAddCandidateCallbackV2 &callback) {
FCITX_INFO() << "Quickphrase text: " << text;
if (text == "PVD") {
callback("PROVIDERV2", "V2", "COMMENT",
QuickPhraseAction::Commit);
return false;
}
return true;
});

testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("Super+grave"),
false);
testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("P"), false);
testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("V"), false);
testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("D"), false);
testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("1"), false);
});
}

Expand All @@ -172,9 +207,13 @@ int main() {
char *argv[] = {arg0, arg1, arg2};
Instance instance(FCITX_ARRAY_SIZE(argv), argv);
instance.addonManager().registerDefaultLoader(nullptr);
EventDispatcher dispatcher;
dispatcher.attach(&instance.eventLoop());
scheduleEvent(&dispatcher, &instance);
testInit(&instance);
testBasic(&instance);
testProviderV2(&instance);
instance.eventDispatcher().schedule([&instance]() {
handle.reset();
instance.exit();
});
instance.exec();
return 0;
}

0 comments on commit 57f7769

Please sign in to comment.