Repo // Conforming compatibility requirements by Megrez 2.0.0 update.

This commit is contained in:
ShikiSuen 2022-08-07 18:59:25 +08:00
parent 5fc0351a9c
commit 0cb8ffd649
10 changed files with 149 additions and 251 deletions

View File

@ -38,13 +38,10 @@ public class KeyHandler {
///
var isTypingContentEmpty: Bool { composer.isEmpty && compositor.isEmpty }
///
let kMaxComposingBufferNeedsToWalkSize = Int(max(12, ceil(Double(mgrPrefs.composingBufferSize) / 2)))
var composer: Tekkon.Composer = .init() //
var compositor: Megrez.Compositor //
var currentLM: vChewing.LMInstantiator = .init() //
var currentUOM: vChewing.LMUserOverride = .init() //
var walkedAnchors: [Megrez.NodeAnchor] { compositor.walkedAnchors } //
/// (ctlInputMethod)便
var delegate: KeyHandlerDelegate?
@ -72,7 +69,7 @@ public class KeyHandler {
///
public init() {
/// ensureCompositor()
compositor = Megrez.Compositor(lm: currentLM, separator: "-")
compositor = Megrez.Compositor(with: currentLM, separator: "-")
///
ensureParser()
/// inputMode
@ -91,7 +88,8 @@ public class KeyHandler {
///
/// 使 Node Crossing
var actualCandidateCursor: Int {
mgrPrefs.useRearCursorMode ? min(compositor.cursor, compositor.length - 1) : max(compositor.cursor, 1)
compositor.cursor
- ((compositor.cursor == compositor.width || !mgrPrefs.useRearCursorMode) && compositor.cursor > 0 ? 1 : 0)
}
///
@ -116,23 +114,6 @@ public class KeyHandler {
}
}
///
///
/// Viterbi 使 O(N^2)
/// 使
/// 使
///
var commitOverflownCompositionAndWalk: String {
var textToCommit = ""
if compositor.width > mgrPrefs.composingBufferSize, !walkedAnchors.isEmpty {
let anchor: Megrez.NodeAnchor = walkedAnchors[0]
textToCommit = anchor.node.currentPair.value
compositor.removeHeadReadings(count: anchor.spanLength)
}
walk()
return textToCommit
}
///
/// - Parameter key:
/// - Returns:
@ -151,106 +132,86 @@ public class KeyHandler {
/// - value:
/// - respectCursorPushing: true
func fixNode(candidate: (String, String), respectCursorPushing: Bool = true) {
let theCandidate: Megrez.KeyValuePaired = .init(key: candidate.0, value: candidate.1)
let adjustedCursor = max(0, min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length))
//
let selectedNode: Megrez.NodeAnchor = compositor.fixNodeWithCandidate(theCandidate, at: adjustedCursor)
//
if !mgrPrefs.useSCPCTypingMode {
var addToUserOverrideModel = true
//
if selectedNode.spanLength != theCandidate.value.count {
IME.prtDebugIntel("UOM: SpanningLength != value.count, dismissing.")
addToUserOverrideModel = false
}
if addToUserOverrideModel {
// SymbolLM Score -12
if selectedNode.node.scoreForPaired(candidate: theCandidate) <= -12 {
IME.prtDebugIntel("UOM: Score <= -12, dismissing.")
addToUserOverrideModel = false
}
}
if addToUserOverrideModel, mgrPrefs.fetchSuggestionsFromUserOverrideModel {
IME.prtDebugIntel("UOM: Start Observation.")
// 使
//
// AppDelegate
mgrPrefs.failureFlagForUOMObservation = true
//
//
currentUOM.observe(
walkedAnchors: walkedAnchors, cursorIndex: adjustedCursor, candidate: theCandidate.value,
timestamp: NSDate().timeIntervalSince1970, saveCallback: { mgrLangModel.saveUserOverrideModelData() }
)
//
mgrPrefs.failureFlagForUOMObservation = false
}
}
let actualCursor = actualCandidateCursor
let theCandidate: Megrez.Compositor.Candidate = .init(key: candidate.0, value: candidate.1)
if !compositor.overrideCandidate(theCandidate, at: actualCursor) { return }
//
walk()
// 使
var accumulatedCursor = 0
var currentNode: Megrez.Compositor.Node?
for node in compositor.walkedNodes {
accumulatedCursor += node.spanLength
if accumulatedCursor > actualCursor {
currentNode = node
break
}
}
guard let currentNode = currentNode else { return }
if currentNode.currentUnigram.score > -12 {
IME.prtDebugIntel("UOM: Start Observation.")
// 使
//
// AppDelegate
mgrPrefs.failureFlagForUOMObservation = true
//
//
currentUOM.observe(
walkedNodes: compositor.walkedNodes, cursorIndex: actualCursor, candidate: theCandidate.value,
timestamp: NSDate().timeIntervalSince1970, saveCallback: { mgrLangModel.saveUserOverrideModelData() }
)
//
mgrPrefs.failureFlagForUOMObservation = false
}
///
if mgrPrefs.moveCursorAfterSelectingCandidate, respectCursorPushing {
// compositor.cursor = accumulatedCursor
compositor.jumpCursorBySpan(to: .front)
}
}
///
func markNodesFixedIfNecessary() {
let width = compositor.width
if width <= kMaxComposingBufferNeedsToWalkSize {
return
}
var index = 0
for anchor in walkedAnchors {
if index >= width - kMaxComposingBufferNeedsToWalkSize { break }
if anchor.node.score < Megrez.Node.kSelectedCandidateScore {
compositor.fixNodeWithCandidate(anchor.node.currentPair, at: index + anchor.spanLength)
}
index += anchor.spanLength
}
}
///
func getCandidatesArray(fixOrder: Bool = true) -> [(String, String)] {
var arrAnchors: [Megrez.NodeAnchor] = rawAnchorsOfNodes
var arrCandidates: [Megrez.KeyValuePaired] = .init()
/// 使 nodesCrossing macOS
/// nodeCrossing
var arrCandidates: [Megrez.Compositor.Candidate] = {
switch mgrPrefs.useRearCursorMode {
case false:
return compositor.fetchCandidates(at: actualCandidateCursor, filter: .endAt)
case true:
return compositor.fetchCandidates(at: actualCandidateCursor, filter: .beginAt)
}
}()
/// nodes
///
///
if arrAnchors.isEmpty { return .init() }
if arrCandidates.isEmpty { return .init() }
//
arrAnchors = arrAnchors.stableSort { $0.spanLength > $1.spanLength }
//
for currentCandidate in arrAnchors.map(\.node.candidates).joined() {
// / JIS
//
//
arrCandidates.append(currentCandidate)
}
// 調
if !mgrPrefs.fetchSuggestionsFromUserOverrideModel || mgrPrefs.useSCPCTypingMode || fixOrder {
return arrCandidates.map { ($0.key, $0.value) }
}
let arrSuggestedUnigrams: [Megrez.Unigram] = fetchSuggestedCandidates().stableSort { $0.score > $1.score }
let arrSuggestedCandidates: [Megrez.KeyValuePaired] = arrSuggestedUnigrams.map(\.keyValue)
let arrSuggestedUnigrams: [(String, Megrez.Unigram)] = fetchSuggestedCandidates()
let arrSuggestedCandidates: [Megrez.Compositor.Candidate] = arrSuggestedUnigrams.map {
Megrez.Compositor.Candidate(key: $0.0, value: $0.1.value)
}
arrCandidates = arrSuggestedCandidates.filter { arrCandidates.contains($0) } + arrCandidates
arrCandidates = arrCandidates.deduplicate
arrCandidates = arrCandidates.stableSort { $0.key.split(separator: "-").count > $1.key.split(separator: "-").count }
return arrCandidates.map { ($0.key, $0.value) }
}
///
func fetchSuggestedCandidates() -> [Megrez.Unigram] {
///
func fetchSuggestedCandidates() -> [(String, Megrez.Unigram)] {
currentUOM.suggest(
walkedAnchors: walkedAnchors, cursorIndex: compositor.cursor,
walkedNodes: compositor.walkedNodes, cursorIndex: compositor.cursor,
timestamp: NSDate().timeIntervalSince1970
)
).stableSort { $0.1.score > $1.1.score }
}
///
@ -260,31 +221,19 @@ public class KeyHandler {
///
if !mgrPrefs.fetchSuggestionsFromUserOverrideModel { return }
///
let overrideValue = fetchSuggestedCandidates().first?.keyValue.value ?? ""
let overrideValue = fetchSuggestedCandidates().first?.1.value ?? ""
///
if !overrideValue.isEmpty {
IME.prtDebugIntel(
"UOM: Suggestion retrieved, overriding the node score of the selected candidate.")
compositor.overrideNodeScoreForSelectedCandidate(
location: min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length),
value: overrideValue,
overridingScore: findHighestScore(nodeAnchors: rawAnchorsOfNodes, epsilon: kEpsilon)
)
// TODO:
compositor.overrideCandidateLiteral(overrideValue, at: actualCandidateCursor, overrideType: .withTopUnigramScore)
} else {
IME.prtDebugIntel("UOM: Blank suggestion retrieved, dismissing.")
}
}
///
/// - Parameters:
/// - nodes:
/// - epsilon:
/// - Returns:
func findHighestScore(nodeAnchors: [Megrez.NodeAnchor], epsilon: Double) -> Double {
nodeAnchors.map(\.node.highestUnigramScore).max() ?? 0 + epsilon
}
// MARK: - Extracted methods and functions (Tekkon).
/// _
@ -335,15 +284,6 @@ public class KeyHandler {
// MARK: - Extracted methods and functions (Megrez).
///
var rawAnchorsOfNodes: [Megrez.NodeAnchor] {
/// 使 nodesCrossing macOS
/// nodeCrossing
mgrPrefs.useRearCursorMode
? compositor.nodesBeginningAt(location: actualCandidateCursor)
: compositor.nodesEndingAt(location: actualCandidateCursor)
}
///
func syncBaseLMPrefs() {
currentLM.isPhraseReplacementEnabled = mgrPrefs.phraseReplacementEnabled
@ -354,7 +294,7 @@ public class KeyHandler {
/// 使
func ensureCompositor() {
// 西
compositor = Megrez.Compositor(lm: currentLM, separator: "-")
compositor = Megrez.Compositor(with: currentLM, separator: "-")
}
///

View File

@ -81,23 +81,19 @@ extension KeyHandler {
}
//
compositor.insertReading(readingKey)
compositor.insertKey(readingKey)
//
let textToCommit = commitOverflownCompositionAndWalk
walk()
//
fetchAndApplySuggestionsFromUserOverrideModel()
//
markNodesFixedIfNecessary()
//
composer.clear()
// updateClientComposingBuffer()
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
stateCallback(inputting)
///
@ -106,9 +102,9 @@ extension KeyHandler {
state: inputting,
isTypingVertical: input.isTypingVertical
)
if choosingCandidates.candidates.count == 1 {
let reading: String = choosingCandidates.candidates.first?.0 ?? ""
let text: String = choosingCandidates.candidates.first?.1 ?? ""
if choosingCandidates.candidates.count == 1, let firstCandidate = choosingCandidates.candidates.first {
let reading: String = firstCandidate.0
let text: String = firstCandidate.1
stateCallback(InputState.Committing(textToCommit: text))
if !mgrPrefs.associatedPhrasesEnabled {

View File

@ -163,10 +163,9 @@ extension KeyHandler {
stateCallback(InputState.Committing(textToCommit: " "))
stateCallback(InputState.Empty())
} else if currentLM.hasUnigramsFor(key: " ") {
compositor.insertReading(" ")
let textToCommit = commitOverflownCompositionAndWalk
compositor.insertKey(" ")
walk()
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
stateCallback(inputting)
}
return true
@ -283,10 +282,9 @@ extension KeyHandler {
if input.isOptionHold {
if currentLM.hasUnigramsFor(key: "_punctuation_list") {
if composer.isEmpty {
compositor.insertReading("_punctuation_list")
let textToCommit: String! = commitOverflownCompositionAndWalk
compositor.insertKey("_punctuation_list")
walk()
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
stateCallback(inputting)
stateCallback(buildCandidate(state: inputting, isTypingVertical: input.isTypingVertical))
} else { //

View File

@ -22,21 +22,20 @@ extension KeyHandler {
/// (Update the composing buffer)
/// NSAttributeString
var tooltipParameterRef: [String] = ["", ""]
let nodeValuesArray: [String] = walkedAnchors.values
let nodeValuesArray: [String] = compositor.walkedNodes.values
var composedStringCursorIndex = 0
var readingCursorIndex = 0
/// IMK UTF8 emoji
/// Swift.utf16NSString.length()
///
for theAnchor in walkedAnchors {
let theNode = theAnchor.node
let strNodeValue = theNode.currentPair.value
for theNode in compositor.walkedNodes {
let strNodeValue = theNode.value
let arrSplit: [String] = Array(strNodeValue).map { String($0) }
let codepointCount = arrSplit.count
///
/// NodeAnchorspanningLength
///
let spanningLength: Int = theAnchor.spanLength
let spanningLength: Int = theNode.spanLength
if readingCursorIndex + spanningLength <= compositor.cursor {
composedStringCursorIndex += strNodeValue.utf16.count
readingCursorIndex += spanningLength
@ -60,14 +59,14 @@ extension KeyHandler {
///
///
switch compositor.cursor {
case compositor.readings.count...:
case compositor.keys.count...:
// compositor.cursor readings.count Megrez
tooltipParameterRef[0] = compositor.readings[compositor.cursor - 1]
tooltipParameterRef[0] = compositor.keys[compositor.cursor - 1]
case 0:
tooltipParameterRef[1] = compositor.readings[compositor.cursor]
tooltipParameterRef[1] = compositor.keys[compositor.cursor]
default:
tooltipParameterRef[0] = compositor.readings[compositor.cursor - 1]
tooltipParameterRef[1] = compositor.readings[compositor.cursor]
tooltipParameterRef[0] = compositor.keys[compositor.cursor - 1]
tooltipParameterRef[1] = compositor.keys[compositor.cursor]
}
}
@ -125,7 +124,7 @@ extension KeyHandler {
cursorIndex: currentState.cursorIndex,
candidates: getCandidatesArray(fixOrder: mgrPrefs.useFixecCandidateOrderOnSelection),
isTypingVertical: isTypingVertical,
nodeValuesArray: walkedAnchors.values
nodeValuesArray: compositor.walkedNodes.values
)
}
@ -215,7 +214,7 @@ extension KeyHandler {
cursorIndex: state.cursorIndex,
markerIndex: index,
readings: state.readings,
nodeValuesArray: walkedAnchors.values
nodeValuesArray: compositor.walkedNodes.values
)
marking.tooltipForInputting = state.tooltipForInputting
stateCallback(marking.markedRange.isEmpty ? marking.convertedToInputting : marking)
@ -237,7 +236,7 @@ extension KeyHandler {
cursorIndex: state.cursorIndex,
markerIndex: index,
readings: state.readings,
nodeValuesArray: walkedAnchors.values
nodeValuesArray: compositor.walkedNodes.values
)
marking.tooltipForInputting = state.tooltipForInputting
stateCallback(marking.markedRange.isEmpty ? marking.convertedToInputting : marking)
@ -280,10 +279,9 @@ extension KeyHandler {
return true
}
compositor.insertReading(customPunctuation)
let textToCommit = commitOverflownCompositionAndWalk
compositor.insertKey(customPunctuation)
walk()
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
stateCallback(inputting)
//
@ -338,7 +336,7 @@ extension KeyHandler {
) -> Bool {
guard state is InputState.Inputting else { return false }
var composingBuffer = compositor.readings.joined(separator: "-")
var composingBuffer = compositor.keys.joined(separator: "-")
if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin {
composingBuffer = Tekkon.restoreToneOneInZhuyinKey(target: composingBuffer) //
composingBuffer = Tekkon.cnvPhonaToHanyuPinyin(target: composingBuffer) //
@ -368,7 +366,7 @@ extension KeyHandler {
var composed = ""
for node in walkedAnchors.map(\.node) {
for node in compositor.walkedNodes {
var key = node.key
if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin {
key = Tekkon.restoreToneOneInZhuyinKey(target: key) //
@ -379,7 +377,7 @@ extension KeyHandler {
key = Tekkon.cnvZhuyinChainToTextbookReading(target: key, newSeparator: " ")
}
let value = node.currentPair.value
let value = node.value
//
composed += key.contains("_") ? value : "<ruby>\(value)<rp>(</rp><rt>\(key)</rt><rp>)</rp></ruby>"
}
@ -416,7 +414,7 @@ extension KeyHandler {
composer.clear()
} else if composer.isEmpty {
if compositor.cursor > 0 {
compositor.dropReading(direction: .rear)
compositor.dropKey(direction: .rear)
walk()
} else {
IME.prtDebugIntel("9D69908D")
@ -468,7 +466,7 @@ extension KeyHandler {
}
if composer.isEmpty {
compositor.dropReading(direction: .front)
compositor.dropKey(direction: .front)
walk()
} else {
composer.clear()
@ -640,7 +638,7 @@ extension KeyHandler {
composingBuffer: currentState.composingBuffer,
cursorIndex: currentState.cursorIndex,
markerIndex: nextPosition,
readings: compositor.readings
readings: compositor.keys
)
marking.tooltipForInputting = currentState.tooltip
stateCallback(marking)
@ -714,7 +712,7 @@ extension KeyHandler {
composingBuffer: currentState.composingBuffer,
cursorIndex: currentState.cursorIndex,
markerIndex: previousPosition,
readings: compositor.readings
readings: compositor.keys
)
marking.tooltipForInputting = currentState.tooltip
stateCallback(marking)
@ -770,7 +768,7 @@ extension KeyHandler {
stateCallback: @escaping (InputStateProtocol) -> Void,
errorCallback: @escaping () -> Void
) -> Bool {
if composer.isEmpty, compositor.isEmpty || walkedAnchors.isEmpty { return false }
if composer.isEmpty, compositor.isEmpty || compositor.walkedNodes.isEmpty { return false }
guard state is InputState.Inputting else {
guard state is InputState.Empty else {
IME.prtDebugIntel("6044F081")
@ -795,24 +793,27 @@ extension KeyHandler {
}
var length = 0
var currentAnchor = Megrez.NodeAnchor()
let cursorIndex = min(
actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length
)
for anchor in walkedAnchors {
length += anchor.spanLength
if length >= cursorIndex {
currentAnchor = anchor
var currentNode: Megrez.Compositor.Node?
let cursorIndex = actualCandidateCursor
for node in compositor.walkedNodes {
length += node.spanLength
if length > cursorIndex {
currentNode = node
break
}
}
let currentNode = currentAnchor.node
let currentPaired: Megrez.KeyValuePaired = currentNode.currentPair
guard let currentNode = currentNode else {
IME.prtDebugIntel("F58DEA95")
errorCallback()
return true
}
let currentPaired = (currentNode.key, currentNode.value)
var currentIndex = 0
if currentNode.score < Megrez.Node.kSelectedCandidateScore {
/// 使
if !currentNode.isOverriden {
/// 使
/// 使
/// 2 使
///
@ -821,14 +822,14 @@ extension KeyHandler {
/// (Shift+)Tab ()
/// Shift(+CMD)+Space Alt+/ Alt+/
/// Tab
if candidates[0].0 == currentPaired.key, candidates[0].1 == currentPaired.value {
if candidates[0] == currentPaired {
///
///
currentIndex = reverseModifier ? candidates.count - 1 : 1
}
} else {
for candidate in candidates {
if candidate.0 == currentPaired.key, candidate.1 == currentPaired.value {
if candidate == currentPaired {
if reverseModifier {
if currentIndex == 0 {
currentIndex = candidates.count - 1

View File

@ -175,14 +175,8 @@ extension vChewing {
/// - Parameter key:
/// - Returns:
public func unigramsFor(key: String) -> [Megrez.Unigram] {
if key == " " {
///
let spaceUnigram = Megrez.Unigram(
keyValue: Megrez.KeyValuePaired(key: " ", value: " "),
score: 0
)
return [spaceUnigram]
}
///
if key == " " { return [.init(value: " ")] }
///
var rawAllUnigrams: [Megrez.Unigram] = []
@ -209,11 +203,11 @@ extension vChewing {
rawAllUnigrams.append(contentsOf: queryDateTimeUnigrams(with: key))
// Swift 使 NSOrderedSet
var filteredPairs: Set<Megrez.KeyValuePaired> = []
var filteredPairs: Set<String> = []
// KeyValuePair
for unigram in lmFiltered.unigramsFor(key: key) {
filteredPairs.insert(unigram.keyValue)
filteredPairs.insert(unigram.value)
}
return filterAndTransform(
@ -243,9 +237,6 @@ extension vChewing {
lmAssociates.hasValuesFor(pair: pair)
}
/// 滿 LangModelProtocol
public func bigramsFor(precedingKey _: String, key _: String) -> [Megrez.Bigram] { .init() }
// MARK: -
///
@ -255,20 +246,20 @@ extension vChewing {
/// - Returns:
func filterAndTransform(
unigrams: [Megrez.Unigram],
filter filteredPairs: Set<Megrez.KeyValuePaired>
filter filteredPairs: Set<String>
) -> [Megrez.Unigram] {
var results: [Megrez.Unigram] = []
var insertedPairs: Set<Megrez.KeyValuePaired> = []
var insertedPairs: Set<String> = []
for unigram in unigrams {
var pair: Megrez.KeyValuePaired = unigram.keyValue
if filteredPairs.contains(pair) { continue }
var theValue: String = unigram.value
if filteredPairs.contains(theValue) { continue }
if isPhraseReplacementEnabled {
let replacement = lmReplacements.valuesFor(key: pair.value)
if !replacement.isEmpty { pair.value = replacement }
let replacement = lmReplacements.valuesFor(key: theValue)
if !replacement.isEmpty { theValue = replacement }
}
if insertedPairs.contains(pair) { continue }
results.append(Megrez.Unigram(keyValue: pair, score: unigram.score))
insertedPairs.insert(pair)
if insertedPairs.contains(theValue) { continue }
results.append(Megrez.Unigram(value: theValue, score: unigram.score))
insertedPairs.insert(theValue)
}
return results
}

View File

@ -31,9 +31,9 @@ extension vChewing.LMInstantiator {
var date3 = ChineseConverter.convertArabicNumeralsToChinese(target: date2)
date3 = date3.replacingOccurrences(of: "年〇", with: "")
date3 = date3.replacingOccurrences(of: "月〇", with: "")
results.append(.init(keyValue: .init(key: key, value: date1), score: -94))
results.append(.init(keyValue: .init(key: key, value: date2), score: -95))
results.append(.init(keyValue: .init(key: key, value: date3), score: -96))
results.append(.init(value: date1, score: -94))
results.append(.init(value: date2, score: -95))
results.append(.init(value: date3, score: -96))
if let currentDateShortened = currentDateShortened, delta.year != 0 {
var dateAlt1: String = formatterDate1.string(from: currentDateShortened)
dateAlt1.regReplace(pattern: #"^0+"#)
@ -42,9 +42,9 @@ extension vChewing.LMInstantiator {
var dateAlt3 = ChineseConverter.convertArabicNumeralsToChinese(target: dateAlt2)
dateAlt3 = dateAlt3.replacingOccurrences(of: "年〇", with: "")
dateAlt3 = dateAlt3.replacingOccurrences(of: "月〇", with: "")
results.append(.init(keyValue: .init(key: key, value: dateAlt1), score: -97))
results.append(.init(keyValue: .init(key: key, value: dateAlt2), score: -98))
results.append(.init(keyValue: .init(key: key, value: dateAlt3), score: -99))
results.append(.init(value: dateAlt1, score: -97))
results.append(.init(value: dateAlt2, score: -98))
results.append(.init(value: dateAlt3, score: -99))
}
case "ㄕˊ-ㄐㄧㄢ":
let formatterTime1 = DateFormatter()
@ -56,9 +56,9 @@ extension vChewing.LMInstantiator {
let time1 = formatterTime1.string(from: currentDate)
let time2 = formatterTime2.string(from: currentDate)
let time3 = formatterTime3.string(from: currentDate)
results.append(.init(keyValue: .init(key: key, value: time1), score: -97))
results.append(.init(keyValue: .init(key: key, value: time2), score: -98))
results.append(.init(keyValue: .init(key: key, value: time3), score: -99))
results.append(.init(value: time1, score: -97))
results.append(.init(value: time2, score: -98))
results.append(.init(value: time3, score: -99))
case "ㄒㄧㄥ-ㄑㄧ", "ㄒㄧㄥ-ㄑㄧˊ":
let formatterWeek1 = DateFormatter()
let formatterWeek2 = DateFormatter()
@ -68,8 +68,8 @@ extension vChewing.LMInstantiator {
formatterWeek2.locale = theLocale
let week1 = formatterWeek1.string(from: currentDate)
let week2 = formatterWeek2.string(from: currentDate)
results.append(.init(keyValue: .init(key: key, value: week1), score: -98))
results.append(.init(keyValue: .init(key: key, value: week2), score: -99))
results.append(.init(value: week1, score: -98))
results.append(.init(value: week2, score: -99))
default: return .init()
}
return results

View File

@ -115,18 +115,6 @@ extension vChewing {
IME.prtDebugIntel(strDump)
}
/// 使 strData
///
///
/// - parameters:
/// - precedingKey:
/// - key:
public func bigramsFor(precedingKey: String, key: String) -> [Megrez.Bigram] {
// Swift
// [Megrez.Bigram]()
precedingKey == key ? [Megrez.Bigram]() : [Megrez.Bigram]()
}
/// strData
/// - parameters:
/// - key:
@ -136,7 +124,6 @@ extension vChewing {
for netaRange in arrRangeRecords {
let neta = strData[netaRange].split(separator: " ")
let theValue: String = shouldReverse ? String(neta[0]) : String(neta[1])
let kvPair = Megrez.KeyValuePaired(key: key, value: theValue)
var theScore = defaultScore
if neta.count >= 3, !shouldForceDefaultScore, !neta[2].contains("#") {
theScore = .init(String(neta[2])) ?? defaultScore
@ -144,7 +131,7 @@ extension vChewing {
if theScore > 0 {
theScore *= -1 //
}
grams.append(Megrez.Unigram(keyValue: kvPair, score: theScore))
grams.append(Megrez.Unigram(value: theValue, score: theScore))
}
}
return grams

View File

@ -108,18 +108,6 @@ extension vChewing {
IME.prtDebugIntel(strDump)
}
/// 使 UTF8
///
///
/// - parameters:
/// - precedingKey:
/// - key:
public func bigramsFor(precedingKey: String, key: String) -> [Megrez.Bigram] {
// Swift
// [Megrez.Bigram]()
precedingKey == key ? [Megrez.Bigram]() : [Megrez.Bigram]()
}
/// UTF8
/// - parameters:
/// - key:
@ -130,7 +118,6 @@ extension vChewing {
let strNetaSet = String(decoding: netaSet, as: UTF8.self)
let neta = Array(strNetaSet.split(separator: " ").reversed())
let theValue: String = .init(neta[0])
let kvPair = Megrez.KeyValuePaired(key: key, value: theValue)
var theScore = defaultScore
if neta.count >= 2, !shouldForceDefaultScore {
theScore = .init(String(neta[1])) ?? defaultScore
@ -138,7 +125,7 @@ extension vChewing {
if theScore > 0 {
theScore *= -1 //
}
grams.append(Megrez.Unigram(keyValue: kvPair, score: theScore))
grams.append(Megrez.Unigram(value: theValue, score: theScore))
}
}
return grams

View File

@ -27,13 +27,13 @@ extension vChewing {
}
public func observe(
walkedAnchors: [Megrez.NodeAnchor],
walkedNodes: [Megrez.Compositor.Node],
cursorIndex: Int,
candidate: String,
timestamp: Double,
saveCallback: @escaping () -> Void
) {
let key = convertKeyFrom(walkedAnchors: walkedAnchors, cursorIndex: cursorIndex)
let key = convertKeyFrom(walkedNodes: walkedNodes, cursorIndex: cursorIndex)
guard !key.isEmpty else { return }
guard mutLRUMap[key] != nil else {
@ -57,7 +57,7 @@ extension vChewing {
//
if var theNeta = mutLRUMap[key] {
_ = suggest(
walkedAnchors: walkedAnchors, cursorIndex: cursorIndex, timestamp: timestamp,
walkedNodes: walkedNodes, cursorIndex: cursorIndex, timestamp: timestamp,
decayCallback: {
theNeta.observation.update(candidate: candidate, timestamp: timestamp)
self.mutLRUList.insert(theNeta, at: 0)
@ -70,17 +70,17 @@ extension vChewing {
}
public func suggest(
walkedAnchors: [Megrez.NodeAnchor],
walkedNodes: [Megrez.Compositor.Node],
cursorIndex: Int,
timestamp: Double,
decayCallback: @escaping () -> Void = {}
) -> [Megrez.Unigram] {
let key = convertKeyFrom(walkedAnchors: walkedAnchors, cursorIndex: cursorIndex)
) -> [(String, Megrez.Unigram)] {
let key = convertKeyFrom(walkedNodes: walkedNodes, cursorIndex: cursorIndex)
guard !key.isEmpty else {
IME.prtDebugIntel("UOM: Blank key generated on suggestion, aborting suggestion.")
return .init()
}
let currentReadingKey = convertKeyFrom(walkedAnchors: walkedAnchors, cursorIndex: cursorIndex, readingOnly: true)
let currentReadingKey = convertKeyFrom(walkedNodes: walkedNodes, cursorIndex: cursorIndex, readingOnly: true)
guard let koPair = mutLRUMap[key] else {
IME.prtDebugIntel("UOM: mutLRUMap[key] is nil, throwing blank suggestion for key: \(key).")
return .init()
@ -88,7 +88,7 @@ extension vChewing {
let observation = koPair.observation
var arrResults = [Megrez.Unigram]()
var arrResults = [(String, Megrez.Unigram)]()
var currentHighScore = 0.0
for overrideNeta in Array(observation.overrides) {
let override: Override = overrideNeta.value
@ -111,10 +111,8 @@ extension vChewing {
)
if (0...currentHighScore).contains(overrideDetectionScore) { decayCallback() }
let newUnigram = Megrez.Unigram(
keyValue: .init(key: currentReadingKey, value: overrideNeta.key), score: overrideScore
)
arrResults.insert(newUnigram, at: 0)
let newUnigram = Megrez.Unigram(value: overrideNeta.key, score: overrideScore)
arrResults.insert((currentReadingKey, newUnigram), at: 0)
currentHighScore = overrideScore
}
if arrResults.isEmpty {
@ -137,12 +135,12 @@ extension vChewing {
}
func convertKeyFrom(
walkedAnchors: [Megrez.NodeAnchor], cursorIndex: Int, readingOnly: Bool = false
walkedNodes: [Megrez.Compositor.Node], cursorIndex: Int, readingOnly: Bool = false
) -> String {
let whiteList = "你他妳她祢衪它牠再在"
var arrNodes: [Megrez.NodeAnchor] = []
var arrNodes: [Megrez.Compositor.Node] = []
var intLength = 0
for theNodeAnchor in walkedAnchors {
for theNodeAnchor in walkedNodes {
arrNodes.append(theNodeAnchor)
intLength += theNodeAnchor.spanLength
if intLength >= cursorIndex {
@ -154,7 +152,7 @@ extension vChewing {
arrNodes = Array(arrNodes.reversed())
let kvCurrent = arrNodes[0].node.currentPair
let kvCurrent = arrNodes[0].currentPair
guard !kvCurrent.key.contains("_") else {
return ""
}
@ -183,7 +181,7 @@ extension vChewing {
!kvPrevious.key.contains("_"),
kvPrevious.key.split(separator: "-").count == kvPrevious.value.count
{
kvPrevious = arrNodes[1].node.currentPair
kvPrevious = arrNodes[1].currentPair
readingStack = kvPrevious.key + readingStack
}
@ -191,7 +189,7 @@ extension vChewing {
!kvAnterior.key.contains("_"),
kvAnterior.key.split(separator: "-").count == kvAnterior.value.count
{
kvAnterior = arrNodes[2].node.currentPair
kvAnterior = arrNodes[2].currentPair
readingStack = kvAnterior.key + readingStack
}

View File

@ -184,7 +184,7 @@ enum mgrLangModel {
(mode == InputMode.imeModeCHT)
? gLangModelCHT.unigramsFor(key: unigramKey) : gLangModelCHS.unigramsFor(key: unigramKey)
for unigram in unigrams {
if unigram.keyValue.value == userPhrase {
if unigram.value == userPhrase {
return true
}
}