IMEState // Ensure lowerCamelCase.
This commit is contained in:
parent
75193a32fd
commit
e85e3382fe
|
@ -51,7 +51,7 @@ public protocol IMEStateProtocol {
|
||||||
/// 不需要再在某個狀態下為了該狀態不需要的變數與常數的處置策略而煩惱。
|
/// 不需要再在某個狀態下為了該狀態不需要的變數與常數的處置策略而煩惱。
|
||||||
///
|
///
|
||||||
/// 對 IMEState 型別下的諸多狀態的切換,應以生成新副本來取代舊有副本的形式來完
|
/// 對 IMEState 型別下的諸多狀態的切換,應以生成新副本來取代舊有副本的形式來完
|
||||||
/// 成。唯一例外是 IMEState.Marking、擁有可以將自身轉變為 IMEState.Inputting
|
/// 成。唯一例外是 IMEState.ofMarking、擁有可以將自身轉變為 IMEState.ofInputting
|
||||||
/// 的成員函式,但也只是生成副本、來交給輸入法控制器來處理而已。每個狀態都有
|
/// 的成員函式,但也只是生成副本、來交給輸入法控制器來處理而已。每個狀態都有
|
||||||
/// 各自的構造器 (Constructor)。
|
/// 各自的構造器 (Constructor)。
|
||||||
///
|
///
|
||||||
|
@ -91,23 +91,23 @@ public struct IMEState: IMEStateProtocol {
|
||||||
// MARK: - 針對不同的狀態,規定不同的構造器
|
// MARK: - 針對不同的狀態,規定不同的構造器
|
||||||
|
|
||||||
extension IMEState {
|
extension IMEState {
|
||||||
public static func Deactivated() -> IMEState { .init(type: .ofDeactivated) }
|
public static func ofDeactivated() -> IMEState { .init(type: .ofDeactivated) }
|
||||||
public static func Empty() -> IMEState { .init(type: .ofEmpty) }
|
public static func ofEmpty() -> IMEState { .init(type: .ofEmpty) }
|
||||||
public static func Abortion() -> IMEState { .init(type: .ofAbortion) }
|
public static func ofAbortion() -> IMEState { .init(type: .ofAbortion) }
|
||||||
public static func Committing(textToCommit: String) -> IMEState {
|
public static func ofCommitting(textToCommit: String) -> IMEState {
|
||||||
var result = IMEState(type: .ofCommitting)
|
var result = IMEState(type: .ofCommitting)
|
||||||
result.data.textToCommit = textToCommit
|
result.data.textToCommit = textToCommit
|
||||||
ChineseConverter.ensureCurrencyNumerals(target: &result.data.textToCommit)
|
ChineseConverter.ensureCurrencyNumerals(target: &result.data.textToCommit)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func Associates(candidates: [(String, String)]) -> IMEState {
|
public static func ofAssociates(candidates: [(String, String)]) -> IMEState {
|
||||||
var result = IMEState(type: .ofAssociates)
|
var result = IMEState(type: .ofAssociates)
|
||||||
result.data.candidates = candidates
|
result.data.candidates = candidates
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func NotEmpty(displayTextSegments: [String], cursor: Int) -> IMEState {
|
public static func ofNotEmpty(displayTextSegments: [String], cursor: Int) -> IMEState {
|
||||||
var result = IMEState(type: .ofNotEmpty)
|
var result = IMEState(type: .ofNotEmpty)
|
||||||
// 注意資料的設定順序,一定得先設定 displayTextSegments。
|
// 注意資料的設定順序,一定得先設定 displayTextSegments。
|
||||||
result.data.displayTextSegments = displayTextSegments
|
result.data.displayTextSegments = displayTextSegments
|
||||||
|
@ -115,18 +115,18 @@ extension IMEState {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func Inputting(displayTextSegments: [String], cursor: Int) -> IMEState {
|
public static func ofInputting(displayTextSegments: [String], cursor: Int) -> IMEState {
|
||||||
var result = IMEState.NotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
|
var result = IMEState.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
|
||||||
result.type = .ofInputting
|
result.type = .ofInputting
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func Marking(
|
public static func ofMarking(
|
||||||
displayTextSegments: [String], markedReadings: [String], cursor: Int, marker: Int
|
displayTextSegments: [String], markedReadings: [String], cursor: Int, marker: Int
|
||||||
)
|
)
|
||||||
-> IMEState
|
-> IMEState
|
||||||
{
|
{
|
||||||
var result = IMEState.NotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
|
var result = IMEState.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
|
||||||
result.type = .ofMarking
|
result.type = .ofMarking
|
||||||
result.data.marker = marker
|
result.data.marker = marker
|
||||||
result.data.markedReadings = markedReadings
|
result.data.markedReadings = markedReadings
|
||||||
|
@ -134,15 +134,15 @@ extension IMEState {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func Candidates(candidates: [(String, String)], displayTextSegments: [String], cursor: Int) -> IMEState
|
public static func ofCandidates(candidates: [(String, String)], displayTextSegments: [String], cursor: Int) -> IMEState
|
||||||
{
|
{
|
||||||
var result = IMEState.NotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
|
var result = IMEState.ofNotEmpty(displayTextSegments: displayTextSegments, cursor: cursor)
|
||||||
result.type = .ofCandidates
|
result.type = .ofCandidates
|
||||||
result.data.candidates = candidates
|
result.data.candidates = candidates
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func SymbolTable(node: SymbolNode) -> IMEState {
|
public static func ofSymbolTable(node: SymbolNode) -> IMEState {
|
||||||
var result = IMEState(type: .ofNotEmpty, node: node)
|
var result = IMEState(type: .ofNotEmpty, node: node)
|
||||||
result.type = .ofSymbolTable
|
result.type = .ofSymbolTable
|
||||||
return result
|
return result
|
||||||
|
@ -156,7 +156,7 @@ extension IMEState {
|
||||||
public var candidates: [(String, String)] { data.candidates }
|
public var candidates: [(String, String)] { data.candidates }
|
||||||
public var convertedToInputting: IMEState {
|
public var convertedToInputting: IMEState {
|
||||||
if type == .ofInputting { return self }
|
if type == .ofInputting { return self }
|
||||||
var result = IMEState.Inputting(displayTextSegments: data.displayTextSegments, cursor: data.cursor)
|
var result = IMEState.ofInputting(displayTextSegments: data.displayTextSegments, cursor: data.cursor)
|
||||||
result.tooltip = data.tooltipBackupForInputting
|
result.tooltip = data.tooltipBackupForInputting
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,12 @@ extension KeyHandler {
|
||||||
// 就將當前的組字緩衝區析構處理、強制重設輸入狀態。
|
// 就將當前的組字緩衝區析構處理、強制重設輸入狀態。
|
||||||
// 否則,一個本不該出現的真空組字緩衝區會使前後方向鍵與 BackSpace 鍵失靈。
|
// 否則,一個本不該出現的真空組字緩衝區會使前後方向鍵與 BackSpace 鍵失靈。
|
||||||
// 所以這裡需要對 compositor.isEmpty 做判定。
|
// 所以這裡需要對 compositor.isEmpty 做判定。
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
} else {
|
} else {
|
||||||
stateCallback(buildInputtingState)
|
stateCallback(buildInputtingState)
|
||||||
}
|
}
|
||||||
if state.type == .ofSymbolTable, let nodePrevious = state.node.previous, let _ = nodePrevious.children {
|
if state.type == .ofSymbolTable, let nodePrevious = state.node.previous, let _ = nodePrevious.children {
|
||||||
stateCallback(IMEState.SymbolTable(node: nodePrevious))
|
stateCallback(IMEState.ofSymbolTable(node: nodePrevious))
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ extension KeyHandler {
|
||||||
|
|
||||||
if input.isEnter {
|
if input.isEnter {
|
||||||
if state.type == .ofAssociates, !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter {
|
if state.type == .ofAssociates, !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter {
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
delegate?.keyHandler(
|
delegate?.keyHandler(
|
||||||
|
@ -323,9 +323,9 @@ extension KeyHandler {
|
||||||
didSelectCandidateAt: candidateIndex,
|
didSelectCandidateAt: candidateIndex,
|
||||||
ctlCandidate: ctlCandidateCurrent
|
ctlCandidate: ctlCandidateCurrent
|
||||||
)
|
)
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
return handle(
|
return handle(
|
||||||
input: input, state: IMEState.Empty(), stateCallback: stateCallback, errorCallback: errorCallback
|
input: input, state: IMEState.ofEmpty(), stateCallback: stateCallback, errorCallback: errorCallback
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -100,7 +100,7 @@ extension KeyHandler {
|
||||||
switch compositor.isEmpty {
|
switch compositor.isEmpty {
|
||||||
case false: stateCallback(buildInputtingState)
|
case false: stateCallback(buildInputtingState)
|
||||||
case true:
|
case true:
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
}
|
}
|
||||||
return true // 向 IMK 報告說這個按鍵訊號已經被輸入法攔截處理了。
|
return true // 向 IMK 報告說這個按鍵訊號已經被輸入法攔截處理了。
|
||||||
}
|
}
|
||||||
|
@ -130,16 +130,16 @@ extension KeyHandler {
|
||||||
if candidateState.candidates.count == 1, let firstCandidate = candidateState.candidates.first {
|
if candidateState.candidates.count == 1, let firstCandidate = candidateState.candidates.first {
|
||||||
let reading: String = firstCandidate.0
|
let reading: String = firstCandidate.0
|
||||||
let text: String = firstCandidate.1
|
let text: String = firstCandidate.1
|
||||||
stateCallback(IMEState.Committing(textToCommit: text))
|
stateCallback(IMEState.ofCommitting(textToCommit: text))
|
||||||
|
|
||||||
if !mgrPrefs.associatedPhrasesEnabled {
|
if !mgrPrefs.associatedPhrasesEnabled {
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
} else {
|
} else {
|
||||||
let associatedPhrases =
|
let associatedPhrases =
|
||||||
buildAssociatePhraseState(
|
buildAssociatePhraseState(
|
||||||
withPair: .init(key: reading, value: text)
|
withPair: .init(key: reading, value: text)
|
||||||
)
|
)
|
||||||
stateCallback(associatedPhrases.candidates.isEmpty ? IMEState.Empty() : associatedPhrases)
|
stateCallback(associatedPhrases.candidates.isEmpty ? IMEState.ofEmpty() : associatedPhrases)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stateCallback(candidateState)
|
stateCallback(candidateState)
|
||||||
|
|
|
@ -68,7 +68,7 @@ extension KeyHandler {
|
||||||
// 略過對 BackSpace 的處理。
|
// 略過對 BackSpace 的處理。
|
||||||
} else if input.isCapsLockOn || input.isASCIIModeInput {
|
} else if input.isCapsLockOn || input.isASCIIModeInput {
|
||||||
// 但願能夠處理這種情況下所有可能的按鍵組合。
|
// 但願能夠處理這種情況下所有可能的按鍵組合。
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
|
|
||||||
// 字母鍵摁 Shift 的話,無須額外處理,因為直接就會敲出大寫字母。
|
// 字母鍵摁 Shift 的話,無須額外處理,因為直接就會敲出大寫字母。
|
||||||
if input.isUpperCaseASCIILetterKey {
|
if input.isUpperCaseASCIILetterKey {
|
||||||
|
@ -82,8 +82,8 @@ extension KeyHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 將整個組字區的內容遞交給客體應用。
|
// 將整個組字區的內容遞交給客體應用。
|
||||||
stateCallback(IMEState.Committing(textToCommit: inputText.lowercased()))
|
stateCallback(IMEState.ofCommitting(textToCommit: inputText.lowercased()))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -97,9 +97,9 @@ extension KeyHandler {
|
||||||
if !(state.type == .ofCandidates || state.type == .ofAssociates
|
if !(state.type == .ofCandidates || state.type == .ofAssociates
|
||||||
|| state.type == .ofSymbolTable)
|
|| state.type == .ofSymbolTable)
|
||||||
{
|
{
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
stateCallback(IMEState.Committing(textToCommit: inputText.lowercased()))
|
stateCallback(IMEState.ofCommitting(textToCommit: inputText.lowercased()))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ extension KeyHandler {
|
||||||
) {
|
) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,10 +157,10 @@ extension KeyHandler {
|
||||||
if compositor.cursor >= compositor.length {
|
if compositor.cursor >= compositor.length {
|
||||||
let displayedText = state.displayedText
|
let displayedText = state.displayedText
|
||||||
if !displayedText.isEmpty {
|
if !displayedText.isEmpty {
|
||||||
stateCallback(IMEState.Committing(textToCommit: displayedText))
|
stateCallback(IMEState.ofCommitting(textToCommit: displayedText))
|
||||||
}
|
}
|
||||||
stateCallback(IMEState.Committing(textToCommit: " "))
|
stateCallback(IMEState.ofCommitting(textToCommit: " "))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
} else if currentLM.hasUnigramsFor(key: " ") {
|
} else if currentLM.hasUnigramsFor(key: " ") {
|
||||||
compositor.insertKey(" ")
|
compositor.insertKey(" ")
|
||||||
walk()
|
walk()
|
||||||
|
@ -297,7 +297,7 @@ extension KeyHandler {
|
||||||
// 於是這裡用「模擬一次 Enter 鍵的操作」使其代為執行這個 commit buffer 的動作。
|
// 於是這裡用「模擬一次 Enter 鍵的操作」使其代為執行這個 commit buffer 的動作。
|
||||||
// 這裡不需要該函式所傳回的 bool 結果,所以用「_ =」解消掉。
|
// 這裡不需要該函式所傳回的 bool 結果,所以用「_ =」解消掉。
|
||||||
_ = handleEnter(state: state, stateCallback: stateCallback)
|
_ = handleEnter(state: state, stateCallback: stateCallback)
|
||||||
stateCallback(IMEState.SymbolTable(node: SymbolNode.root))
|
stateCallback(IMEState.ofSymbolTable(node: SymbolNode.root))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,9 +312,9 @@ extension KeyHandler {
|
||||||
let string = NSMutableString(string: stringRAW)
|
let string = NSMutableString(string: stringRAW)
|
||||||
CFStringTransform(string, nil, kCFStringTransformFullwidthHalfwidth, true)
|
CFStringTransform(string, nil, kCFStringTransformFullwidthHalfwidth, true)
|
||||||
stateCallback(
|
stateCallback(
|
||||||
IMEState.Committing(textToCommit: mgrPrefs.halfWidthPunctuationEnabled ? stringRAW : string as String)
|
IMEState.ofCommitting(textToCommit: mgrPrefs.halfWidthPunctuationEnabled ? stringRAW : string as String)
|
||||||
)
|
)
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,8 +359,8 @@ extension KeyHandler {
|
||||||
/// 該功能僅可在當前組字區沒有任何內容的時候使用。
|
/// 該功能僅可在當前組字區沒有任何內容的時候使用。
|
||||||
if state.type == .ofEmpty {
|
if state.type == .ofEmpty {
|
||||||
if input.isSpace, !input.isOptionHold, !input.isControlHold, !input.isCommandHold {
|
if input.isSpace, !input.isOptionHold, !input.isControlHold, !input.isCommandHold {
|
||||||
stateCallback(IMEState.Committing(textToCommit: input.isShiftHold ? " " : " "))
|
stateCallback(IMEState.ofCommitting(textToCommit: input.isShiftHold ? " " : " "))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,14 +371,14 @@ extension KeyHandler {
|
||||||
if input.isShiftHold { // 這裡先不要判斷 isOptionHold。
|
if input.isShiftHold { // 這裡先不要判斷 isOptionHold。
|
||||||
switch mgrPrefs.upperCaseLetterKeyBehavior {
|
switch mgrPrefs.upperCaseLetterKeyBehavior {
|
||||||
case 1:
|
case 1:
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
stateCallback(IMEState.Committing(textToCommit: inputText.lowercased()))
|
stateCallback(IMEState.ofCommitting(textToCommit: inputText.lowercased()))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
case 2:
|
case 2:
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
stateCallback(IMEState.Committing(textToCommit: inputText.uppercased()))
|
stateCallback(IMEState.ofCommitting(textToCommit: inputText.uppercased()))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
default: // 包括 case 0,直接塞給組字區。
|
default: // 包括 case 0,直接塞給組字區。
|
||||||
let letter = "_letter_\(inputText)"
|
let letter = "_letter_\(inputText)"
|
||||||
|
|
|
@ -52,7 +52,7 @@ extension KeyHandler {
|
||||||
cursor += reading.count
|
cursor += reading.count
|
||||||
}
|
}
|
||||||
/// 這裡生成準備要拿來回呼的「正在輸入」狀態,但還不能立即使用,因為工具提示仍未完成。
|
/// 這裡生成準備要拿來回呼的「正在輸入」狀態,但還不能立即使用,因為工具提示仍未完成。
|
||||||
return IMEState.Inputting(displayTextSegments: displayTextSegments, cursor: cursor)
|
return IMEState.ofInputting(displayTextSegments: displayTextSegments, cursor: cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 生成「正在輸入」狀態。
|
/// 生成「正在輸入」狀態。
|
||||||
|
@ -97,7 +97,7 @@ extension KeyHandler {
|
||||||
state currentState: IMEStateProtocol,
|
state currentState: IMEStateProtocol,
|
||||||
isTypingVertical _: Bool = false
|
isTypingVertical _: Bool = false
|
||||||
) -> IMEState {
|
) -> IMEState {
|
||||||
IMEState.Candidates(
|
IMEState.ofCandidates(
|
||||||
candidates: getCandidatesArray(fixOrder: mgrPrefs.useFixecCandidateOrderOnSelection),
|
candidates: getCandidatesArray(fixOrder: mgrPrefs.useFixecCandidateOrderOnSelection),
|
||||||
displayTextSegments: compositor.walkedNodes.values,
|
displayTextSegments: compositor.walkedNodes.values,
|
||||||
cursor: currentState.data.cursor
|
cursor: currentState.data.cursor
|
||||||
|
@ -122,7 +122,7 @@ extension KeyHandler {
|
||||||
withPair pair: Megrez.Compositor.KeyValuePaired
|
withPair pair: Megrez.Compositor.KeyValuePaired
|
||||||
) -> IMEState {
|
) -> IMEState {
|
||||||
// 上一行必須要用驚嘆號,否則 Xcode 會誤導你砍掉某些實際上必需的語句。
|
// 上一行必須要用驚嘆號,否則 Xcode 會誤導你砍掉某些實際上必需的語句。
|
||||||
IMEState.Associates(
|
IMEState.ofAssociates(
|
||||||
candidates: buildAssociatePhraseArray(withPair: pair))
|
candidates: buildAssociatePhraseArray(withPair: pair))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ extension KeyHandler {
|
||||||
if isCursorCuttingChar(isMarker: true) {
|
if isCursorCuttingChar(isMarker: true) {
|
||||||
compositor.jumpCursorBySpan(to: .rear, isMarker: true)
|
compositor.jumpCursorBySpan(to: .rear, isMarker: true)
|
||||||
}
|
}
|
||||||
var marking = IMEState.Marking(
|
var marking = IMEState.ofMarking(
|
||||||
displayTextSegments: state.data.displayTextSegments,
|
displayTextSegments: state.data.displayTextSegments,
|
||||||
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
||||||
cursor: convertCursorForDisplay(compositor.cursor),
|
cursor: convertCursorForDisplay(compositor.cursor),
|
||||||
|
@ -219,7 +219,7 @@ extension KeyHandler {
|
||||||
if isCursorCuttingChar(isMarker: true) {
|
if isCursorCuttingChar(isMarker: true) {
|
||||||
compositor.jumpCursorBySpan(to: .front, isMarker: true)
|
compositor.jumpCursorBySpan(to: .front, isMarker: true)
|
||||||
}
|
}
|
||||||
var marking = IMEState.Marking(
|
var marking = IMEState.ofMarking(
|
||||||
displayTextSegments: state.data.displayTextSegments,
|
displayTextSegments: state.data.displayTextSegments,
|
||||||
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
||||||
cursor: convertCursorForDisplay(compositor.cursor),
|
cursor: convertCursorForDisplay(compositor.cursor),
|
||||||
|
@ -281,8 +281,8 @@ extension KeyHandler {
|
||||||
if candidateState.candidates.count == 1 {
|
if candidateState.candidates.count == 1 {
|
||||||
clear() // 這句不要砍,因為下文可能會回呼 candidateState。
|
clear() // 這句不要砍,因為下文可能會回呼 candidateState。
|
||||||
if let candidateToCommit: (String, String) = candidateState.candidates.first, !candidateToCommit.1.isEmpty {
|
if let candidateToCommit: (String, String) = candidateState.candidates.first, !candidateToCommit.1.isEmpty {
|
||||||
stateCallback(IMEState.Committing(textToCommit: candidateToCommit.1))
|
stateCallback(IMEState.ofCommitting(textToCommit: candidateToCommit.1))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
} else {
|
} else {
|
||||||
stateCallback(candidateState)
|
stateCallback(candidateState)
|
||||||
}
|
}
|
||||||
|
@ -305,8 +305,8 @@ extension KeyHandler {
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
guard state.type == .ofInputting else { return false }
|
guard state.type == .ofInputting else { return false }
|
||||||
|
|
||||||
stateCallback(IMEState.Committing(textToCommit: state.displayedText))
|
stateCallback(IMEState.ofCommitting(textToCommit: state.displayedText))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,8 +333,8 @@ extension KeyHandler {
|
||||||
displayedText = displayedText.replacingOccurrences(of: "-", with: " ")
|
displayedText = displayedText.replacingOccurrences(of: "-", with: " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
stateCallback(IMEState.Committing(textToCommit: displayedText))
|
stateCallback(IMEState.ofCommitting(textToCommit: displayedText))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,8 +369,8 @@ extension KeyHandler {
|
||||||
composed += key.contains("_") ? value : "<ruby>\(value)<rp>(</rp><rt>\(key)</rt><rp>)</rp></ruby>"
|
composed += key.contains("_") ? value : "<ruby>\(value)<rp>(</rp><rt>\(key)</rt><rp>)</rp></ruby>"
|
||||||
}
|
}
|
||||||
|
|
||||||
stateCallback(IMEState.Committing(textToCommit: composed))
|
stateCallback(IMEState.ofCommitting(textToCommit: composed))
|
||||||
stateCallback(IMEState.Empty())
|
stateCallback(IMEState.ofEmpty())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,13 +403,13 @@ extension KeyHandler {
|
||||||
stateCallback(buildInputtingState)
|
stateCallback(buildInputtingState)
|
||||||
return true
|
return true
|
||||||
case 1:
|
case 1:
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
return true
|
return true
|
||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.isShiftHold, input.isOptionHold {
|
if input.isShiftHold, input.isOptionHold {
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +432,7 @@ extension KeyHandler {
|
||||||
switch composer.isEmpty && compositor.isEmpty {
|
switch composer.isEmpty && compositor.isEmpty {
|
||||||
case false: stateCallback(buildInputtingState)
|
case false: stateCallback(buildInputtingState)
|
||||||
case true:
|
case true:
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -455,7 +455,7 @@ extension KeyHandler {
|
||||||
guard state.type == .ofInputting else { return false }
|
guard state.type == .ofInputting else { return false }
|
||||||
|
|
||||||
if input.isShiftHold {
|
if input.isShiftHold {
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,7 +478,7 @@ extension KeyHandler {
|
||||||
switch inputting.displayedText.isEmpty {
|
switch inputting.displayedText.isEmpty {
|
||||||
case false: stateCallback(inputting)
|
case false: stateCallback(inputting)
|
||||||
case true:
|
case true:
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -589,7 +589,7 @@ extension KeyHandler {
|
||||||
if mgrPrefs.escToCleanInputBuffer {
|
if mgrPrefs.escToCleanInputBuffer {
|
||||||
/// 若啟用了該選項,則清空組字器的內容與注拼槽的內容。
|
/// 若啟用了該選項,則清空組字器的內容與注拼槽的內容。
|
||||||
/// 此乃 macOS 內建注音輸入法預設之行為,但不太受 Windows 使用者群體之待見。
|
/// 此乃 macOS 內建注音輸入法預設之行為,但不太受 Windows 使用者群體之待見。
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
} else {
|
} else {
|
||||||
if composer.isEmpty { return true }
|
if composer.isEmpty { return true }
|
||||||
/// 如果注拼槽不是空的話,則清空之。
|
/// 如果注拼槽不是空的話,則清空之。
|
||||||
|
@ -597,7 +597,7 @@ extension KeyHandler {
|
||||||
switch compositor.isEmpty {
|
switch compositor.isEmpty {
|
||||||
case false: stateCallback(buildInputtingState)
|
case false: stateCallback(buildInputtingState)
|
||||||
case true:
|
case true:
|
||||||
stateCallback(IMEState.Abortion())
|
stateCallback(IMEState.ofAbortion())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -634,7 +634,7 @@ extension KeyHandler {
|
||||||
if isCursorCuttingChar(isMarker: true) {
|
if isCursorCuttingChar(isMarker: true) {
|
||||||
compositor.jumpCursorBySpan(to: .front, isMarker: true)
|
compositor.jumpCursorBySpan(to: .front, isMarker: true)
|
||||||
}
|
}
|
||||||
var marking = IMEState.Marking(
|
var marking = IMEState.ofMarking(
|
||||||
displayTextSegments: compositor.walkedNodes.values,
|
displayTextSegments: compositor.walkedNodes.values,
|
||||||
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
||||||
cursor: convertCursorForDisplay(compositor.cursor),
|
cursor: convertCursorForDisplay(compositor.cursor),
|
||||||
|
@ -707,7 +707,7 @@ extension KeyHandler {
|
||||||
if isCursorCuttingChar(isMarker: true) {
|
if isCursorCuttingChar(isMarker: true) {
|
||||||
compositor.jumpCursorBySpan(to: .rear, isMarker: true)
|
compositor.jumpCursorBySpan(to: .rear, isMarker: true)
|
||||||
}
|
}
|
||||||
var marking = IMEState.Marking(
|
var marking = IMEState.ofMarking(
|
||||||
displayTextSegments: compositor.walkedNodes.values,
|
displayTextSegments: compositor.walkedNodes.values,
|
||||||
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
markedReadings: Array(compositor.keys[currentMarkedRange()]),
|
||||||
cursor: convertCursorForDisplay(compositor.cursor),
|
cursor: convertCursorForDisplay(compositor.cursor),
|
||||||
|
|
|
@ -41,7 +41,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
/// 按鍵調度模組的副本。
|
/// 按鍵調度模組的副本。
|
||||||
var keyHandler: KeyHandler = .init()
|
var keyHandler: KeyHandler = .init()
|
||||||
/// 用以記錄當前輸入法狀態的變數。
|
/// 用以記錄當前輸入法狀態的變數。
|
||||||
var state: IMEStateProtocol = IMEState.Empty() {
|
var state: IMEStateProtocol = IMEState.ofEmpty() {
|
||||||
didSet {
|
didSet {
|
||||||
IME.prtDebugIntel("Current State: \(state.type.rawValue)")
|
IME.prtDebugIntel("Current State: \(state.type.rawValue)")
|
||||||
}
|
}
|
||||||
|
@ -75,9 +75,9 @@ class ctlInputMethod: IMKInputController {
|
||||||
}
|
}
|
||||||
if state.hasComposition {
|
if state.hasComposition {
|
||||||
/// 將傳回的新狀態交給調度函式。
|
/// 將傳回的新狀態交給調度函式。
|
||||||
handle(state: IMEState.Committing(textToCommit: state.displayedText))
|
handle(state: IMEState.ofCommitting(textToCommit: state.displayedText))
|
||||||
}
|
}
|
||||||
handle(state: IMEState.Empty())
|
handle(state: IMEState.ofEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - IMKInputController 方法
|
// MARK: - IMKInputController 方法
|
||||||
|
@ -131,7 +131,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
if let client = client(), client.bundleIdentifier() != Bundle.main.bundleIdentifier {
|
if let client = client(), client.bundleIdentifier() != Bundle.main.bundleIdentifier {
|
||||||
// 強制重設當前鍵盤佈局、使其與偏好設定同步。
|
// 強制重設當前鍵盤佈局、使其與偏好設定同步。
|
||||||
setKeyLayout()
|
setKeyLayout()
|
||||||
handle(state: IMEState.Empty())
|
handle(state: IMEState.ofEmpty())
|
||||||
} // 除此之外就不要動了,免得在點開輸入法自身的視窗時卡死。
|
} // 除此之外就不要動了,免得在點開輸入法自身的視窗時卡死。
|
||||||
(NSApp.delegate as? AppDelegate)?.checkForUpdate()
|
(NSApp.delegate as? AppDelegate)?.checkForUpdate()
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
override func deactivateServer(_ sender: Any!) {
|
override func deactivateServer(_ sender: Any!) {
|
||||||
_ = sender // 防止格式整理工具毀掉與此對應的參數。
|
_ = sender // 防止格式整理工具毀掉與此對應的參數。
|
||||||
resetKeyHandler() // 這條會自動搞定 Empty 狀態。
|
resetKeyHandler() // 這條會自動搞定 Empty 狀態。
|
||||||
handle(state: IMEState.Deactivated())
|
handle(state: IMEState.ofDeactivated())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 切換至某一個輸入法的某個副本時(比如威注音的簡體輸入法副本與繁體輸入法副本),會觸發該函式。
|
/// 切換至某一個輸入法的某個副本時(比如威注音的簡體輸入法副本與繁體輸入法副本),會觸發該函式。
|
||||||
|
@ -172,7 +172,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
if let client = client(), client.bundleIdentifier() != Bundle.main.bundleIdentifier {
|
if let client = client(), client.bundleIdentifier() != Bundle.main.bundleIdentifier {
|
||||||
// 強制重設當前鍵盤佈局、使其與偏好設定同步。這裡的這一步也不能省略。
|
// 強制重設當前鍵盤佈局、使其與偏好設定同步。這裡的這一步也不能省略。
|
||||||
setKeyLayout()
|
setKeyLayout()
|
||||||
handle(state: IMEState.Empty())
|
handle(state: IMEState.ofEmpty())
|
||||||
} // 除此之外就不要動了,免得在點開輸入法自身的視窗時卡死。
|
} // 除此之外就不要動了,免得在點開輸入法自身的視窗時卡死。
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +367,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
let candidateString: NSAttributedString = candidateString ?? .init(string: "")
|
let candidateString: NSAttributedString = candidateString ?? .init(string: "")
|
||||||
if state.type == .ofAssociates {
|
if state.type == .ofAssociates {
|
||||||
if !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter {
|
if !mgrPrefs.alsoConfirmAssociatedCandidatesByEnter {
|
||||||
handle(state: IMEState.Abortion())
|
handle(state: IMEState.ofAbortion())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,11 +111,11 @@ extension ctlInputMethod: ctlCandidateDelegate {
|
||||||
let node = state.node.children?[index]
|
let node = state.node.children?[index]
|
||||||
{
|
{
|
||||||
if let children = node.children, !children.isEmpty {
|
if let children = node.children, !children.isEmpty {
|
||||||
handle(state: IMEState.Empty()) // 防止縱橫排選字窗同時出現
|
handle(state: IMEState.ofEmpty()) // 防止縱橫排選字窗同時出現
|
||||||
handle(state: IMEState.SymbolTable(node: node))
|
handle(state: IMEState.ofSymbolTable(node: node))
|
||||||
} else {
|
} else {
|
||||||
handle(state: IMEState.Committing(textToCommit: node.title))
|
handle(state: IMEState.ofCommitting(textToCommit: node.title))
|
||||||
handle(state: IMEState.Empty())
|
handle(state: IMEState.ofEmpty())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -130,15 +130,15 @@ extension ctlInputMethod: ctlCandidateDelegate {
|
||||||
let inputting = keyHandler.buildInputtingState
|
let inputting = keyHandler.buildInputtingState
|
||||||
|
|
||||||
if mgrPrefs.useSCPCTypingMode {
|
if mgrPrefs.useSCPCTypingMode {
|
||||||
handle(state: IMEState.Committing(textToCommit: inputting.displayedText))
|
handle(state: IMEState.ofCommitting(textToCommit: inputting.displayedText))
|
||||||
// 此時是逐字選字模式,所以「selectedValue.1」是單個字、不用追加處理。
|
// 此時是逐字選字模式,所以「selectedValue.1」是單個字、不用追加處理。
|
||||||
if mgrPrefs.associatedPhrasesEnabled {
|
if mgrPrefs.associatedPhrasesEnabled {
|
||||||
let associates = keyHandler.buildAssociatePhraseState(
|
let associates = keyHandler.buildAssociatePhraseState(
|
||||||
withPair: .init(key: selectedValue.0, value: selectedValue.1)
|
withPair: .init(key: selectedValue.0, value: selectedValue.1)
|
||||||
)
|
)
|
||||||
handle(state: associates.candidates.isEmpty ? IMEState.Empty() : associates)
|
handle(state: associates.candidates.isEmpty ? IMEState.ofEmpty() : associates)
|
||||||
} else {
|
} else {
|
||||||
handle(state: IMEState.Empty())
|
handle(state: IMEState.ofEmpty())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
handle(state: inputting)
|
handle(state: inputting)
|
||||||
|
@ -148,11 +148,11 @@ extension ctlInputMethod: ctlCandidateDelegate {
|
||||||
|
|
||||||
if state.type == .ofAssociates {
|
if state.type == .ofAssociates {
|
||||||
let selectedValue = state.candidates[index]
|
let selectedValue = state.candidates[index]
|
||||||
handle(state: IMEState.Committing(textToCommit: selectedValue.1))
|
handle(state: IMEState.ofCommitting(textToCommit: selectedValue.1))
|
||||||
// 此時是聯想詞選字模式,所以「selectedValue.1」必須只保留最後一個字。
|
// 此時是聯想詞選字模式,所以「selectedValue.1」必須只保留最後一個字。
|
||||||
// 不然的話,一旦你選中了由多個字組成的聯想候選詞,則連續聯想會被打斷。
|
// 不然的話,一旦你選中了由多個字組成的聯想候選詞,則連續聯想會被打斷。
|
||||||
guard let valueKept = selectedValue.1.last else {
|
guard let valueKept = selectedValue.1.last else {
|
||||||
handle(state: IMEState.Empty())
|
handle(state: IMEState.ofEmpty())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if mgrPrefs.associatedPhrasesEnabled {
|
if mgrPrefs.associatedPhrasesEnabled {
|
||||||
|
@ -164,7 +164,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handle(state: IMEState.Empty())
|
handle(state: IMEState.ofEmpty())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ extension ctlInputMethod {
|
||||||
case .ofEmpty, .ofAbortion:
|
case .ofEmpty, .ofAbortion:
|
||||||
var previous = previous
|
var previous = previous
|
||||||
if state.type == .ofAbortion {
|
if state.type == .ofAbortion {
|
||||||
state = IMEState.Empty()
|
state = IMEState.ofEmpty()
|
||||||
previous = state
|
previous = state
|
||||||
}
|
}
|
||||||
ctlInputMethod.ctlCandidateCurrent.visible = false
|
ctlInputMethod.ctlCandidateCurrent.visible = false
|
||||||
|
|
Loading…
Reference in New Issue