/
GureumComposer.swift
222 lines (206 loc) · 11.1 KB
/
GureumComposer.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
//
// GureumComposer.swift
// OSX
//
// Created by Hyewon on 2018. 9. 7..
// Copyright © 2018년 youknowone.org. All rights reserved.
//
/*!
@brief 구름 입력기의 합성기
입력 모드에 따라 libhangul을 이용하여 문자를 합성해 준다.
*/
import Foundation
@objc class GureumInputSourceIdentifier: NSObject {
@objc static let qwerty = "org.youknowone.inputmethod.Gureum.qwerty"
@objc static let dvorak = "org.youknowone.inputmethod.Gureum.dvorak"
@objc static let dvorakQwertyCommand = "org.youknowone.inputmethod.Gureum.dvorakq"
@objc static let colemak = "org.youknowone.inputmethod.Gureum.colemak"
@objc static let colemakQwertyCommand = "org.youknowone.inputmethod.Gureum.colemakq"
@objc static let han2 = "org.youknowone.inputmethod.Gureum.han2"
@objc static let han2Classic = "org.youknowone.inputmethod.Gureum.han2classic"
@objc static let han3Final = "org.youknowone.inputmethod.Gureum.han3final"
@objc static let han3FinalLoose = "org.youknowone.inputmethod.Gureum.han3finalloose"
@objc static let han390 = "org.youknowone.inputmethod.Gureum.han390"
@objc static let han390Loose = "org.youknowone.inputmethod.Gureum.han390loose"
@objc static let han3NoShift = "org.youknowone.inputmethod.Gureum.han3noshift"
@objc static let han3Classic = "org.youknowone.inputmethod.Gureum.han3classic"
@objc static let han3Layout2 = "org.youknowone.inputmethod.Gureum.han3layout2"
@objc static let hanAhnmatae = "org.youknowone.inputmethod.Gureum.han3ahnmatae"
@objc static let hanRoman = "org.youknowone.inputmethod.Gureum.hanroman"
@objc static let han3_2011 = "org.youknowone.inputmethod.Gureum.han3-2011"
@objc static let han3_2011Loose = "org.youknowone.inputmethod.Gureum.han3-2011loose"
@objc static let han3_2012 = "org.youknowone.inputmethod.Gureum.han3-2012"
@objc static let han3_2012Loose = "org.youknowone.inputmethod.Gureum.han3-2012loose"
@objc static let han3FinalNoShiftCompat = "org.youknowone.inputmethod.Gureum.han3finalnoshiftcompat"
@objc static let han3FinalNoShiftSymbol = "org.youknowone.inputmethod.Gureum.han3finalnoshiftsymbol"
@objc static let han3_2014 = "org.youknowone.inputmethod.Gureum.han3-2014"
@objc static let han3_2015 = "org.youknowone.inputmethod.Gureum.han3-2015"
}
let GureumInputSourceToHangulKeyboardIdentifierTable: [String: String] = [
GureumInputSourceIdentifier.qwerty : "",
GureumInputSourceIdentifier.han2 : "2",
GureumInputSourceIdentifier.han2Classic : "2y",
GureumInputSourceIdentifier.han3Final : "3f",
GureumInputSourceIdentifier.han390 : "39",
GureumInputSourceIdentifier.han3NoShift : "3s",
GureumInputSourceIdentifier.han3Classic : "3y",
GureumInputSourceIdentifier.han3Layout2 : "32",
GureumInputSourceIdentifier.hanRoman : "ro",
GureumInputSourceIdentifier.hanAhnmatae : "ahn",
GureumInputSourceIdentifier.han3FinalNoShiftCompat: "3gc",
GureumInputSourceIdentifier.han3FinalNoShiftSymbol : "3gs",
GureumInputSourceIdentifier.han3_2011 : "3-2011",
GureumInputSourceIdentifier.han3_2012 : "3-2012",
GureumInputSourceIdentifier.han3_2014 : "3-2014",
GureumInputSourceIdentifier.han3_2015 : "3-2015",
]
@objcMembers class GureumComposer: CIMComposer {
@objc var romanComposer: RomanComposer
@objc var hangulComposer: HangulComposer
@objc var hanjaComposer: HanjaComposer
override init() {
romanComposer = RomanComposer()
hangulComposer = HangulComposer(keyboardIdentifier: "2")!
hanjaComposer = HanjaComposer()
hanjaComposer.delegate = hangulComposer
super.init()
self.delegate = romanComposer
}
@objc override var inputMode: String {
get {
return super.inputMode
}
set {
guard self.inputMode != newValue else {
return
}
guard let keyboardIdentifier = GureumInputSourceToHangulKeyboardIdentifierTable[newValue] else {
return
}
if keyboardIdentifier.count == 0 {
self.delegate = romanComposer
} else {
self.delegate = hangulComposer
// 단축키 지원을 위해 마지막 자판을 기억
hangulComposer.setKeyboardWithIdentifier(keyboardIdentifier)
GureumConfiguration.shared().lastHangulInputMode = newValue
}
super.inputMode = newValue
}
}
@objc override func inputController(_ controller: CIMInputController!, command string: String!, key keyCode: Int, modifiers flags: NSEvent.ModifierFlags, client sender: Any) -> CIMInputTextProcessResult {
let configuration = GureumConfiguration.shared()
let inputModifier = flags.intersection(NSEvent.ModifierFlags.deviceIndependentFlagsMask).intersection(NSEvent.ModifierFlags(rawValue: ~NSEvent.ModifierFlags.capsLock.rawValue))
var need_exchange = false
var need_hanjamode = false
// if (string == nil) {
// NSUInteger modifierKey = flags & 0xff;
// if (self->lastModifier != 0 && modifierKey == 0) {
// dlog(DEBUG_SHORTCUT, @"**** Trigger modifier: %lx ****", self->lastModifier);
// NSDictionary *correspondedConfigurations = @{
// @(0x01): @(CIMSharedConfiguration->leftControlKeyShortcutBehavior),
// @(0x20): @(CIMSharedConfiguration->leftOptionKeyShortcutBehavior),
// @(0x08): @(CIMSharedConfiguration->leftCommandKeyShortcutBehavior),
// @(0x10): @(CIMSharedConfiguration->leftCommandKeyShortcutBehavior),
// @(0x40): @(CIMSharedConfiguration->leftOptionKeyShortcutBehavior),
// };
// for (NSNumber *marker in @[@(0x01), @(0x20), @(0x08), @(0x10), @(0x40)]) {
// if (self->lastModifier == marker.unsignedIntegerValue ) {
// NSInteger configuration = [correspondedConfigurations[marker] integerValue];
// switch (configuration) {
// case 0:
// break;
// case 1: {
// dlog(DEBUG_SHORTCUT, @"**** Layout exchange by exchange modifier ****");
// need_exchange = YES;
// } break;
// case 2: {
// dlog(DEBUG_SHORTCUT, @"**** Hanja mode by hanja modifier ****");
// need_hanjamode = YES;
// } break;
// case 3: if (self.delegate == self->hangulComposer) {
// dlog(DEBUG_SHORTCUT, @"**** Layout exchange by change to english modifier ****");
// need_exchange = YES;
// } break;
// case 4: if (self.delegate == self->romanComposer) {
// dlog(DEBUG_SHORTCUT, @"**** Layout exchange by change to korean modifier ****");
// need_exchange = YES;
// } break;
// default:
// dassert(NO);
// break;
// }
// }
// }
// } else {
// self->lastModifier = modifierKey;
// dlog(DEBUG_SHORTCUT, @"**** Save modifier: %lx ****", self->lastModifier);
// }
// } else
// {
var lastModifier = 0
if keyCode == -1 {
if !flags.intersection(NSEvent.ModifierFlags.capsLock).isEmpty && self.delegate === romanComposer {
need_exchange = true
} else if flags.rawValue == 0 && self.delegate === hangulComposer {
need_exchange = true
} else {
return CIMInputTextProcessResult.processed
}
}
if Int(inputModifier.rawValue) == configuration.inputModeExchangeKeyModifier && keyCode == configuration.inputModeExchangeKeyCode {
need_exchange = true
}
// else if (self.delegate == self->hangulComposer && inputModifier == CIMSharedConfiguration->inputModeEnglishKeyModifier && keyCode == CIMSharedConfiguration->inputModeEnglishKeyCode) {
// dlog(DEBUG_SHORTCUT, @"**** Layout exchange by change to english shortcut ****");
// need_exchange = YES;
// }
// else if (self.delegate == self->romanComposer && inputModifier == CIMSharedConfiguration->inputModeKoreanKeyModifier && keyCode == CIMSharedConfiguration->inputModeKoreanKeyCode) {
// dlog(DEBUG_SHORTCUT, @"**** Layout exchange by change to korean shortcut ****");
// need_exchange = YES;
// }
if Int(inputModifier.rawValue) == configuration.inputModeHanjaKeyModifier && keyCode == configuration.inputModeHanjaKeyCode {
need_hanjamode = true
}
// }
if need_exchange {
// 한영전환을 위해 현재 입력 중인 문자 합성 취소
self.delegate.cancelComposition()
if self.delegate === romanComposer {
var lastHangulInputMode = GureumConfiguration.shared().lastHangulInputMode
if lastHangulInputMode == nil {
lastHangulInputMode = GureumInputSourceIdentifier.han2
}
(sender as AnyObject).selectMode(lastHangulInputMode)
} else {
(sender as AnyObject).selectMode(GureumInputSourceIdentifier.qwerty)
}
manager.needsFakeComposedString = true
return CIMInputTextProcessResult.processed
}
if self.delegate === hanjaComposer {
if !hanjaComposer.mode && hanjaComposer.composedString.count == 0 && hanjaComposer.commitString.count == 0 {
// 한자 입력이 완료되었고 한자 모드도 아님
self.delegate = hangulComposer
}
}
if self.delegate === hangulComposer {
if need_hanjamode {
// 현재 조합 중 여부에 따라 한자 모드 여부를 결정
let isComposing = hangulComposer.composedString.count > 0
hanjaComposer.mode = !isComposing // 조합 중이 아니면 1회만 사전을 띄운다
self.delegate = hanjaComposer
self.delegate.composerSelected!(self)
hanjaComposer.update(fromController: controller)
return CIMInputTextProcessResult.processed
}
// Vi-mode: esc로 로마자 키보드로 전환
if GureumConfiguration.shared().romanModeByEscapeKey != 0 && (keyCode == kVK_Escape || false) {
self.delegate.cancelComposition()
(sender as AnyObject).selectMode(GureumInputSourceIdentifier.qwerty)
return CIMInputTextProcessResult.notProcessedAndNeedsCommit
}
}
return CIMInputTextProcessResult.notProcessed
}
}