Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions bamboo.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ func (e *BambooEngine) GetProcessedString(mode Mode) string {
}

func (e *BambooEngine) getApplicableRules(key rune) []Rule {
if !e.CanProcessKey(key) {
return nil
}
var applicableRules []Rule
for _, inputRule := range e.inputMethod.Rules {
if inputRule.Key == unicode.ToLower(key) {
Expand All @@ -122,12 +125,7 @@ func (e *BambooEngine) generateTransformations(composition []*Transformation, lo
// transformation fall-backs to an APPENDING one.
transformations = generateFallbackTransformations(composition, e.getApplicableRules(lowerKey), lowerKey, isUpperCase)
var newComposition = append(composition, transformations...)

// Implement the uwo+ typing shortcut by creating a virtual
// Mark.HORN rule that targets 'u' or 'o'.
if virtualTrans := e.applyUowShortcut(newComposition); virtualTrans != nil {
transformations = append(transformations, virtualTrans)
}
transformations = append(transformations, e.applyUIShortcuts(newComposition)...)
}
/**
* Sometimes, a tone's position in a previous state must be changed to fit the new state
Expand All @@ -140,6 +138,15 @@ func (e *BambooEngine) generateTransformations(composition []*Transformation, lo
return transformations
}

func (e *BambooEngine) applyUIShortcuts(syllable []*Transformation) []*Transformation {
// Implement the uwo+ typing shortcut by creating a virtual
// Mark.HORN rule that targets 'u' or 'o'.
if virtualTrans := e.applyUowShortcut(syllable); virtualTrans != nil {
return []*Transformation{virtualTrans}
}
return nil
}

func (e *BambooEngine) newComposition(composition []*Transformation, key rune, isUpperCase bool) []*Transformation {
// Just process the key stroke on the last syllable
var previousTransformations, lastSyllable = extractLastSyllable(composition)
Expand Down Expand Up @@ -184,6 +191,10 @@ func (e *BambooEngine) ProcessString(str string, mode Mode) {
func (e *BambooEngine) ProcessKey(key rune, mode Mode) {
var lowerKey = unicode.ToLower(key)
var isUpperCase = unicode.IsUpper(key)
if mode&EnglishMode == 0 && (key == '\b' || key == 0x7f) {
e.handleBackspace()
return
}
if mode&EnglishMode != 0 || !e.CanProcessKey(lowerKey) {
if mode&InReverseOrder != 0 {
e.composition = append([]*Transformation{newAppendingTrans(lowerKey, isUpperCase)}, e.composition...)
Expand Down Expand Up @@ -217,27 +228,21 @@ func (e *BambooEngine) Reset() {

// Find the last APPENDING transformation and all
// the transformations that add effects to it.
func (e *BambooEngine) RemoveLastChar(refreshLastToneTarget bool) {
var lastAppending = findLastAppendingTrans(e.composition)
if lastAppending == nil {
return
func (e *BambooEngine) RemoveLastChar(refreshLastTone bool) {
e.handleBackspace()
if refreshLastTone {
e.composition = append(e.composition, e.refreshLastToneTarget(e.composition)...)
}
if !e.CanProcessKey(lastAppending.Rule.Key) {
e.composition = e.composition[:len(e.composition)-1]
}

func (e *BambooEngine) handleBackspace() {
if len(e.composition) == 0 {
return
}
var previous, lastComb = extractLastWord(e.composition, e.GetInputMethod().Keys)
var newComb []*Transformation
for _, t := range lastComb {
if t.Target == lastAppending || t == lastAppending {
continue
}
newComb = append(newComb, t)
}
if refreshLastToneTarget {
newComb = append(newComb, e.refreshLastToneTarget(newComb)...)
e.composition = e.composition[:len(e.composition)-1]
for len(e.composition) > 0 && e.composition[len(e.composition)-1].Rule.Key == 0 {
e.composition = e.composition[:len(e.composition)-1]
}
e.composition = append(previous, newComb...)
}

/***** END SIDE-EFFECT METHODS ******/
66 changes: 50 additions & 16 deletions bamboo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ func TestProcessThuowString(t *testing.T) {
t.Errorf("Process [Thuow], got [%s] expected [%s]", ng.GetProcessedString(VietnameseMode), "Thuơ")
}
ng.RemoveLastChar(true)
if ng.GetProcessedString(VietnameseMode) != "Thu" {
t.Errorf("Process [Thuow] and remove last char, got [%s] expected [%s]", ng.GetProcessedString(VietnameseMode), "Thu")
if ng.GetProcessedString(VietnameseMode) != "Thuo" {
t.Errorf("Process [Thuow] and remove last char, got [%s] expected [%s]", ng.GetProcessedString(VietnameseMode), "Thuo")
}
}

Expand All @@ -90,13 +90,13 @@ func TestBambooEngine_RemoveLastChar(t *testing.T) {
t.Errorf("Process [loanj], got [%s] expected [loạn]", ng.GetProcessedString(VietnameseMode))
}
ng.RemoveLastChar(true)
if ng.GetProcessedString(VietnameseMode) != "lọa" {
t.Errorf("Process [loanj-1], got [%s] expected [lọa]", ng.GetProcessedString(VietnameseMode))
if ng.GetProcessedString(VietnameseMode) != "loan" {
t.Errorf("Process [loanj-1], got [%s] expected [loan]", ng.GetProcessedString(VietnameseMode))
}
ng.ProcessString(":", EnglishMode)
ng.RemoveLastChar(true)
if ng.GetProcessedString(VietnameseMode) != "lọa" {
t.Errorf("Process [loanj-1], got [%s] expected [lọa]", ng.GetProcessedString(VietnameseMode))
if ng.GetProcessedString(VietnameseMode) != "loan" {
t.Errorf("Process [loanj-1], got [%s] expected [loan]", ng.GetProcessedString(VietnameseMode))
}
}

Expand All @@ -107,12 +107,12 @@ func TestProcessUpperString(t *testing.T) {
t.Errorf("Process [VIEETJ], got [%s] expected [VIỆT]", ng.GetProcessedString(VietnameseMode))
}
ng.RemoveLastChar(false)
if ng.GetProcessedString(VietnameseMode) != "VIỆ" {
t.Errorf("Process remove last char of upper string, got [%s] expected [VIỆ]", ng.GetProcessedString(VietnameseMode))
if ng.GetProcessedString(VietnameseMode) != "VIÊT" {
t.Errorf("Process remove last char of upper string, got [%s] expected [VIÊT]", ng.GetProcessedString(VietnameseMode))
}
ng.ProcessKey('Q', VietnameseMode)
if ng.GetProcessedString(EnglishMode) != "VIEEJQ" {
t.Errorf("Process remove last char of upper string, got [%s] expected [VIEEJQ]", ng.GetProcessedString(EnglishMode))
if ng.GetProcessedString(EnglishMode) != "VIEETQ" {
t.Errorf("Process remove last char of upper string, got [%s] expected [VIEETQ]", ng.GetProcessedString(EnglishMode))
}
ng.Reset()
ng.ProcessString("IB", EnglishMode)
Expand Down Expand Up @@ -196,8 +196,8 @@ func TestRemoveLastChar(t *testing.T) {
ng := newStdEngine()
ng.ProcessString("hanhj", VietnameseMode)
ng.RemoveLastChar(true)
if ng.GetProcessedString(VietnameseMode) != "hạn" {
t.Errorf("Process [hanhj], got [%s] expected [%s]", ng.GetProcessedString(VietnameseMode), "hạn")
if ng.GetProcessedString(VietnameseMode) != "hanh" {
t.Errorf("Process [hanhj], got [%s] expected [hanh]", ng.GetProcessedString(VietnameseMode))
}
ng.Reset()
}
Expand Down Expand Up @@ -300,8 +300,8 @@ func TestProcessRefresh2(t *testing.T) {
ng.ProcessString("reff", VietnameseMode)
ng.RemoveLastChar(true)
ng.ProcessKey('f', VietnameseMode)
if ng.GetProcessedString(VietnameseMode) != "" {
t.Errorf("Process reff-1+f, got [%v] expected []", ng.GetProcessedString(VietnameseMode))
if ng.GetProcessedString(VietnameseMode) != "ref" {
t.Errorf("Process reff-1+f, got [%v] expected [ref]", ng.GetProcessedString(VietnameseMode))
}
}

Expand Down Expand Up @@ -606,8 +606,8 @@ func TestDoubleTyping(t *testing.T) {
ng.RemoveLastChar(true)
ng.RemoveLastChar(true)
// ng.ProcessString("r", VietnameseMode)
if ng.GetProcessedString(VietnameseMode) != "tủ" {
t.Errorf("Process turyen,BS,BS,BS,r, got [%s] expected [tủ]", ng.GetProcessedString(VietnameseMode))
if ng.GetProcessedString(VietnameseMode) != "tủy" {
t.Errorf("Process turyen,BS,BS,BS,r, got [%s] expected [tủy]", ng.GetProcessedString(VietnameseMode))
}
ng.Reset()
ng.ProcessString("chuyển", VietnameseMode)
Expand Down Expand Up @@ -646,6 +646,40 @@ func TestDoubleTyping(t *testing.T) {

var ng = newStdEngine()

func TestProcessKey_Backspace(t *testing.T) {
e := newStdEngine()
e.ProcessString("chao", VietnameseMode)
if e.GetProcessedString(VietnameseMode) != "chao" {
t.Errorf("Expected chao, got %s", e.GetProcessedString(VietnameseMode))
}
e.ProcessKey('s', VietnameseMode)
if e.GetProcessedString(VietnameseMode) != "cháo" {
t.Errorf("Expected cháo, got %s", e.GetProcessedString(VietnameseMode))
}
e.ProcessKey('\b', VietnameseMode)
if e.GetProcessedString(VietnameseMode) != "chao" {
t.Errorf("Expected chao after backspace, got %s", e.GetProcessedString(VietnameseMode))
}
}

func TestGetApplicableRules_Invalid(t *testing.T) {
e := newStdEngine().(*BambooEngine)
rules := e.getApplicableRules('😊')
if rules != nil {
t.Errorf("Expected nil rules for emoji, got %v", rules)
}
}

func TestCanProcessKey_Invalid(t *testing.T) {
e := newStdEngine()
if e.CanProcessKey('😊') {
t.Error("Expected CanProcessKey to return false for emoji")
}
if !e.CanProcessKey('a') {
t.Error("Expected CanProcessKey to return true for 'a'")
}
}

func BenchmarkRemoveLastChar(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/BambooEngine/bamboo-core
module github.com/LotusInputMethod/bamboo-core

go 1.18
Loading