SessionCtl // Patch fixIndexForIMKCandidates(), etc.
This commit is contained in:
parent
f346ff198e
commit
234c2656b7
|
@ -71,8 +71,8 @@ public protocol InputHandlerDelegate {
|
||||||
func candidateSelectionConfirmedByInputHandler(at index: Int)
|
func candidateSelectionConfirmedByInputHandler(at index: Int)
|
||||||
func setInlineDisplayWithCursor()
|
func setInlineDisplayWithCursor()
|
||||||
func updatePopupDisplayWithCursor()
|
func updatePopupDisplayWithCursor()
|
||||||
func performUserPhraseOperation(addToFilter: Bool)
|
func performUserPhraseOperation(addToFilter: Bool) -> Bool
|
||||||
-> Bool
|
func deductCandidateIndex(from candidateString: String) -> Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - 核心 (Kernel).
|
// MARK: - 核心 (Kernel).
|
||||||
|
|
|
@ -74,13 +74,11 @@ public extension SessionCtl {
|
||||||
/// IMK 選字窗限定函式,只要選字窗內的高亮內容選擇出現變化了、就會呼叫這個函式。
|
/// IMK 選字窗限定函式,只要選字窗內的高亮內容選擇出現變化了、就會呼叫這個函式。
|
||||||
/// - Parameter currentSelection: 已經高亮選中的候選字詞內容。
|
/// - Parameter currentSelection: 已經高亮選中的候選字詞內容。
|
||||||
override func candidateSelectionChanged(_ currentSelection: NSAttributedString!) {
|
override func candidateSelectionChanged(_ currentSelection: NSAttributedString!) {
|
||||||
|
guard state.isCandidateContainer else { return }
|
||||||
guard let candidateString = currentSelection?.string, !candidateString.isEmpty else { return }
|
guard let candidateString = currentSelection?.string, !candidateString.isEmpty else { return }
|
||||||
// Handle candidatePairHighlightChanged().
|
// Handle candidatePairHighlightChanged().
|
||||||
var indexDeducted = 0
|
let indexDeducted = deductCandidateIndex(from: candidateString)
|
||||||
fixIndexForIMKCandidates(&indexDeducted, source: candidateString)
|
candidatePairHighlightChanged(at: indexDeducted)
|
||||||
if state.type == .ofCandidates {
|
|
||||||
candidatePairHighlightChanged(at: indexDeducted)
|
|
||||||
}
|
|
||||||
let realCandidateString = state.candidates[indexDeducted].value
|
let realCandidateString = state.candidates[indexDeducted].value
|
||||||
// Handle IMK Annotation... We just use this to tell Apple that this never works in IMKCandidates.
|
// Handle IMK Annotation... We just use this to tell Apple that this never works in IMKCandidates.
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [self] in
|
||||||
|
@ -97,6 +95,7 @@ public extension SessionCtl {
|
||||||
/// - Remark: 不要被 IMK 的 API 命名方式困惑到。這其實是 Confirm Selection 確認選字。
|
/// - Remark: 不要被 IMK 的 API 命名方式困惑到。這其實是 Confirm Selection 確認選字。
|
||||||
/// - Parameter candidateString: 已經確認的候選字詞內容。
|
/// - Parameter candidateString: 已經確認的候選字詞內容。
|
||||||
override func candidateSelected(_ candidateString: NSAttributedString!) {
|
override func candidateSelected(_ candidateString: NSAttributedString!) {
|
||||||
|
guard state.isCandidateContainer else { return }
|
||||||
let candidateString: String = candidateString?.string ?? ""
|
let candidateString: String = candidateString?.string ?? ""
|
||||||
if state.type == .ofAssociates {
|
if state.type == .ofAssociates {
|
||||||
// 聯想詞的 Shift+選字鍵的處理已經在其它位置實作完成。
|
// 聯想詞的 Shift+選字鍵的處理已經在其它位置實作完成。
|
||||||
|
@ -106,13 +105,18 @@ public extension SessionCtl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let indexDeducted = deductCandidateIndex(from: candidateString)
|
||||||
|
candidatePairSelectionConfirmed(at: indexDeducted)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deductCandidateIndex(from candidateString: String) -> Int {
|
||||||
var indexDeducted = 0
|
var indexDeducted = 0
|
||||||
|
|
||||||
// 分類符號選單不會出現同符異音項、不需要康熙 / JIS 轉換,所以使用簡化過的處理方式。
|
// 分類符號選單不會出現同符異音項、不需要康熙 / JIS 轉換,所以使用簡化過的處理方式。
|
||||||
func fixSymbolIndexForIMKCandidates() {
|
func fixSymbolIndexForIMKCandidates() {
|
||||||
for (i, neta) in state.candidates.enumerated() {
|
for (i, neta) in state.candidates.enumerated() {
|
||||||
if candidateString == neta.value {
|
if candidateString == neta.value {
|
||||||
indexDeducted = i
|
indexDeducted = min(i, state.candidates.count - 1)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +130,7 @@ public extension SessionCtl {
|
||||||
case .ofSymbolTable:
|
case .ofSymbolTable:
|
||||||
fixSymbolIndexForIMKCandidates()
|
fixSymbolIndexForIMKCandidates()
|
||||||
case .ofCandidates:
|
case .ofCandidates:
|
||||||
guard !state.candidates.isEmpty else { return }
|
guard !state.candidates.isEmpty else { break }
|
||||||
if state.candidates[0].keyArray.description.contains("_punctuation") {
|
if state.candidates[0].keyArray.description.contains("_punctuation") {
|
||||||
fixSymbolIndexForIMKCandidates() // 標點符號選單處理。
|
fixSymbolIndexForIMKCandidates() // 標點符號選單處理。
|
||||||
} else {
|
} else {
|
||||||
|
@ -134,11 +138,11 @@ public extension SessionCtl {
|
||||||
}
|
}
|
||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
candidatePairSelectionConfirmed(at: indexDeducted)
|
return indexDeducted
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解析 IMKCandidates 給出的資料參數,據此推算正確的被確認的候選字詞配對的編號。
|
/// 解析 IMKCandidates 給出的資料參數,據此推算正確的被確認的候選字詞配對的編號。
|
||||||
/// - Remark: 該函式當中的不可列印字元`\u{1A`是用來方便在 IMEState 當中用來分割資料的。
|
/// - Remark: 該函式當中的不可列印字元`\u{1A}`是用來方便在 IMEState 當中用來分割資料的。
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - prefix: 前綴(僅限於聯想詞模式)。
|
/// - prefix: 前綴(僅限於聯想詞模式)。
|
||||||
/// - indexToFix: 要糾正的編號變數。
|
/// - indexToFix: 要糾正的編號變數。
|
||||||
|
@ -146,8 +150,10 @@ public extension SessionCtl {
|
||||||
private func fixIndexForIMKCandidates(
|
private func fixIndexForIMKCandidates(
|
||||||
_ indexDeducted: inout Int, prefix: String = "", source candidateString: String
|
_ indexDeducted: inout Int, prefix: String = "", source candidateString: String
|
||||||
) {
|
) {
|
||||||
|
guard state.isCandidateContainer else { return }
|
||||||
guard let separator = inputHandler?.keySeparator else { return }
|
guard let separator = inputHandler?.keySeparator else { return }
|
||||||
let candidates = state.candidates
|
let candidates = state.candidates
|
||||||
|
let maxIndex = candidates.count - 1
|
||||||
for (i, neta) in candidates.enumerated() {
|
for (i, neta) in candidates.enumerated() {
|
||||||
let theConverted = ChineseConverter.kanjiConversionIfRequired(neta.value)
|
let theConverted = ChineseConverter.kanjiConversionIfRequired(neta.value)
|
||||||
let netaShown = (neta.value == theConverted)
|
let netaShown = (neta.value == theConverted)
|
||||||
|
@ -169,11 +175,11 @@ public extension SessionCtl {
|
||||||
: neta.keyArray.joined(separator: separator))
|
: neta.keyArray.joined(separator: separator))
|
||||||
let netaShownWithPronunciation = "\(netaShown)\u{17}(\(reading))"
|
let netaShownWithPronunciation = "\(netaShown)\u{17}(\(reading))"
|
||||||
if candidateString == prefix + netaShownWithPronunciation {
|
if candidateString == prefix + netaShownWithPronunciation {
|
||||||
indexDeducted = i
|
indexDeducted = min(i, maxIndex)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if candidateString == prefix + netaShown {
|
if candidateString == prefix + netaShown {
|
||||||
indexDeducted = i
|
indexDeducted = min(i, maxIndex)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue