1.8.3 // Maintenance. Merge Gitee PR!66 from upd/1.8.3

This commit is contained in:
ShikiSuen 2022-07-22 10:44:54 +00:00 committed by Gitee
commit 509262bf6a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
13 changed files with 92 additions and 149 deletions

View File

@ -16,7 +16,7 @@ $ Contributors and volunteers of the upstream repo, having no responsibility in
- Zonble Yang:
- McBopomofo for macOS 2.x architect, especially state-based IME behavior management.
- Voltaire candidate window MK2 (massively modified as MK3 in vChewing by Shiki Suen).
- InputHandler.
- InputSignal (previously "KeyHandlerInput").
- Notifier window and Tooltip UI.
- NSStringUtils and FSEventStreamHelper.
- App-style installer (only preserved for developer purposes).

@ -1 +1 @@
Subproject commit 32ae1957bdbbb1daabf108f6352708677aec27fa
Subproject commit 91a12bb5a355b56456beceec42cb001dea036b2b

View File

@ -50,7 +50,7 @@ enum KeyCode: UInt16 {
case kVolumeUp = 72
case kVolumeDown = 73
case kMute = 74
case kLineFeed = 76 // Another keyCode to identify the Enter Key.
case kLineFeed = 76 // Another keyCode to identify the Enter Key, typable by Fn+Enter.
case kF18 = 79
case kF19 = 80
case kF20 = 90

View File

@ -103,7 +103,7 @@ class KeyHandler {
///
/// 使 Node Crossing
var actualCandidateCursor: Int {
mgrPrefs.useRearCursorMode ? min(compositorCursorIndex, compositorLength - 1) : max(compositorCursorIndex, 1)
mgrPrefs.useRearCursorMode ? min(compositor.cursor, compositor.length - 1) : max(compositor.cursor, 1)
}
///
@ -161,10 +161,10 @@ class KeyHandler {
///
/// - Parameters:
/// - value:
/// - respectCursorPushing: true
/// - 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), compositorLength))
let adjustedCursor = max(0, min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length))
//
let selectedNode: Megrez.NodeAnchor = compositor.fixNodeWithCandidate(theCandidate, at: adjustedCursor)
//
@ -196,7 +196,7 @@ class KeyHandler {
//
walk()
///
///
if mgrPrefs.moveCursorAfterSelectingCandidate, respectCursorPushing {
compositor.jumpCursorBySpan(to: .front)
}
@ -254,7 +254,7 @@ class KeyHandler {
///
func fetchSuggestedCandidates() -> [Megrez.Unigram] {
currentUOM.suggest(
walkedAnchors: walkedAnchors, cursorIndex: compositorCursorIndex,
walkedAnchors: walkedAnchors, cursorIndex: compositor.cursor,
timestamp: NSDate().timeIntervalSince1970
)
}
@ -273,7 +273,7 @@ class KeyHandler {
IME.prtDebugIntel(
"UOM: Suggestion retrieved, overriding the node score of the selected candidate.")
compositor.overrideNodeScoreForSelectedCandidate(
location: min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositorLength),
location: min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length),
value: overrideValue,
overridingScore: findHighestScore(nodeAnchors: rawAnchorsOfNodes, epsilon: kEpsilon)
)
@ -288,7 +288,7 @@ class KeyHandler {
/// - epsilon:
/// - Returns:
func findHighestScore(nodeAnchors: [Megrez.NodeAnchor], epsilon: Double) -> Double {
return nodeAnchors.map(\.node.highestUnigramScore).max() ?? 0 + epsilon
nodeAnchors.map(\.node.highestUnigramScore).max() ?? 0 + epsilon
}
// MARK: - Extracted methods and functions (Tekkon).
@ -337,9 +337,6 @@ class KeyHandler {
// MARK: - Extracted methods and functions (Megrez).
///
var isCompositorEmpty: Bool { compositor.isEmpty }
///
var rawAnchorsOfNodes: [Megrez.NodeAnchor] {
/// 使 nodesCrossing macOS
@ -362,59 +359,6 @@ class KeyHandler {
compositor = Megrez.Compositor(lm: currentLM, separator: "-")
}
///
var currentReadings: [String] { compositor.readings }
///
func ifLangModelHasUnigrams(forKey reading: String) -> Bool {
currentLM.hasUnigramsFor(key: reading)
}
///
func insertToCompositorAtCursor(reading: String) {
compositor.insertReading(reading)
}
///
var compositorCursorIndex: Int {
get { compositor.cursor }
set { compositor.cursor = newValue }
}
///
var compositorLength: Int {
compositor.length
}
///
///
/// Rear
func deleteCompositorReadingAtTheRearOfCursor() {
compositor.dropReading(direction: .rear)
}
///
///
/// Front
func deleteCompositorReadingToTheFrontOfCursor() {
compositor.dropReading(direction: .front)
}
///
/// - Returns:
var keyLengthAtCurrentIndex: Int {
walkedAnchors[compositorCursorIndex].node.key.split(separator: "-").count
}
var nextPhrasePosition: Int {
var nextPosition = 0
for theAnchor in walkedAnchors {
if nextPosition > actualCandidateCursor { break }
nextPosition += theAnchor.spanLength
}
return min(nextPosition, compositorLength)
}
///
/// - Parameter input:
/// - Returns:

View File

@ -61,12 +61,12 @@ extension KeyHandler {
if cancelCandidateKey {
if (state is InputState.AssociatedPhrases)
|| mgrPrefs.useSCPCTypingMode
|| isCompositorEmpty
|| compositor.isEmpty
{
//
//
// 使 BackSpace
// isCompositorEmpty
// compositor.isEmpty
clear()
stateCallback(InputState.EmptyIgnoringPreviousState())
} else {
@ -326,12 +326,12 @@ extension KeyHandler {
let punctuation: String = arrPunctuations.joined(separator: "")
var shouldAutoSelectCandidate: Bool =
composer.inputValidityCheck(key: charCode) || ifLangModelHasUnigrams(forKey: customPunctuation)
|| ifLangModelHasUnigrams(forKey: punctuation)
composer.inputValidityCheck(key: charCode) || currentLM.hasUnigramsFor(key: customPunctuation)
|| currentLM.hasUnigramsFor(key: punctuation)
if !shouldAutoSelectCandidate, input.isUpperCaseASCIILetterKey {
let letter: String! = String(format: "%@%c", "_letter_", CChar(charCode))
if ifLangModelHasUnigrams(forKey: letter) { shouldAutoSelectCandidate = true }
if currentLM.hasUnigramsFor(key: letter) { shouldAutoSelectCandidate = true }
}
if shouldAutoSelectCandidate {

View File

@ -188,7 +188,7 @@ extension KeyHandler {
//
//
if !ifLangModelHasUnigrams(forKey: reading) {
if !currentLM.hasUnigramsFor(key: reading) {
IME.prtDebugIntel("B49C0979語彙庫內無「\(reading)」的匹配記錄。")
errorCallback()
composer.clear()
@ -198,7 +198,7 @@ extension KeyHandler {
}
//
insertToCompositorAtCursor(reading: reading)
compositor.insertReading(reading)
//
let textToCommit = commitOverflownCompositionAndWalk
@ -270,7 +270,7 @@ extension KeyHandler {
if input.isSpace {
/// Space
if !mgrPrefs.chooseCandidateUsingSpace {
if compositorCursorIndex >= compositorLength {
if compositor.cursor >= compositor.length {
let composingBuffer = currentState.composingBuffer
if !composingBuffer.isEmpty {
stateCallback(InputState.Committing(textToCommit: composingBuffer))
@ -278,8 +278,8 @@ extension KeyHandler {
clear()
stateCallback(InputState.Committing(textToCommit: " "))
stateCallback(InputState.Empty())
} else if ifLangModelHasUnigrams(forKey: " ") {
insertToCompositorAtCursor(reading: " ")
} else if currentLM.hasUnigramsFor(key: " ") {
compositor.insertReading(" ")
let textToCommit = commitOverflownCompositionAndWalk
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
@ -354,7 +354,7 @@ extension KeyHandler {
// MARK: AbsorbedArrowKey
if input.isAbsorbedArrowKey || input.isExtraChooseCandidateKey || input.isExtraChooseCandidateKeyReverse {
if input.isOptionHold, state.type == .ofInputting {
if input.isOptionHold, state is InputState.Inputting {
if input.isExtraChooseCandidateKey {
return handleInlineCandidateRotation(
state: state, reverseModifier: false, stateCallback: stateCallback, errorCallback: errorCallback
@ -396,9 +396,9 @@ extension KeyHandler {
if input.isSymbolMenuPhysicalKey && !input.isShiftHold {
if input.isOptionHold {
if ifLangModelHasUnigrams(forKey: "_punctuation_list") {
if currentLM.hasUnigramsFor(key: "_punctuation_list") {
if composer.isEmpty {
insertToCompositorAtCursor(reading: "_punctuation_list")
compositor.insertReading("_punctuation_list")
let textToCommit: String! = commitOverflownCompositionAndWalk
let inputting = buildInputtingState
inputting.textToCommit = textToCommit

View File

@ -54,35 +54,35 @@ extension KeyHandler {
/// NodeAnchorspanningLength
///
let spanningLength: Int = theAnchor.spanLength
if readingCursorIndex + spanningLength <= compositorCursorIndex {
if readingCursorIndex + spanningLength <= compositor.cursor {
composedStringCursorIndex += strNodeValue.utf16.count
readingCursorIndex += spanningLength
} else {
if codepointCount == spanningLength {
var i = 0
while i < codepointCount, readingCursorIndex < compositorCursorIndex {
while i < codepointCount, readingCursorIndex < compositor.cursor {
composedStringCursorIndex += arrSplit[i].utf16.count
readingCursorIndex += 1
i += 1
}
} else {
if readingCursorIndex < compositorCursorIndex {
if readingCursorIndex < compositor.cursor {
composedStringCursorIndex += strNodeValue.utf16.count
readingCursorIndex += spanningLength
readingCursorIndex = min(readingCursorIndex, compositorCursorIndex)
readingCursorIndex = min(readingCursorIndex, compositor.cursor)
///
///
///
///
///
switch compositorCursorIndex {
switch compositor.cursor {
case compositor.readings.count...:
tooltipParameterRef[0] = compositor.readings[compositor.readings.count - 1]
tooltipParameterRef[0] = compositor.readings[compositor.cursor - 1]
case 0:
tooltipParameterRef[1] = compositor.readings[compositorCursorIndex]
tooltipParameterRef[1] = compositor.readings[compositor.cursor]
default:
tooltipParameterRef[0] = compositor.readings[compositorCursorIndex - 1]
tooltipParameterRef[1] = compositor.readings[compositorCursorIndex]
tooltipParameterRef[0] = compositor.readings[compositor.cursor - 1]
tooltipParameterRef[1] = compositor.readings[compositor.cursor]
}
///
for (i, _) in tooltipParameterRef.enumerated() {
@ -301,7 +301,7 @@ extension KeyHandler {
stateCallback: @escaping (InputStateProtocol) -> Void,
errorCallback: @escaping () -> Void
) -> Bool {
if !ifLangModelHasUnigrams(forKey: customPunctuation) {
if !currentLM.hasUnigramsFor(key: customPunctuation) {
return false
}
@ -313,7 +313,7 @@ extension KeyHandler {
return true
}
insertToCompositorAtCursor(reading: customPunctuation)
compositor.insertReading(customPunctuation)
let textToCommit = commitOverflownCompositionAndWalk
let inputting = buildInputtingState
inputting.textToCommit = textToCommit
@ -372,7 +372,7 @@ extension KeyHandler {
) -> Bool {
guard state is InputState.Inputting else { return false }
var composingBuffer = currentReadings.joined(separator: "-")
var composingBuffer = compositor.readings.joined(separator: "-")
if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin {
composingBuffer = Tekkon.restoreToneOneInZhuyinKey(target: composingBuffer) //
composingBuffer = Tekkon.cnvPhonaToHanyuPinyin(target: composingBuffer) //
@ -445,8 +445,8 @@ extension KeyHandler {
if composer.hasToneMarker(withNothingElse: true) {
composer.clear()
} else if composer.isEmpty {
if compositorCursorIndex > 0 {
deleteCompositorReadingAtTheRearOfCursor()
if compositor.cursor > 0 {
compositor.dropReading(direction: .rear)
walk()
} else {
IME.prtDebugIntel("9D69908D")
@ -485,14 +485,14 @@ extension KeyHandler {
return true
}
guard compositorCursorIndex != compositorLength else {
guard compositor.cursor != compositor.length else {
IME.prtDebugIntel("9B69938D")
errorCallback()
stateCallback(state)
return true
}
deleteCompositorReadingToTheFrontOfCursor()
compositor.dropReading(direction: .front)
walk()
let inputting = buildInputtingState
// count > 0!isEmpty滿
@ -544,8 +544,8 @@ extension KeyHandler {
return true
}
if compositorCursorIndex != 0 {
compositorCursorIndex = 0
if compositor.cursor != 0 {
compositor.cursor = 0
stateCallback(buildInputtingState)
} else {
IME.prtDebugIntel("66D97F90")
@ -578,8 +578,8 @@ extension KeyHandler {
return true
}
if compositorCursorIndex != compositorLength {
compositorCursorIndex = compositorLength
if compositor.cursor != compositor.length {
compositor.cursor = compositor.length
stateCallback(buildInputtingState)
} else {
IME.prtDebugIntel("9B69908E")
@ -650,7 +650,7 @@ extension KeyHandler {
composingBuffer: currentState.composingBuffer,
cursorIndex: currentState.cursorIndex,
markerIndex: nextPosition,
readings: currentReadings
readings: compositor.readings
)
marking.tooltipForInputting = currentState.tooltip
stateCallback(marking)
@ -672,8 +672,8 @@ extension KeyHandler {
}
stateCallback(buildInputtingState)
} else {
if compositorCursorIndex < compositorLength {
compositorCursorIndex += 1
if compositor.cursor < compositor.length {
compositor.cursor += 1
stateCallback(buildInputtingState)
} else {
IME.prtDebugIntel("A96AAD58")
@ -718,7 +718,7 @@ extension KeyHandler {
composingBuffer: currentState.composingBuffer,
cursorIndex: currentState.cursorIndex,
markerIndex: previousPosition,
readings: currentReadings
readings: compositor.readings
)
marking.tooltipForInputting = currentState.tooltip
stateCallback(marking)
@ -740,8 +740,8 @@ extension KeyHandler {
}
stateCallback(buildInputtingState)
} else {
if compositorCursorIndex > 0 {
compositorCursorIndex -= 1
if compositor.cursor > 0 {
compositor.cursor -= 1
stateCallback(buildInputtingState)
} else {
IME.prtDebugIntel("7045E6F3")
@ -795,7 +795,7 @@ extension KeyHandler {
var length = 0
var currentAnchor = Megrez.NodeAnchor()
let cursorIndex = min(
actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositorLength
actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length
)
for anchor in walkedAnchors {
length += anchor.spanLength
@ -817,7 +817,8 @@ extension KeyHandler {
///
/// 使
/// (Shift+)Tab ()
/// Shift(+CMD)+Space Tab
/// Shift(+CMD)+Space Alt+/ Alt+/
/// Tab
if candidates[0].0 == currentPaired.key, candidates[0].1 == currentPaired.value {
///
///

View File

@ -906,7 +906,7 @@ public struct Tekkon {
}
for key in Tekkon.mapArayuruPinyinIntonation.keys.sorted(by: { $0.count > $1.count }) {
guard let value = Tekkon.mapArayuruPinyinIntonation[key] else { continue }
result = result.replacingOccurrences(of: key, with: value)
result = result.replacingOccurrences(of: key, with: (key == "1") ? "" : value)
}
return result
}

View File

@ -42,6 +42,15 @@ extension vChewing {
!rangeMap.isEmpty
}
internal func cnvNgramKeyFromPinyinToPhona(target: String) -> String {
guard target.contains("("), target.contains(","), target.contains(")") else {
return target
}
let arrTarget = target.dropLast().dropFirst().split(separator: ",")
guard arrTarget.count == 2 else { return target }
return "(\(Tekkon.cnvHanyuPinyinToPhona(target: String(arrTarget[0]))),\(arrTarget[1]))"
}
@discardableResult public mutating func open(_ path: String) -> Bool {
if isLoaded() {
return false
@ -60,7 +69,7 @@ extension vChewing {
if !theKey.isEmpty, theKey.first != "#" {
for (i, _) in neta.filter({ $0.first != "#" && !$0.isEmpty }).enumerated() {
if i == 0 { continue }
rangeMap[theKey, default: []].append(($0, i))
rangeMap[cnvNgramKeyFromPinyinToPhona(target: theKey), default: []].append(($0, i))
}
}
}
@ -102,8 +111,6 @@ extension vChewing {
}
public func valuesFor(pair: Megrez.KeyValuePaired) -> [String] {
var pairPinyin = pair
pairPinyin.key = Tekkon.cnvPhonaToHanyuPinyin(target: pairPinyin.key)
var pairs: [String] = []
if let arrRangeRecords: [(Range<String.Index>, Int)] = rangeMap[pair.toNGramKey] {
for (netaRange, index) in arrRangeRecords {
@ -112,13 +119,6 @@ extension vChewing {
pairs.append(theValue)
}
}
if let arrRangeRecords: [(Range<String.Index>, Int)] = rangeMap[pairPinyin.toNGramKey] {
for (netaRange, index) in arrRangeRecords {
let neta = strData[netaRange].split(separator: " ")
let theValue: String = .init(neta[index])
pairs.append(theValue)
}
}
if let arrRangeRecords: [(Range<String.Index>, Int)] = rangeMap[pair.value] {
for (netaRange, index) in arrRangeRecords {
let neta = strData[netaRange].split(separator: " ")

View File

@ -3,9 +3,9 @@
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.8.2</string>
<string>1.8.3</string>
<key>CFBundleVersion</key>
<string>1982</string>
<string>1983</string>
<key>UpdateInfoEndpoint</key>
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
<key>UpdateInfoSite</key>

View File

@ -726,7 +726,7 @@
<key>USE_HFS+_COMPRESSION</key>
<false/>
<key>VERSION</key>
<string>1.8.2</string>
<string>1.8.3</string>
</dict>
<key>TYPE</key>
<integer>0</integer>

View File

@ -1389,7 +1389,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -1399,7 +1399,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
@ -1428,13 +1428,13 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
@ -1465,7 +1465,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
DEAD_CODE_STRIPPING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
@ -1486,7 +1486,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
@ -1515,7 +1515,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
DEAD_CODE_STRIPPING = YES;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
@ -1532,7 +1532,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
@ -1575,6 +1575,8 @@
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
ONLY_ACTIVE_ARCH = YES;
@ -1616,6 +1618,8 @@
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11.5;
OTHER_CPLUSPLUSFLAGS = (
@ -1642,7 +1646,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
@ -1665,15 +1669,12 @@
GCC_WARN_SHADOW = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "Source/Resources/IME-Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1700,7 +1701,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
@ -1717,15 +1718,12 @@
GCC_WARN_SHADOW = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "Source/Resources/IME-Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1747,7 +1745,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -1762,13 +1760,12 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "Installer/Installer-Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1790,7 +1787,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1982;
CURRENT_PROJECT_VERSION = 1983;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
@ -1799,13 +1796,12 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "Installer/Installer-Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.8.2;
MARKETING_VERSION = 1.8.3;
PRODUCT_BUNDLE_IDENTIFIER = "org.atelierInmu.vChewing.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -357,13 +357,15 @@ extension String {
extension vChewing.LMAssociates {
public mutating func forceOpenStringInstead(_ strData: String) {
strData.ranges(splitBy: "\n").forEach {
strData.ranges(splitBy: "\n").filter({ !$0.isEmpty }).forEach {
let neta = strData[$0].split(separator: " ")
if neta.count >= 2 {
let theKey = String(neta[0])
if !neta[0].isEmpty, !neta[1].isEmpty, theKey.first != "#" {
let theValue = $0
rangeMap[theKey, default: []].append(theValue)
if !theKey.isEmpty, theKey.first != "#" {
for (i, _) in neta.filter({ $0.first != "#" && !$0.isEmpty }).enumerated() {
if i == 0 { continue }
rangeMap[theKey, default: []].append(($0, i))
}
}
}
}