원본 프로젝트: gureum/gureum — macOS/iOS 한글 입력기, Swift ~10K LOC (BSD + LGPL) 핵심 의존: libhangul (C, 한글 조합 상태 머신), Apple InputMethodKit 증류 기준: gureum v1.13.2 (commit
b495b70시점 소스 분석)
이 문서는 gureum 입력기의 아키텍처를 분석·증류하여, AI 코딩 에이전트가 동등한 입력기를 재구현할 수 있도록 작성한 Ghost Library입니다.
한글 1개 자판(두벌식) + 영문 전환이 되는 최소 동작 입력기.
참조:
OSXCore/InputController.swift,OSXCore/InputReceiver.swift,OSXCore/InputMethodServer.swift
macOS TSM → IMKServer (싱글턴)
→ InputController (IMKInputController)
→ InputReceiver (전처리, 커밋/업데이트 흐름)
→ Composer Chain
├─ HangulComposer (libhangul 래핑)
└─ RomanComposer (패스스루)
3계층 분리: IMK 인터페이스 → 처리 로직 → 조합 로직 (플랫폼 무관)
protocol Composer {
var delegate: Composer! { get set }
var composedString: String { get } // 조합 중 (밑줄)
var commitString: String { get } // 확정 대기
func dequeueCommitString() -> String // 소비 후 비움
func cancelComposition()
func input(text:key:modifiers:client:) -> InputResult
}- 기본 구현이 모든 호출을
delegate로 위임 - 이중 버퍼: composedString(밑줄) / commitString(확정) + dequeue 큐 패턴
참조:
OSXCore/HangulComposer.swift, libhangulHGInputContext
"r"(ㄱ) → process → preedit=[ㄱ] → 밑줄 "ㄱ"
"k"(ㅏ) → process → preedit=[가] → 밑줄 "가"
"s"(ㄴ) → process → commit=[가] preedit=[ㄴ] → "가" 확정, 밑줄 "ㄴ"
libhangul의 HGInputContext가 초성/중성/종성 상태 머신을 관리. HangulComposer는 얇은 래퍼.
- libhangul 출력: 첫가끝(U+1100대) →
representableString()으로 호환 자모(U+3131대) 변환 - 옛한글은 원본 유지, 초성/중성 필러(U+115F, U+1160) 제거
GureumComposer가delegate를 HangulComposer ↔ RomanComposer로 교체 (Strategy)- 전환 시
cancelAndCommit()→ 조합 확정 →selectMode()→ macOS에 알림
참조:
OSXCore/HangulComposer.swift—ComposerTypeenum,OSXCore/data/(키보드/조합 규칙 XML)
두벌식, 두벌식 옛글, 세벌식(최종/390/순아래/옛글/2011/2012/2014/2015), 안마태, 로마자 — setKeyboard(identifier:)로 libhangul 키-자모 매핑 테이블 변경.
QWERTY/Dvorak/Colemak — keyMap: [Character: Character] 딕셔너리로 매핑. system 타입은 OS 기본 사용.
참조:
OSXCore/InputMethodServer.swift—IOKitty클래스,OSXCore/InputController.swift—handle(_:client:)
| 트리거 | 감지 | 비고 |
|---|---|---|
| 커스텀 단축키 | filterCommand() | 설정 가능 |
| CapsLock <0.5초 | IOKitty (IOHIDManager) | NSEvent 불가, 하드웨어 선점 필요 |
| CapsLock ≥0.5초 | IOKitty | 원래 CapsLock 유지 |
| 우측 Alt/Ctrl | IOKitty | 우측 modifier 감지 |
| ESC (Vi 모드) | filterCommand() | 코딩용 |
IOHIDManager를 쓰는 이유: macOS가 CapsLock을 입력기 전에 자체 처리하므로 NSEvent로는 짧게/길게 구분 불가.
UserDefaults 싱글턴 (suite name 기반). 마지막 한글/로마자 모드 기억, 단축키 커스텀, 옵션 키 동작 선택. HangulComposer가 KVO로 설정 변경 실시간 반영.
이중 위임: GureumComposer → SearchComposer → HangulComposer
한글 입력을 delegate에 위임하면서 조합 결과를 가로채어 검색.
- 비동기 검색:
DispatchQueue.global+DispatchWorkItem취소 (debounce) - 후보창: IMKCandidates 활용
- 후보 선택: "한자:뜻" 형식에서 한자만 추출 커밋
- ESC 탈출, 조합/커밋 비어있으면 자동 복귀
참조:
OSXCore/Configuration.swift,OSXCore/HangulComposer.swift
| 설정 | 용도 |
|---|---|
| ` → ₩ 변환 | 한글 모드 원화 기호 |
| JDK 호환 | 기호도 조합 상태 유지 |
| MS Windows 호환 | 종성 결합 허용 |
| 모아치기 자동 교정 | 동시 타건 순서 무관 |
| 세벌식 정석 | 엄격 조합 규칙 |
참조:
iOSShared/,iOSApp/
macOS와 공유하는 것은 libhangul 조합 로직뿐. 나머지는 완전히 별도 아키텍처.
UIInputViewController
→ BasicInputViewController (텍스트 입출력, 문서 컨텍스트)
→ InputViewController (스와이프 제스처, 자동 대문자화)
참조:
iOSShared/GRKeyboardLayoutHelper.swift,iOSShared/QwertyKeyboardLayout.swift,iOSShared/TenkeyKeyboardLayout.swift
GRKeyboardLayoutHelper — Position(row, column) + delegate 프로토콜 기반 그리드 엔진. 버튼 생성과 배치 분리.
지원 레이아웃: QWERTY(10-9-7), 기호 2세트, 두벌식(KS X 5002), 단모음(8-8-6), 천지인, 천지인+, 텐키 숫자/영문, 숫자패드, 이모티콘
Hangeul.swift — 기존 조합과 새 조합의 diff를 계산해 deleteBackward/insertText로 최소 변경만 적용.
JSON 기반. 디바이스/방향별 trait → 그룹(qwerty/tenkey/numpad) → 분류(key/special/function) → 캡션 클래스 cascade. 리소스는 Base64로 App Group UserDefaults에 저장.
이 Phase는 gureum 원본에 없는 확장 기능 제안임.
"gksrmf" 입력 중 한글 모드가 아닌 것을 감지 → "한글" 제안 (Ghost Text).
단순 음절 매칭이 아닌 문장 맥락으로 후보 순위 결정. 로컬 n-gram 또는 경량 모델.
조합 완료된 문장에 밑줄 표시 + 교정 후보. macOS NSSpellChecker 연동 또는 자체 사전.
- Composer Chain이 전체 확장성의 열쇠 — 새 기능 = 새 Composer + 라우터에 연결. →
Composer.swift - 이중 버퍼 + dequeue는 IMK 필수 패턴 — 조합 중(밑줄)과 확정을 반드시 분리. →
InputReceiver.swift - IOHIDManager는 macOS 입력기의 현실적 제약 해결책 — 접근성 권한 필요. →
InputMethodServer.swift - libhangul이 한글 조합 복잡성을 캡슐화 — 직접 구현하지 않는다. → libhangul
- iOS는 별도 아키텍처 — 공유하는 것은 조합 엔진뿐. →
iOSShared/
| 파일 | 경로 | 역할 |
|---|---|---|
| Composer.swift | OSXCore/ |
Composer 프로토콜 + 기본 구현 |
| GureumComposer.swift | OSXCore/ |
최상위 라우터, 입력 모드 전환 |
| HangulComposer.swift | OSXCore/ |
libhangul 래핑, 한글 조합 |
| RomanComposer.swift | OSXCore/ |
로마자 레이아웃 매핑 |
| SearchComposer.swift | OSXCore/ |
한자/이모지 검색 |
| InputController.swift | OSXCore/ |
IMK 이벤트 핸들러 |
| InputReceiver.swift | OSXCore/ |
입력 처리 오케스트레이터 |
| InputMethodServer.swift | OSXCore/ |
IMKServer + IOKitty |
| Configuration.swift | OSXCore/ |
설정 관리 (UserDefaults) |
| KeyCode.swift | OSXCore/ |
하드웨어 키 코드 정의 |
| InputViewController.swift | iOSShared/ |
iOS 키보드 컨트롤러 |
| Hangeul.swift | iOSShared/ |
iOS 한글 조합 엔진 |
| Theme.swift | iOSShared/ |
iOS 테마 시스템 |
| GureumTests.swift | GureumTests/ |
테스트 (930줄, 모아치기 포함) |