Skip to content

Commit

Permalink
Improve candidate suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
bingzheung committed Mar 24, 2024
1 parent e017157 commit 653e5de
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 154 deletions.
21 changes: 20 additions & 1 deletion CoreIME/Sources/CoreIME/Candidate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public struct Candidate: Hashable {
/// Formatted user input for pre-edit display
public let mark: String

/// Rank. Smaller is preferred.
let order: Int

public let notation: Notation?

/// Primary Initializer
Expand All @@ -60,6 +63,19 @@ public struct Candidate: Hashable {
self.romanization = romanization
self.input = input
self.mark = mark ?? input
self.order = 0
self.notation = notation
}

/// CoreIME Internal Initializer
init(text: String, romanization: String, input: String, mark: String, order: Int, notation: Notation?) {
self.type = .cantonese
self.text = text
self.lexiconText = text
self.romanization = romanization
self.input = input
self.mark = mark
self.order = order
self.notation = notation
}

Expand All @@ -77,6 +93,7 @@ public struct Candidate: Hashable {
self.romanization = romanization
self.input = input
self.mark = input
self.order = 0
self.notation = nil
}

Expand All @@ -93,6 +110,7 @@ public struct Candidate: Hashable {
self.romanization = secondaryComment ?? ""
self.input = input
self.mark = input
self.order = 0
self.notation = nil
}

Expand Down Expand Up @@ -136,7 +154,8 @@ public struct Candidate: Hashable {
let newLexiconText: String = lhs.lexiconText + rhs.lexiconText
let newRomanization: String = lhs.romanization + " " + rhs.romanization
let newInput: String = lhs.input + rhs.input
return Candidate(text: newText, lexiconText: newLexiconText, romanization: newRomanization, input: newInput)
let newMark: String = lhs.mark + " " + rhs.mark
return Candidate(text: newText, lexiconText: newLexiconText, romanization: newRomanization, input: newInput, mark: newMark)
}
}

Expand Down
9 changes: 7 additions & 2 deletions CoreIME/Sources/CoreIME/Converter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ extension Candidate {
/// - Returns: Transformed Candidate
public func transformed(to variant: CharacterStandard) -> Candidate {
guard self.isCantonese else { return self }
let convertedText: String = Converter.convert(text, to: variant)
return Candidate(text: convertedText, lexiconText: lexiconText, romanization: romanization, input: input, mark: mark, notation: notation)
switch variant {
case .traditional:
return self
case .simplified:
let convertedText: String = Converter.convert(text, to: variant)
return Candidate(text: convertedText, lexiconText: lexiconText, romanization: romanization, input: input, mark: mark, notation: notation)
}
}
}

Expand Down
17 changes: 8 additions & 9 deletions CoreIME/Sources/CoreIME/Emoji.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,32 @@ extension Engine {
}

public static func searchSymbols(text: String, segmentation: Segmentation) -> [Candidate] {
let regular: [Candidate] = match(text: text)
let regular: [Candidate] = match(text: text, input: text)
let textCount = text.count
let segmentation = segmentation.filter({ $0.length == textCount })
guard segmentation.maxLength > 0 else { return regular }
let matches = segmentation.map({ scheme -> [Candidate] in
let schemes = segmentation.filter({ $0.length == textCount })
guard !(schemes.isEmpty) else { return regular }
let matches = schemes.map({ scheme -> [Candidate] in
let pingText = scheme.map(\.origin).joined()
return match(text: pingText, input: text)
})
let symbols: [Candidate] = regular + matches.flatMap({ $0 })
return symbols.uniqued()
}

private static func match(text: String, input: String? = nil) -> [Candidate] {
let inputText: String = input ?? text
private static func match(text: String, input: String) -> [Candidate] {
var candidates: [Candidate] = []
let query = "SELECT category, codepoint, cantonese, romanization FROM symboltable WHERE ping = \(text.hash);"
let command: String = "SELECT category, codepoint, cantonese, romanization FROM symboltable WHERE ping = \(text.hash);"
var statement: OpaquePointer? = nil
defer { sqlite3_finalize(statement) }
guard sqlite3_prepare_v2(Engine.database, query, -1, &statement, nil) == SQLITE_OK else { return candidates }
guard sqlite3_prepare_v2(Engine.database, command, -1, &statement, nil) == SQLITE_OK else { return candidates }
while sqlite3_step(statement) == SQLITE_ROW {
let categoryCode: Int = Int(sqlite3_column_int64(statement, 0))
let codepoint: String = String(cString: sqlite3_column_text(statement, 1))
let cantonese: String = String(cString: sqlite3_column_text(statement, 2))
let romanization: String = String(cString: sqlite3_column_text(statement, 3))
if let symbolText = generateSymbol(from: codepoint) {
let isEmoji: Bool = (categoryCode > 0) && (categoryCode < 9)
let instance = Candidate(symbol: symbolText, cantonese: cantonese, romanization: romanization, input: inputText, isEmoji: isEmoji)
let instance = Candidate(symbol: symbolText, cantonese: cantonese, romanization: romanization, input: input, isEmoji: isEmoji)
candidates.append(instance)
}
}
Expand Down
Loading

0 comments on commit 653e5de

Please sign in to comment.