[WIP] Starts to work on the user phrases.

This commit is contained in:
zonble 2022-01-07 13:21:30 +08:00 committed by Lukhnos Liu
parent 39cdc7d73d
commit 358462dff1
3 changed files with 144 additions and 12 deletions

View File

@ -53,6 +53,10 @@ namespace Formosa {
void setJoinSeparator(const string& separator); void setJoinSeparator(const string& separator);
const string joinSeparator() const; const string joinSeparator() const;
size_t markerCursorIndex() const;
void setMarkerCursorIndex(size_t inNewIndex);
vector<string> readingsAtRange(size_t begin, size_t end) const;
Grid& grid(); Grid& grid();
protected: protected:
@ -64,6 +68,7 @@ namespace Formosa {
static const size_t MaximumBuildSpanLength = 6; static const size_t MaximumBuildSpanLength = 6;
size_t m_cursorIndex; size_t m_cursorIndex;
size_t m_markerCursorIndex;
vector<string> m_readings; vector<string> m_readings;
Grid m_grid; Grid m_grid;
@ -74,12 +79,14 @@ namespace Formosa {
inline BlockReadingBuilder::BlockReadingBuilder(LanguageModel *inLM) inline BlockReadingBuilder::BlockReadingBuilder(LanguageModel *inLM)
: m_LM(inLM) : m_LM(inLM)
, m_cursorIndex(0) , m_cursorIndex(0)
, m_markerCursorIndex(-1)
{ {
} }
inline void BlockReadingBuilder::clear() inline void BlockReadingBuilder::clear()
{ {
m_cursorIndex = 0; m_cursorIndex = 0;
m_markerCursorIndex = -1;
m_readings.clear(); m_readings.clear();
m_grid.clear(); m_grid.clear();
} }
@ -99,6 +106,15 @@ namespace Formosa {
m_cursorIndex = inNewIndex > m_readings.size() ? m_readings.size() : inNewIndex; m_cursorIndex = inNewIndex > m_readings.size() ? m_readings.size() : inNewIndex;
} }
inline size_t BlockReadingBuilder::markerCursorIndex() const
{
return m_markerCursorIndex;
}
inline void BlockReadingBuilder::setMarkerCursorIndex(size_t inNewIndex)
{
m_markerCursorIndex = inNewIndex > m_readings.size() ? m_readings.size() : inNewIndex;
}
inline void BlockReadingBuilder::insertReadingAtCursor(const string& inReading) inline void BlockReadingBuilder::insertReadingAtCursor(const string& inReading)
{ {
@ -109,6 +125,14 @@ namespace Formosa {
m_cursorIndex++; m_cursorIndex++;
} }
inline vector<string> BlockReadingBuilder::readingsAtRange(size_t begin, size_t end) const {
vector<string> v;
for (size_t i = begin; i < end; i++) {
v.push_back(m_readings[i]);
}
return v;
}
inline bool BlockReadingBuilder::deleteReadingBeforeCursor() inline bool BlockReadingBuilder::deleteReadingBeforeCursor()
{ {
if (!m_cursorIndex) { if (!m_cursorIndex) {

View File

@ -114,6 +114,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot
// shared language model object that stores our phrase-term probability database // shared language model object that stores our phrase-term probability database
FastLM gLanguageModel; FastLM gLanguageModel;
FastLM gLanguageModelPlainBopomofo; FastLM gLanguageModelPlainBopomofo;
FastLM gUserPhraseLanguageModel;
static const int kUserOverrideModelCapacity = 500; static const int kUserOverrideModelCapacity = 500;
static const double kObservedOverrideHalflife = 5400.0; // 1.5 hr. static const double kObservedOverrideHalflife = 5400.0; // 1.5 hr.
@ -451,6 +452,22 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
NSMarkedClauseSegmentAttributeName: @0}; NSMarkedClauseSegmentAttributeName: @0};
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:composedText attributes:attrDict]; NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:composedText attributes:attrDict];
if (_bpmfReadingBuffer->isEmpty() && _builder->markerCursorIndex() != -1) {
NSInteger begin = 0;
NSInteger end = 0;
if (_builder->markerCursorIndex() > _builder->cursorIndex()) {
begin = _builder->cursorIndex();
end = _builder->markerCursorIndex();
} else {
end = _builder->cursorIndex();
begin = _builder->markerCursorIndex();
}
NSRange range = NSMakeRange(begin, end - begin);
NSDictionary *highlightAttrDict = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleDouble),
NSMarkedClauseSegmentAttributeName: @0};
[attrString addAttributes:highlightAttrDict range:range];
}
// the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound, // the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound,
// i.e. the client app needs to take care of where to put ths composing buffer // i.e. the client app needs to take care of where to put ths composing buffer
[client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; [client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
@ -559,6 +576,41 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
return layout; return layout;
} }
- (NSString *)_currentHighlighText
{
if (_builder->markerCursorIndex() == -1) {
return @"";
}
if (!_bpmfReadingBuffer->isEmpty()) {
return @"";
}
NSInteger begin = 0;
NSInteger end = 0;
if (_builder->markerCursorIndex() > _builder->cursorIndex()) {
begin = _builder->cursorIndex();
end = _builder->markerCursorIndex();
} else {
end = _builder->cursorIndex();
begin = _builder->markerCursorIndex();
}
NSRange range = NSMakeRange(begin, end - begin);
NSString *reading = [_composingBuffer substringWithRange:range];
NSMutableString *string = [[NSMutableString alloc] init];
[string appendString:reading];
[string appendString:@" "];
NSMutableArray *readingsArray = [[NSMutableArray alloc] init];
vector<std::string> v = _builder->readingsAtRange(begin,end);
for(vector<std::string>::iterator it_i=v.begin(); it_i!=v.end(); ++it_i) {
[readingsArray addObject:[NSString stringWithUTF8String:it_i->c_str()]];
}
NSString *joined = [readingsArray componentsJoinedByString:@"-"];
[string appendString:joined];
[string appendString:@" "];
[string appendString:@"-1.0"];
return string;
}
- (BOOL)handleInputText:(NSString*)inputText key:(NSInteger)keyCode modifiers:(NSUInteger)flags client:(id)client - (BOOL)handleInputText:(NSString*)inputText key:(NSInteger)keyCode modifiers:(NSUInteger)flags client:(id)client
{ {
NSRect textFrame = NSZeroRect; NSRect textFrame = NSZeroRect;
@ -771,6 +823,24 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
return NO; return NO;
} }
if (flags & NSShiftKeyMask) {
if (_builder->markerCursorIndex() == -1) {
if (_builder->cursorIndex() > 0) {
_builder->setMarkerCursorIndex(_builder->cursorIndex() - 1);
} else {
[self beep];
}
NSString *tmp = [self _currentHighlighText];
NSLog(@"%@", tmp);
}
else {
if (_builder->markerCursorIndex() > 0) {
_builder->setMarkerCursorIndex(_builder->markerCursorIndex() - 1);
} else {
[self beep];
}
}
} else {
if (_builder->cursorIndex() > 0) { if (_builder->cursorIndex() > 0) {
_builder->setCursorIndex(_builder->cursorIndex() - 1); _builder->setCursorIndex(_builder->cursorIndex() - 1);
} }
@ -778,6 +848,7 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
[self beep]; [self beep];
} }
} }
}
[self updateClientComposingBuffer:client]; [self updateClientComposingBuffer:client];
return YES; return YES;
@ -793,6 +864,26 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
return NO; return NO;
} }
if (flags & NSShiftKeyMask) {
if (_builder->markerCursorIndex() == -1) {
if (_builder->cursorIndex() < _builder->length()) {
_builder->setMarkerCursorIndex(_builder->cursorIndex() + 1);
} else {
[self beep];
}
NSString *tmp = [self _currentHighlighText];
NSLog(@"%@", tmp);
}
else {
if (_builder->markerCursorIndex() < _builder->length()) {
_builder->setMarkerCursorIndex(_builder->markerCursorIndex() + 1);
} else {
[self beep];
}
NSString *tmp = [self _currentHighlighText];
NSLog(@"%@", tmp);
}
} else {
if (_builder->cursorIndex() < _builder->length()) { if (_builder->cursorIndex() < _builder->length()) {
_builder->setCursorIndex(_builder->cursorIndex() + 1); _builder->setCursorIndex(_builder->cursorIndex() + 1);
} }
@ -800,6 +891,7 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
[self beep]; [self beep];
} }
} }
}
[self updateClientComposingBuffer:client]; [self updateClientComposingBuffer:client];
return YES; return YES;
@ -1419,6 +1511,13 @@ static double FindHighestScore(const vector<NodeAnchor>& nodes, double epsilon)
@end @end
static NSString *userDataFolderPath() {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDirectory, YES);
NSString *appSupportPath = [paths objectAtIndex:0];
NSString *userDictPath = [appSupportPath stringByAppendingPathComponent:@"McBopomofo"];
return userDictPath;
}
static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, FastLM &lm) static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, FastLM &lm)
{ {
NSString *dataPath = [[NSBundle bundleForClass:[McBopomofoInputMethodController class]] pathForResource:filenameWithoutExtension ofType:@"txt"]; NSString *dataPath = [[NSBundle bundleForClass:[McBopomofoInputMethodController class]] pathForResource:filenameWithoutExtension ofType:@"txt"];
@ -1428,6 +1527,15 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, FastLM &
} }
} }
static void LTLoadUserLanguageModelFile(NSString *filenameWithoutExtension, FastLM &lm)
{
NSString *filename = [filenameWithoutExtension stringByAppendingPathExtension:@"txt"];
NSString *dataPath = [userDataFolderPath() stringByAppendingPathComponent:filename];
bool result = lm.open([dataPath UTF8String]);
if (!result) {
NSLog(@"Failed opening language model: %@", dataPath);
}
}
void LTLoadLanguageModel() void LTLoadLanguageModel()
{ {

View File

@ -224,7 +224,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="按下 ESC 會清除整個輸入緩衝區" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="7gv-k3-Mbt"> <buttonCell key="cell" type="check" title="按下 ESC 會清除整個輸入緩衝區" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="7gv-k3-Mbt">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" size="13" name=".PingFangTC-Regular"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
<connections> <connections>
<binding destination="32" name="value" keyPath="values.EscToCleanInputBufferKey" id="DyT-0S-5XE"/> <binding destination="32" name="value" keyPath="values.EscToCleanInputBufferKey" id="DyT-0S-5XE"/>