Skip to content

Commit 9f774e7

Browse files
authored
feat(language): shared user dictionary per language (Closes #184) (#214)
1 parent b86b647 commit 9f774e7

10 files changed

+91
-46
lines changed

src/rime/dict/user_dictionary.cc

+6-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <boost/lexical_cast.hpp>
1010
#include <boost/scope_exit.hpp>
1111
#include <rime/common.h>
12+
#include <rime/language.h>
1213
#include <rime/schema.h>
1314
#include <rime/service.h>
1415
#include <rime/ticket.h>
@@ -116,8 +117,8 @@ bool UserDictEntryIterator::Next() {
116117

117118
// UserDictionary members
118119

119-
UserDictionary::UserDictionary(const an<Db>& db)
120-
: db_(db) {
120+
UserDictionary::UserDictionary(const string& name, an<Db> db)
121+
: name_(name), db_(db) {
121122
}
122123

123124
UserDictionary::~UserDictionary() {
@@ -494,10 +495,8 @@ UserDictionary* UserDictionaryComponent::Create(const Ticket& ticket) {
494495
// user specified name
495496
}
496497
else if (config->GetString(ticket.name_space + "/dictionary", &dict_name)) {
497-
// {dictionary: lunapinyin.extra} implies {user_dict: luna_pinyin}
498-
size_t dot = dict_name.find('.');
499-
if (dot != string::npos && dot != 0)
500-
dict_name.resize(dot);
498+
// {dictionary: luna_pinyin.extra} implies {user_dict: luna_pinyin}
499+
dict_name = Language::get_language_component(dict_name);
501500
}
502501
else {
503502
LOG(ERROR) << ticket.name_space << "/dictionary not specified in schema '"
@@ -519,7 +518,7 @@ UserDictionary* UserDictionaryComponent::Create(const Ticket& ticket) {
519518
db.reset(component->Create(dict_name));
520519
db_pool_[dict_name] = db;
521520
}
522-
return new UserDictionary(db);
521+
return new UserDictionary(dict_name, db);
523522
}
524523

525524
} // namespace rime

src/rime/dict/user_dictionary.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct Ticket;
5050

5151
class UserDictionary : public Class<UserDictionary, const Ticket&> {
5252
public:
53-
explicit UserDictionary(const an<Db>& db);
53+
UserDictionary(const string& name, an<Db> db);
5454
virtual ~UserDictionary();
5555

5656
void Attach(const an<Table>& table, const an<Prism>& prism);

src/rime/gear/memory.cc

+10-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <rime/composition.h>
1010
#include <rime/engine.h>
1111
#include <rime/key_event.h>
12+
#include <rime/language.h>
1213
#include <rime/schema.h>
1314
#include <rime/ticket.h>
1415
#include <rime/dict/dictionary.h>
@@ -65,6 +66,13 @@ Memory::Memory(const Ticket& ticket) {
6566
}
6667
}
6768

69+
// user dictionary is named after language; dictionary name may have an
70+
// optional suffix separated from the language component by dot.
71+
language_.reset(new Language{
72+
user_dict_ ? user_dict_->name() :
73+
Language::get_language_component(dict_->name())
74+
});
75+
6876
Context* ctx = ticket.engine->context();
6977
commit_connection_ = ctx->commit_notifier().connect(
7078
[this](Context* ctx) { OnCommit(ctx); });
@@ -100,7 +108,7 @@ void Memory::OnCommit(Context* ctx) {
100108
for (auto& seg : ctx->composition()) {
101109
auto phrase = As<Phrase>(Candidate::GetGenuineCandidate(
102110
seg.GetSelectedCandidate()));
103-
bool recognized = phrase && phrase->language() == language();
111+
bool recognized = Language::intelligible(phrase, this);
104112
if (recognized) {
105113
commit_entry.AppendPhrase(phrase);
106114
}
@@ -119,8 +127,7 @@ void Memory::OnDeleteEntry(Context* ctx) {
119127
return;
120128
auto phrase = As<Phrase>(Candidate::GetGenuineCandidate(
121129
ctx->GetSelectedCandidate()));
122-
bool recognized = phrase && phrase->language() == language();
123-
if (recognized) {
130+
if (Language::intelligible(phrase, this)) {
124131
const DictEntry& entry(phrase->entry());
125132
LOG(INFO) << "deleting entry: '" << entry.text << "'.";
126133
user_dict_->UpdateEntry(entry, -1); // mark as deleted in user dict

src/rime/gear/memory.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Context;
1717
class Engine;
1818
class Dictionary;
1919
class UserDictionary;
20+
class Language;
2021
class Phrase;
2122
class Memory;
2223

@@ -31,9 +32,6 @@ struct CommitEntry : DictEntry {
3132
bool Save() const;
3233
};
3334

34-
class Language {
35-
};
36-
3735
class Memory {
3836
public:
3937
Memory(const Ticket& ticket);
@@ -45,24 +43,24 @@ class Memory {
4543
bool FinishSession();
4644
bool DiscardSession();
4745

48-
Language* language() { return &language_; }
49-
5046
Dictionary* dict() const { return dict_.get(); }
5147
UserDictionary* user_dict() const { return user_dict_.get(); }
5248

49+
const Language* language() const { return language_.get(); }
50+
5351
protected:
5452
void OnCommit(Context* ctx);
5553
void OnDeleteEntry(Context* ctx);
5654
void OnUnhandledKey(Context* ctx, const KeyEvent& key);
5755

5856
the<Dictionary> dict_;
5957
the<UserDictionary> user_dict_;
58+
the<Language> language_;
6059

6160
private:
6261
connection commit_connection_;
6362
connection delete_connection_;
6463
connection unhandled_key_connection_;
65-
Language language_;
6664
};
6765

6866
} // namespace rime

src/rime/gear/poet.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ class Language;
2121

2222
class Poet {
2323
public:
24-
Poet(Language* language) : language_(language) {}
24+
Poet(const Language* language) : language_(language) {}
25+
26+
an<Sentence> MakeSentence(const WordGraph& graph, size_t total_length);
2527

26-
an<Sentence> MakeSentence(const WordGraph& graph,
27-
size_t total_length);
2828
protected:
29-
Language* language_;
29+
const Language* language_;
3030
};
3131

3232
} // namespace rime

src/rime/gear/table_translator.cc

+3-14
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,10 @@ static const char* kUnitySymbol = " \xe2\x98\xaf ";
2828
// TableTranslation
2929

3030
TableTranslation::TableTranslation(TranslatorOptions* options,
31-
Language* language,
31+
const Language* language,
3232
const string& input,
33-
size_t start, size_t end,
34-
const string& preedit)
35-
: options_(options), language_(language),
36-
input_(input), start_(start), end_(end), preedit_(preedit) {
37-
if (options_)
38-
options_->preedit_formatter().Apply(&preedit_);
39-
set_exhausted(true);
40-
}
41-
42-
TableTranslation::TableTranslation(TranslatorOptions* options,
43-
Language* language,
44-
const string& input,
45-
size_t start, size_t end,
33+
size_t start,
34+
size_t end,
4635
const string& preedit,
4736
const DictEntryIterator& iter,
4837
const UserDictEntryIterator& uter)

src/rime/gear/table_translator.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ class TableTranslator : public Translator,
5050
class TableTranslation : public Translation {
5151
public:
5252

53-
TableTranslation(TranslatorOptions* options, Language* language,
54-
const string& input, size_t start, size_t end,
55-
const string& preedit);
56-
TableTranslation(TranslatorOptions* options, Language* language,
57-
const string& input, size_t start, size_t end,
53+
TableTranslation(TranslatorOptions* options,
54+
const Language* language,
55+
const string& input,
56+
size_t start,
57+
size_t end,
5858
const string& preedit,
59-
const DictEntryIterator& iter,
59+
const DictEntryIterator& iter = DictEntryIterator(),
6060
const UserDictEntryIterator& uter = UserDictEntryIterator());
6161

6262
virtual bool Next();
@@ -74,7 +74,7 @@ class TableTranslation : public Translation {
7474
}
7575

7676
TranslatorOptions* options_;
77-
Language* language_;
77+
const Language* language_;
7878
string input_;
7979
size_t start_;
8080
size_t end_;

src/rime/gear/translator_commons.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class Language;
7070

7171
class Phrase : public Candidate {
7272
public:
73-
Phrase(Language* language,
73+
Phrase(const Language* language,
7474
const string& type, size_t start, size_t end,
7575
const an<DictEntry>& entry)
7676
: Candidate(type, start, end),
@@ -93,14 +93,14 @@ class Phrase : public Candidate {
9393
double weight() const { return entry_->weight; }
9494
Code& code() const { return entry_->code; }
9595
const DictEntry& entry() const { return *entry_; }
96-
Language* language() const { return language_; }
96+
const Language* language() const { return language_; }
9797
Spans spans() {
9898
return syllabifier_ ? syllabifier_->Syllabify(this)
9999
: Spans();
100100
}
101101

102102
protected:
103-
Language* language_;
103+
const Language* language_;
104104
an<DictEntry> entry_;
105105
an<PhraseSyllabifier> syllabifier_;
106106
};
@@ -109,7 +109,7 @@ class Phrase : public Candidate {
109109

110110
class Sentence : public Phrase {
111111
public:
112-
Sentence(Language* language)
112+
Sentence(const Language* language)
113113
: Phrase(language, "sentence", 0, 0, New<DictEntry>()) {
114114
entry_->weight = 1.0;
115115
}

src/rime/language.cc

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// Copyright RIME Developers
3+
// Distributed under the BSD License
4+
//
5+
#include <rime/common.h>
6+
#include <rime/language.h>
7+
8+
namespace rime {
9+
10+
// "luna_pinyin.extra" has language component "luna_pinyin".
11+
string Language::get_language_component(const string& name) {
12+
size_t dot = name.find('.');
13+
if (dot != string::npos && dot != 0)
14+
return name.substr(0, dot);
15+
return name;
16+
}
17+
18+
} // namespace rime

src/rime/language.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Copyright RIME Developers
3+
// Distributed under the BSD License
4+
//
5+
#ifndef RIME_LANGUAGE_H_
6+
#define RIME_LANGUAGE_H_
7+
8+
#include <rime/common.h>
9+
10+
namespace rime {
11+
12+
class Language {
13+
const string name_;
14+
15+
public:
16+
Language(const string& name) : name_(name) {}
17+
string name() const { return name_; }
18+
19+
bool operator== (const Language& other) const {
20+
return name_ == other.name_;
21+
}
22+
23+
template <class T, class U>
24+
static bool intelligible(const T& t, const U& u) {
25+
return t && t->language() && u && u->language() &&
26+
*t->language() == *u->language();
27+
}
28+
29+
static string get_language_component(const string& name);
30+
};
31+
32+
} // namespace rime
33+
34+
#endif // RIME_LANGUAGE_H_

0 commit comments

Comments
 (0)