Repo // Use KeyValuePaired as candidate unit.

This commit is contained in:
ShikiSuen 2022-07-11 23:03:41 +08:00
parent 5f654c842e
commit 828575a08a
11 changed files with 49 additions and 50 deletions

View File

@ -139,9 +139,9 @@ enum InputState {
/// 西 .NotEmpty
class AssociatedPhrases: InputStateProtocol {
public var type: StateType { .ofAssociatedPhrases }
private(set) var candidates: [String] = []
private(set) var candidates: [(String, String)] = []
private(set) var isTypingVertical: Bool = false
init(candidates: [String], isTypingVertical: Bool) {
init(candidates: [(String, String)], isTypingVertical: Bool) {
self.candidates = candidates
self.isTypingVertical = isTypingVertical
}
@ -407,10 +407,10 @@ enum InputState {
/// .ChoosingCandidate: 使
class ChoosingCandidate: NotEmpty {
override public var type: StateType { .ofChooseCandidate }
private(set) var candidates: [String]
private(set) var candidates: [(String, String)]
private(set) var isTypingVertical: Bool
init(composingBuffer: String, cursorIndex: Int, candidates: [String], isTypingVertical: Bool) {
init(composingBuffer: String, cursorIndex: Int, candidates: [(String, String)], isTypingVertical: Bool) {
self.candidates = candidates
self.isTypingVertical = isTypingVertical
super.init(composingBuffer: composingBuffer, cursorIndex: cursorIndex)
@ -432,7 +432,7 @@ enum InputState {
self.node = node
let candidates = node.children?.map(\.title) ?? [String]()
super.init(
composingBuffer: "", cursorIndex: 0, candidates: candidates,
composingBuffer: "", cursorIndex: 0, candidates: candidates.map { ("", $0) },
isTypingVertical: isTypingVertical
)
}

View File

@ -149,10 +149,10 @@ class KeyHandler {
/// - Parameter key:
/// - Returns:
/// nil
func buildAssociatePhraseArray(withKey key: String) -> [String] {
var arrResult: [String] = []
func buildAssociatePhraseArray(withKey key: String) -> [(String, String)] {
var arrResult: [(String, String)] = []
if currentLM.hasAssociatedPhrasesFor(key: key) {
arrResult.append(contentsOf: currentLM.associatedPhrasesFor(key: key))
arrResult = currentLM.associatedPhrasesFor(key: key).map { ("", $0) }
}
return arrResult
}
@ -162,21 +162,22 @@ class KeyHandler {
/// - Parameters:
/// - value:
/// - respectCursorPushing: true
func fixNode(value: String, respectCursorPushing: Bool = 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), compositorLength))
//
let selectedNode: Megrez.NodeAnchor = compositor.fixNodeSelectedCandidate(value, at: adjustedCursor)
let selectedNode: Megrez.NodeAnchor = compositor.fixNodeWithCandidate(theCandidate, at: adjustedCursor)
//
if !mgrPrefs.useSCPCTypingMode {
var addToUserOverrideModel = true
//
if selectedNode.spanLength != value.count {
if selectedNode.spanLength != theCandidate.value.count {
IME.prtDebugIntel("UOM: SpanningLength != value.count, dismissing.")
addToUserOverrideModel = false
}
if addToUserOverrideModel {
// SymbolLM Score -12
if selectedNode.node.scoreFor(candidate: value) <= -12 {
if selectedNode.node.scoreForPaired(candidate: theCandidate) <= -12 {
IME.prtDebugIntel("UOM: Score <= -12, dismissing.")
addToUserOverrideModel = false
}
@ -186,7 +187,7 @@ class KeyHandler {
//
//
currentUOM.observe(
walkedAnchors: walkedAnchors, cursorIndex: adjustedCursor, candidate: value,
walkedAnchors: walkedAnchors, cursorIndex: adjustedCursor, candidate: theCandidate.value,
timestamp: NSDate().timeIntervalSince1970
)
}
@ -211,21 +212,21 @@ class KeyHandler {
for anchor in walkedAnchors {
if index >= width - kMaxComposingBufferNeedsToWalkSize { break }
if anchor.node.score < Megrez.Node.kSelectedCandidateScore {
compositor.fixNodeSelectedCandidate(anchor.node.currentPair.value, at: index + anchor.spanLength)
compositor.fixNodeWithCandidate(anchor.node.currentPair, at: index + anchor.spanLength)
}
index += anchor.spanLength
}
}
///
func getCandidatesArray(fixOrder: Bool = true) -> [String] {
///
func getCandidatesArray(fixOrder: Bool = true) -> [(String, String)] {
var arrAnchors: [Megrez.NodeAnchor] = rawAnchorsOfNodes
var arrCandidates: [String] = []
var arrCandidates: [Megrez.KeyValuePaired] = .init()
/// nodes
///
///
if arrAnchors.isEmpty { return arrCandidates }
if arrAnchors.isEmpty { return .init() }
//
arrAnchors = arrAnchors.stableSort { $0.keyLength > $1.keyLength }
@ -235,19 +236,19 @@ class KeyHandler {
// / JIS
//
//
arrCandidates.append(currentCandidate.value)
arrCandidates.append(.init(key: currentCandidate.key, value: currentCandidate.value))
}
// 調
if !mgrPrefs.fetchSuggestionsFromUserOverrideModel || mgrPrefs.useSCPCTypingMode || fixOrder {
return arrCandidates
return arrCandidates.map { ($0.key, $0.value) }
}
let arrSuggestedUnigrams: [Megrez.Unigram] = fetchSuggestedCandidates().stableSort { $0.score > $1.score }
let arrSuggestedCandidates: [String] = arrSuggestedUnigrams.map(\.keyValue.value)
let arrSuggestedCandidates: [Megrez.KeyValuePaired] = arrSuggestedUnigrams.map(\.keyValue)
arrCandidates = arrSuggestedCandidates.filter { arrCandidates.contains($0) } + arrCandidates
arrCandidates = arrCandidates.deduplicate
arrCandidates = arrCandidates.stableSort { $0.count > $1.count }
return arrCandidates
arrCandidates = arrCandidates.stableSort { $0.key.split(separator: "-").count > $1.key.split(separator: "-").count }
return arrCandidates.map { ($0.key, $0.value) }
}
///

View File

@ -274,7 +274,7 @@ extension KeyHandler {
// MARK: End Key
var candidates: [String]!
var candidates: [(String, String)]!
if let state = state as? InputState.ChoosingCandidate {
candidates = state.candidates

View File

@ -225,7 +225,7 @@ extension KeyHandler {
)
if choosingCandidates.candidates.count == 1 {
clear()
let text: String = choosingCandidates.candidates.first ?? ""
let text: String = choosingCandidates.candidates.first?.1 ?? ""
stateCallback(InputState.Committing(textToCommit: text))
if !mgrPrefs.associatedPhrasesEnabled {

View File

@ -330,8 +330,8 @@ extension KeyHandler {
)
if candidateState.candidates.count == 1 {
clear()
if let strtextToCommit: String = candidateState.candidates.first {
stateCallback(InputState.Committing(textToCommit: strtextToCommit))
if let candidateToCommit: (String, String) = candidateState.candidates.first {
stateCallback(InputState.Committing(textToCommit: candidateToCommit.1))
stateCallback(InputState.Empty())
} else {
stateCallback(candidateState)
@ -802,7 +802,7 @@ extension KeyHandler {
}
let currentNode = currentAnchor.node
let currentValue = currentNode.currentPair.value
let currentPaired: Megrez.KeyValuePaired = currentNode.currentPair
var currentIndex = 0
if currentNode.score < Megrez.Node.kSelectedCandidateScore {
@ -814,14 +814,14 @@ extension KeyHandler {
/// 使
/// (Shift+)Tab ()
/// Shift(+CMD)+Space Tab
if candidates[0] == currentValue {
if candidates[0].0 == currentPaired.key, candidates[0].1 == currentPaired.value {
///
///
currentIndex = reverseModifier ? candidates.count - 1 : 1
}
} else {
for candidate in candidates {
if candidate == currentValue {
if candidate.0 == currentPaired.key, candidate.1 == currentPaired.value {
if reverseModifier {
if currentIndex == 0 {
currentIndex = candidates.count - 1
@ -841,7 +841,7 @@ extension KeyHandler {
currentIndex = 0
}
fixNode(value: candidates[currentIndex], respectCursorPushing: false)
fixNode(candidate: candidates[currentIndex], respectCursorPushing: false)
stateCallback(buildInputtingState)
return true

View File

@ -81,7 +81,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
}
func ctlCandidate(_ controller: ctlCandidate, candidateAtIndex index: Int)
-> String
-> (String, String)
{
_ = controller //
if let state = state as? InputState.ChoosingCandidate {
@ -89,7 +89,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
} else if let state = state as? InputState.AssociatedPhrases {
return state.candidates[index]
}
return ""
return ("", "")
}
func ctlCandidate(_ controller: ctlCandidate, didSelectCandidateAtIndex index: Int) {
@ -112,7 +112,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
if let state = state as? InputState.ChoosingCandidate {
let selectedValue = state.candidates[index]
keyHandler.fixNode(value: selectedValue, respectCursorPushing: true)
keyHandler.fixNode(candidate: selectedValue, respectCursorPushing: true)
let inputting = keyHandler.buildInputtingState
@ -137,10 +137,10 @@ extension ctlInputMethod: ctlCandidateDelegate {
if let state = state as? InputState.AssociatedPhrases {
let selectedValue = state.candidates[index]
handle(state: InputState.Committing(textToCommit: selectedValue))
handle(state: InputState.Committing(textToCommit: selectedValue.1))
if mgrPrefs.associatedPhrasesEnabled,
let associatePhrases = keyHandler.buildAssociatePhraseState(
withKey: selectedValue, isTypingVertical: state.isTypingVertical
withKey: selectedValue.1, isTypingVertical: state.isTypingVertical
), !associatePhrases.candidates.isEmpty
{
handle(state: associatePhrases)

View File

@ -55,7 +55,7 @@ extension ctlInputMethod {
return false
}
var isCandidateWindowVertical: Bool {
var candidates: [String] = []
var candidates: [(String, String)] = .init()
if let state = state as? InputState.ChoosingCandidate {
candidates = state.candidates
} else if let state = state as? InputState.AssociatedPhrases {
@ -63,13 +63,11 @@ extension ctlInputMethod {
}
if isTypingVertical { return true }
// 使
candidates.sort {
$0.count > $1.count
}
//
// 使
// Beer emoji
let maxCandidatesPerPage = mgrPrefs.candidateKeys.count
let firstPageCandidates = candidates[0..<min(maxCandidatesPerPage, candidates.count)]
let firstPageCandidates = candidates[0..<min(maxCandidatesPerPage, candidates.count)].map(\.1)
return firstPageCandidates.joined().count > Int(round(Double(maxCandidatesPerPage) * 1.8))
// true
}

View File

@ -40,7 +40,7 @@ public class CandidateKeyLabel: NSObject {
public protocol ctlCandidateDelegate: AnyObject {
func candidateCountForController(_ controller: ctlCandidate) -> Int
func ctlCandidate(_ controller: ctlCandidate, candidateAtIndex index: Int)
-> String
-> (String, String)
func ctlCandidate(
_ controller: ctlCandidate, didSelectCandidateAtIndex index: Int
)

View File

@ -559,7 +559,7 @@ extension ctlCandidateUniversal {
}
candidateView.set(keyLabelFont: keyLabelFont, candidateFont: candidateFont)
var candidates = [String]()
var candidates = [(String, String)]()
let count = delegate.candidateCountForController(self)
let keyLabelCount = keyLabels.count
@ -569,7 +569,7 @@ extension ctlCandidateUniversal {
candidates.append(candidate)
}
candidateView.set(
keyLabels: keyLabels.map(\.displayedText), displayedCandidates: candidates
keyLabels: keyLabels.map(\.displayedText), displayedCandidates: candidates.map(\.1)
)
var newSize = candidateView.sizeForView
var frameRect = candidateView.frame

View File

@ -365,7 +365,7 @@ class KeyHandlerTestsNormalCHS: XCTestCase {
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
if let state = state as? InputState.ChoosingCandidate {
XCTAssertTrue(state.candidates.contains(""))
XCTAssertTrue(state.candidates.map(\.1).contains(""))
}
mgrPrefs.halfWidthPunctuationEnabled = enabled
}
@ -993,7 +993,7 @@ class KeyHandlerTestsNormalCHS: XCTestCase {
XCTAssertEqual(state.composingBuffer, "")
XCTAssertEqual(state.cursorIndex, 1)
let candidates = state.candidates
XCTAssertTrue(candidates.contains(""))
XCTAssertTrue(candidates.map(\.1).contains(""))
}
}
@ -1030,7 +1030,7 @@ class KeyHandlerTestsNormalCHS: XCTestCase {
XCTAssertEqual(state.composingBuffer, "")
XCTAssertEqual(state.cursorIndex, 1)
let candidates = state.candidates
XCTAssertTrue(candidates.contains(""))
XCTAssertTrue(candidates.map(\.1).contains(""))
}
mgrPrefs.chooseCandidateUsingSpace = enabled
}

View File

@ -85,7 +85,7 @@ class KeyHandlerTestsSCPCCHT: XCTestCase {
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
if let state = state as? InputState.ChoosingCandidate {
XCTAssertTrue(state.candidates.contains(""))
XCTAssertTrue(state.candidates.map(\.1).contains(""))
}
}
@ -238,7 +238,7 @@ class KeyHandlerTestsSCPCCHT: XCTestCase {
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
if let state = state as? InputState.ChoosingCandidate {
XCTAssertTrue(state.candidates.contains(""))
XCTAssertTrue(state.candidates.map(\.1).contains(""))
}
}
@ -315,7 +315,7 @@ class KeyHandlerTestsSCPCCHT: XCTestCase {
print("\(state)")
// XCTAssertTrue(state is InputState.AssociatedPhrases, "\(state)")
// if let state = state as? InputState.AssociatedPhrases {
// XCTAssertTrue(state.candidates.contains(""))
// XCTAssertTrue(state.candidates.map(\.1).contains(""))
// }
mgrPrefs.associatedPhrasesEnabled = enabled
}