Skip to content

feat: MoaKey-Vim 전체 기능 통합 (리브랜딩 + 버그 수정)#1

Merged
verlane merged 122 commits into
mainfrom
feat/rebrand-moakey-vim
May 7, 2026
Merged

feat: MoaKey-Vim 전체 기능 통합 (리브랜딩 + 버그 수정)#1
verlane merged 122 commits into
mainfrom
feat/rebrand-moakey-vim

Conversation

@verlane

@verlane verlane commented May 7, 2026

Copy link
Copy Markdown
Owner

Summary

OpenMoa(pe.aioo.openmoa)를 기반으로 MoaKey-Vim(dev.bsb.moakeyvim)으로 리브랜딩하고, 다수의 기능을 추가한 통합 PR입니다.

주요 변경사항

리브랜딩

  • 패키지명 전체 변경: pe.aioo.openmoadev.bsb.moakeyvim (107개 .kt 파일)
  • 앱 이름: 오픈모아모아키 Vim
  • 테마명: Theme.OpenMoa.*Theme.MoaKeyVim.*

버그 수정

  • 설정 가져오기 크래쉬 수정: SharedPreferences 타입 불일치 (Boolean/Int/String 분리 처리)
  • GitHub Actions CI 버전 업데이트 (actions/checkout@v1@v4, setup-java@v1@v4)

신규 기능

  • Vim 키맵: 외부 키보드 Tab 길게 누르기로 Vim 모드 진입
  • 하드웨어 키보드: Caps Lock → Ctrl 리매핑
  • 클립보드 관리: 복사 히스토리, URL 미리보기, 핀 고정, 편집
  • 단축어(Hotstring): 트리거 입력 시 텍스트 자동 치환
  • 단어 학습 & 추천: 입력 빈도 기반 한국어/영어 자동완성
  • 설정 백업/복원: JSON 형식 내보내기·가져오기

문서

  • README.md 전면 재작성 (한국어 주, 기능명 영문 병기)
  • 저작권 병기: 원작자(Ahn Kiwook) 유지 + 수정자(Songbum Bae) 추가

Test plan

  • ./gradlew testDebugUnitTest 통과 확인
  • 설정 내보내기 → 가져오기 라운드트립 정상 동작 확인
  • 첫 설치 후 키보드 활성화 및 한글 입력 확인
  • 설정 가져오기 후 크래쉬 없는지 확인
  • Vim 키맵 동작 확인 (hjkl 방향키, w/b/e 단어 이동)

verlane added 30 commits April 20, 2026 18:17
- 설정 화면(SettingsActivity) 추가: 한글 입력 모드, 키패드 높이, 한손 모드 설정
- 모아키 레이아웃(open_moa_view_moakey) 추가 및 OpenMoaView에서 모드 전환 지원
- LanguageKey 길게 누르면 설정 화면 열기(OPEN_SETTINGS 특수키 추가)
- HangulInputMode, KeypadHeight, OneHandMode config 클래스 추가
- SettingsPreferences로 SharedPreferences 접근 일원화
- 자음 키 터치 시 키 위쪽에 반투명 팝업으로 입력될 글자 표시
- 드래그 중 조합 글자 실시간 업데이트 (예: ㅇ → 오른쪽 스와이프 → 아)
- PopupWindow 사용으로 SYSTEM_ALERT_WINDOW 권한 불필요
- 설정 화면에서 키 미리보기 ON/OFF 토글 지원
- 자음 키 오른쪽 위에 상용구 첫 글자 뱃지 표시
- 탭: 상용구 전체 텍스트 입력
- 드래그: 기존 자음+모음 제스처 동작 유지
- 롱키: 팝업 메뉴 표시 (상용구 내용 / 수정 / 취소, 스와이프 선택)
  - 상용구 내용 선택 시 텍스트 입력
  - 수정 선택 시 QuickPhraseEditActivity 팝업 실행
- 상용구 키 터치 시 키 프리뷰 미표시
- QuickPhraseEditActivity: 스피너로 키 선택, EditText로 내용 편집
- SettingsActivity에 상용구 섹션 추가
- longPressThresholdTime은 Config 공통 설정값 사용
- JaumKeyTouchListener에 numberChar 파라미터 추가
- 롱프레스 시 프리뷰 팝업 자음→숫자로 전환, 손가락 뗄 때 숫자 전송
- 롱프레스 진입 후 드래그는 무시하고 숫자 입력 유지 (B안)
- 양손모드/모아키 모드 두 레이아웃에 1~0 숫자 뱃지 표시
- key_preview_popup.xml: 52dp→78dp, 32sp→48sp, 8dp→12dp (1.5배)
- SimpleKeyTouchListener: previewController 파라미터 추가, 문자 키 DOWN/UP/CANCEL 처리
- CrossKeyTouchListener: List<StringKeyMessage> 타입 강제, resolveKey() 추출, MOVE에서 방향별 실시간 업데이트
- FunctionalKeyTouchListener: previewController 추가, view.text로 프리뷰 표시, named param 명시
- OpenMoaView: 특수키 제외 모든 문자 키에 previewController 전달
- QuertyView: KoinComponent 추가, lazy previewController, 문자/숫자 키 프리뷰 적용
- PunctuationView: 동일 패턴으로 기호 키 프리뷰 적용
- SpaceLongPressAction enum 추가 (IME 선택 팝업/언어 전환/없음)
- SpaceKeyTouchListener 추가: 롱키 감지, 발동 시 공백 입력 억제 및 배경 수동 복원
- SpecialKey.SHOW_IME_PICKER 추가 및 OpenMoaIME에서 InputMethodManager.showInputMethodPicker() 호출
- 자동 마침표: 1초 이내 스페이스 두 번 입력 시 ". " 로 대체 (기본 Off)
- 7개 키보드 뷰(OpenMoaView x2, QuertyView, ArrowView, NumberView, PhoneView, PunctuationView) 스페이스 리스너 교체
- 설정 화면에 스페이스 롱키 기능(라디오), 자동 마침표 입력(스위치) 항목 추가
- KeyboardSkin enum 추가 (화이트/다크그레이/블랙/블루/그린, 기본값: 다크그레이)
- SkinApplier: 키 배경, 텍스트색, 프리뷰 배경, 키보드 배경색 생성 유틸
- 설정 화면에 키보드 스킨 선택 항목 추가
- 설정 변경 후 키보드로 돌아올 때 스킨 즉시 재적용 (onStartInputView 감지)
- 키 프리뷰 팝업 색상을 스킨에 맞게 적용
- 한손 입력 모드 빈 영역 및 네비게이션 바 배경색을 스킨 색상으로 설정
- 네비게이션 바 아이콘 색상을 스킨 밝기에 따라 자동 조정
- 키 탭 시 배경색이 흰색으로 변경되는 버그 수정 (BaseKeyTouchListener)
- Config를 data class에서 class로 변경하여 longPressThresholdTime, keyPreviewEnabled를 getter로 전환, 설정 변경 시 앱 재시작 없이 즉시 반영
- configModule을 Config(androidContext()) 형태로 단순화
- 한손모드 활성 시 이모티콘 키 크기를 20sp → 16sp(80%)로 축소
- PhraseKey 인터페이스 도입으로 QuickPhraseKey, QwertyLongKey 공통화
- QuickPhraseEditActivity + QwertyLongKeyEditActivity → PhraseEditActivity 하나로 통합
- 영문 롱키 팝업에 Spinner 추가하여 한글 팝업과 동일한 UX 제공
- 버튼 명칭 변경: OK → 저장, Cancel → 취소
- 버튼 순서 변경: [기본값] 왼쪽 고정, [취소][저장] 오른쪽 정렬
- 버튼 minWidth="0dp" 적용으로 Cancel 줄바꿈 현상 해결
- KeypadHeight 명칭 변경: 낮게 → 보통(기본)
- 팝업 인스턴스 공유 버그 수정: 키마다 QuickPhraseMenuPopup 개별 생성
- onWindowFocusChanged에서 keyHint 갱신하여 stale 표시 문제 해결
- PhraseKey 인터페이스에 name 추가로 unsafe cast 제거
- SettingsActivity commit() → apply() 변경 (메인 스레드 블로킹 방지)
- 상용구 수정 팝업 타이틀 한글/영문 통일
- QuertyView에 configurableLongKeyListeners 수집, onDetachedFromWindow/onWindowFocusChanged(false)에서 cancel() 호출
- importSettings에서 json.get() 런타임 타입 추측 제거 -> 알려진 Boolean/String 키를 optBoolean/optString으로 명시 처리
- UserCharKey enum 추가: ~ ^ ; * ! ? . 7개 키 (PhraseKey 구현)
- UserCharKeyTouchListener 추가: 탭→문자 입력, 롱탭→수정화면 바로 오픈
- PhraseEditActivity에 TYPE_USER_CHAR 추가, 첫 코드포인트만 저장
- OpenMoaView: 투핸드 4개(~^;*), 모아키 7개 전체 터치 리스너 교체
- 키보드 표시 시 onStartInputView에서 사용자 문자 라벨 갱신
- SettingsPreferences.ALL_KEYS에 UserCharKey prefKey 포함 (export/import 반영)
- 영문 자동 대문자 on/off 설정 추가
- 스페이스/엔터 길게 누름 기능 설정 추가 (방향키, 키보드 선택, 언어 전환, 없음)
- 한글/영문 단축키 명칭 정리 (상용구 → 단축키)
- 설정 메뉴 순서 정리 및 롱키 → 길게 누름 용어 통일
- importSettings 타입 안전성 개선 (optString null 전달 제거)
- 기호/방향키/숫자/전화/이모지 키보드의 엔터키를 SimpleKeyTouchListener에서
  EnterKeyTouchListener로 교체하여 롱키 동작 활성화
- 영문/기호/방향키/숫자 키보드의 한/영 키를 LanguageKeyTouchListener로 교체하여
  롱프레스(300ms) 시 설정 화면 열기 기능 추가
- LanguageKeyTouchListener에 cancel() 메서드 추가 (Timer 누수 방지)
- 각 뷰의 onDetachedFromWindow()에서 enterKeyListener/languageKeyListener cancel 처리
- 기호/영문/방향키/숫자 키보드 한/영 키 레이아웃을 LinearLayout으로 변경하여
  한글 키보드와 동일하게 '설정' 힌트 텍스트 표시
- 내보내기/가져오기 저장 위치를 앱 전용 디렉토리에서 다운로드 폴더로 변경 (MediaStore API)
- 동일 파일명 중복 엔트리 전체 삭제 후 재생성 (기존: 첫 번째만 삭제)
- openOutputStream null 반환 시 명시적 예외 처리 (기존: 조용히 실패)
- 설정 설명문에 파일명(openmoa_settings.json) 및 저장 위치 표기
- 초기화 팝업 버튼을 확인/취소로 명시적으로 통일 (기존: android.R.string.ok)
- companion object 위치를 클래스 최상단으로 이동
ACTION_DOWN 시 previewWithAppended()로 현재 조합 상태를 반영한
프리뷰 텍스트를 계산하도록 수정.
- 키 변경 시 previewController.show() 호출
- ACTION_UP 시 previewController.hide() 호출
- ACTION_CANCEL 핸들러 추가 (sendKeyMessage + cancel)
모아키 전용 설정으로 ㅣ·ㅡ 모음 키 표시 여부를 토글할 수 있음.
비표시 시 엔터 키가 해당 영역을 흡수하여 넓어짐.
설정 변경은 다음 키보드 표시 시 즉시 반영되며, 내보내기/가져오기/초기화 대상에 포함.
- SettingsPreferences: prefs() 헬퍼 추출로 중복 제거
- OpenMoaIME: keyboardViews를 Map으로 변경, refreshSkinIfNeeded 후 setKeyboard 호출 누락 수정
- SettingsActivity: export/import 예외 로그 추가
'모음 키 표시' 토글을 제거하고, 입력 방식 선택에 '모아키+'를 추가.
모아키+는 모아키 레이아웃에서 ㅣ·ㅡ 모음 키를 숨기고
스페이스바 행 키 비율을 재조정한 모드.

- HangulInputMode에 MOAKEY_PLUS 추가 (순서: TWO_HAND_MOAKEY → MOAKEY → MOAKEY_PLUS)
- isMoakeyLayout / showsMoeumKey 헬퍼 프로퍼티 추가
- Config.moeumKeyVisible 제거, SettingsPreferences moeum_key_visible 관련 제거
- 모음 키 숨김 시 스페이스바 행 weight 재조정
  (emojiKey 0.5 / spaceKey 2 / enterKey 1.5)
- GestureAngleView: 8핀 드래그로 모음 판정 경계 조절하는 커스텀 뷰
- GestureAngleActivity: 프리셋 스피너 + 각도 뷰 + 적용 버튼
- GestureAngles / GestureAnglePreset: 각도 데이터 및 5가지 프리셋 (오른손/왼손/양손/6방향/사용자 정의)
- JaumKeyTouchListener: 저장된 gestureAngles 기반으로 모음 판정
- 스피너 초기화 콜백 억제 버그 수정 (setAdapter 이전부터 suppress, post로 해제)
- CUSTOM 선택 시 SharedPreferences 재로드 제거로 드래그 중 각도 점프 버그 수정
verlane added 28 commits April 27, 2026 23:24
- showEmpty()에 클립보드 아이콘 추가 (클립보드 비어있을 때도 표시)
- 비밀번호 필드에서는 클립보드 아이콘 숨김 (showClipboardIcon = false)
- setSuggestions()에서 container.gravity를 START로 설정하여 좌측 정렬
- 그 외 케이스(showClipboard, showClipboardIconOnly, showSelectionActions)는 CENTER 유지
- 내부 편집 폼(클립보드/핫스트링/구절)에서 추천바 기능 동작
- 폼 포커스 시 커서 위치 기준 단어 추출해 추천 갱신
- 추천 단어 선택 시 폼 EditText 내 단어 치환
- 좌우 커서 이동, 클립보드 붙여넣기 아이콘 폼 내 동작
- TextWatcher 기반 undo/redo 스택 구현 (폼 전용)
- 클립보드 편집 폼 멀티라인 지원 (최대 4줄, 내부 스크롤)
- 핫스트링 폼 포커스 전환 추적 (triggerEditText ↔ expansionEditText)
TYPE_TEXT_VARIATION_URI(0x10)와 TYPE_NUMBER_VARIATION_PASSWORD(0x10)가
동일 값이라 variation만 비교하면 URI 필드(예: Chrome URL=0x80011)가
password로 잡혀 추천바와 클립보드가 비활성화되던 문제 해결.

inputClass로 먼저 분기 후 각 클래스별 password variation을 비교하도록 수정.
- HangulInputMode에 QWERTY/QWERTY_SIMPLE 추가
- 단모음 자판: ㅂㅈㄷㄱㅅㅗㅐㅔ / ㅁㄴㅇㄹㅎㅓㅏㅣ / ㅋㅌㅊㅍㅜㅡ
- multi-tap 합성: ㅏㅏ→ㅑ, ㄱㄱ→ㄲ 등 (400ms 임계, IME 측 처리)
- HangulAssembler.replaceLastJamo: 음절 보존하며 마지막 자모만 교체
- 가로 모드 한글 쿼티 강제 토글 (landscape_qwerty)
- onConfigurationChanged 회전 시 자판 재구성
- ',?.!' 키 두 줄 텍스트 정렬 보정 (includeFontPadding=false)
- 기존 webp + adaptive icon XML → 새 PNG 아이콘으로 교체
- mipmap-{mdpi,hdpi,xhdpi,xxhdpi,xxxhdpi} 각 밀도별 ic_launcher.png / ic_launcher_round.png 추가
- mipmap-anydpi-v26 adaptive icon XML 및 drawable-v24 foreground 벡터 삭제
- 물리 키 단축키: RAlt(KEYCODE_ALT_RIGHT) 단독, Shift+Space, KEYCODE_LANGUAGE_SWITCH/KANA/HENKAN
- BT 키보드 두벌식 한글 입력 (HardwareDubeolsikMapper, QWERTY→자모 매핑)
- Gboard 스타일 플로팅 인디케이터: 한/영 표시, 탭 토글, 드래그+좌우 가장자리 스냅, 위치 저장
- 외장 키보드 lifecycle 추적: onStartInput/onFinishInput/onUnbindInput + 3초 polling으로 input binding 변화 감지
- 권한 안내 3계층: 설정 화면 상단 배너, 입력 시작 시 1회 Notification, Toast 폴백
- 외장 키보드 카테고리 설정 4개: 인디케이터 ON/OFF, 한/영 키 ON/OFF, RAlt ON/OFF, Shift+Space ON/OFF

구조 분리 (기존 OpenMoaIME.kt 1000줄 룰 대응):
- hardware/: HardwareKeyboardController, HardwareKeyShortcutDetector, HardwareDubeolsikMapper, OverlayPermissionNotifier, ShortcutAction
- floating/: FloatingIndicatorManager, FloatingSnapCalculator
- IMEModeExt: isKoreanFamily, resolveLanguageSwitchTarget

테스트:
- IMEModeExtTest, HardwareKeyShortcutDetectorTest, HardwareDubeolsikMapperTest, FloatingSnapCalculatorTest
- SettingsFragment: ALLOWED_KEYS에 NumberLongKey 추가 (import 시 복원 누락 수정)
- NumberView: onAttachedToWindow에서 updateKeyHints() 호출 (재표시 시 hint 갱신)
- OpenMoaIME: dispatchHardwareJamo를 LocalBroadcastManager.sendBroadcast로 교체
- OpenMoaIME: inputBindingPollRunnable 존재 이유 주석 추가
- HardwareKeyboardController: 불필요한 @volatile 제거 (모든 접근이 Main 스레드)
- Enter 키 입력 시 Space와 동일하게 단어 학습 트리거
- 구두점(.,!?;:) 입력 시 앞 단어 학습 트리거 추가
- 방향키 이동 시 사전에 있는 단어만 학습 (오탐 방지)
- 사전에 있는 단어를 커밋할 때 minLearnCount까지 즉시 카운트 보장
- Dictionary.contains(), UserWordStore.ensureMinCount() 신규 추가
- KoreanTrieDictionary.buildTrie IO 스레드 처리 수정
- ensureMinCount Backspace 경합 조건 수정
- beforeASpace/afterLSpace: GONE 대신 weight=0으로 조정 (수직 체인 앵커 유지)
- Shift/Backspace: 단모음 시 weight 1.5→1.0으로 축소
- 결과: ㅂ행·ㅁ행·ㅋ행 모두 visible weight=8.0으로 통일
- onAttachedToWindow 오버라이드로 뷰 re-attach 시 weight 복원 보장
- HangulAssembler: ㅗ+ㅏ→ㅘ, ㅗ+ㅐ→ㅙ, ㅜ+ㅓ→ㅝ, ㅜ+ㅔ→ㅞ 조합 추가
- HangulAssembler: 두벌식 모드(decomposeMoeum=true)에서 복합 모음 backspace 시
  첫 번째 구성 모음으로 단계적 분해 (예: 왜→오→ㅇ)
- HangulAssembler: 단순 모음도 clear 대신 제거하여 자음 복원 (예: 가→ㄱ)
- OpenMoaIME: isQwertyKoActive() 헬퍼 추출, backspace 두 곳에 적용
- strings: '한글 쿼티(2벌식)' → '두벌식', '두벌식 단모음'으로 용어 통일
물리 한/영 키, RAlt, Shift+Space 전환은 항상 ON으로 고정되어
설정 항목으로 노출할 필요가 없어 제거함.
플로팅 인디케이터, 다른 앱 위에 표시 권한 2개 항목만 유지.
- CapsLock→LCtrl: CapsLock 누르는 동안 다른 키에 Ctrl 적용
  - CapsLock ON 시 영어 소문자 강제 (Shift+키는 대문자)
- Tab-hold vim 모드: Tab 누른 상태에서 vim normal 모드 동작
  - h/j/k/l 커서 이동, w/b/e 단어 이동, 0/$ 줄 처음/끝
  - x 문자 삭제, dd 줄 삭제, v visual mode, y yank
  - visual mode: hjkl로 선택 확장, d/x로 삭제, y로 복사 후 해제
- Tab+u/U: Undo/Redo (Ctrl+Z/Y)
- Tab+,: Backspace, Tab+.: Delete, Tab+n: Ctrl+Backspace
- Tab+i: 위에 새 줄 삽입 (Home+Enter+Up)
- Tab+c/C: Cut (Ctrl+X)
- v+hjkl 블록 선택: Shift 키 이벤트 명시적 전송으로 수정
- Tab 릴리즈 시 visual mode 해제, 인디케이터 V/F 표시 로직 수정
- 인디케이터 롱탭(시스템 롱프레스 타임아웃)으로 설정 화면 즉시 진입
- enabled setter에서 reset() 자동 호출 (CapsLockRemapper, TabHoldVimDetector)
- tryForceLowercase commitText 반환값 처리 수정
- PhoneView 숫자키를 HintKeyView로 교체하고 QwertyKeyTouchListener 적용
- 페이지 0(숫자)은 NumberLongKey 기반 힌트/팝업, 페이지 1(특수문자)은 기존 방식 유지
- 숫자키 탭 시 해당 키의 단어가 추천단어 바에 표시
- 추천단어 선택 시 커서 앞 숫자 확인 후 교체 (beginBatchEdit 보호)
- QuickPhraseMenuPopup 10개를 인스턴스 필드로 미리 할당하여 재사용
한글 코드포인트만 검사하던 isKorean 분기를 TextWidthClassifier로 교체,
히라가나/가타카나/CJK 한자/이모지 등 와이드 글리프도 동일하게 7글자 제한 적용.
상수명 KO/EN -> WIDE/NARROW 로 rename.
- 클립보드 리스너에서 idle 상태 시 suggestion bar 즉시 갱신
- onUpdateSelection 타이밍 이슈 방지를 위해 Handler.post로 지연 처리
- 추천 단어 폰트 17sp → 15.3sp (×0.9), 좌우 패딩 10dp → 5dp (÷2)
- Vim 키 매핑 보기 항목 추가 (풀 화면 Activity, 이동/편집/비주얼 모드 3섹션)
- 외장 키보드 설정 항목 아이콘 각각 교체 (float/layers/caps/vim/info)
- 'Tab-hold vim 모드' → 'Vim 모드'로 명칭 변경
- ScrollView+LinearLayout → RecyclerView+ListAdapter(DiffUtil)로 교체
- 검색바 추가 (200ms 디바운스, 대소문자 무시)
- 정렬 메뉴 추가: 빈도↓/빈도↑/가나다↑/↓, prefs 영속화
- 점진 로딩: 첫 50개 표시 후 스크롤 끝 근처에서 50개씩 추가
- 하단 카운트 텍스트 표시 (총 N개 / 표시 M개)
- 탭 버튼을 MaterialButtonToggleGroup으로 교체해 선택 상태 표시
- 검색창 높이 축소 (OutlinedBox.Dense 스타일)
- 화면 회전 시 탭/검색어/페이지 크기 상태 복원
- 정렬 및 필터 로직 단위 테스트 추가
- 9개 섹션을 입력 방식 / 키보드 외형 / 키 동작 / 입력 보조 / 클립보드 / 소리 및 진동 / 외장 키보드 / 데이터 관리 / 앱 정보 순으로 재배치
- 단축 기능 + 키보드 입력 섹션을 입력 보조로 통합
- 키보드 설정 섹션을 외형(스킨/높이/한손/미리보기)과 동작(길게누름) 섹션으로 분리
- 외장 키보드 섹션을 하단으로 이동
- 클립보드 OFF 시 최대 저장 개수/자동 삭제 기간 비활성화
- 단어 추천 모두 OFF 시 학습 최소 횟수/학습 단어 관리 비활성화
- Vim 모드 OFF 시 Vim 키 매핑 보기 비활성화
- SharedPreferences 키 변경 없음 (기존 사용자 설정 보존)
- 패키지명 pe.aioo.openmoa → dev.bsb.moakeyvim 전체 변경
- 앱 이름 오픈모아 → 모아키 Vim
- 테마명 Theme.OpenMoa → Theme.MoaKeyVim
- LICENSE에 원본 저작자(Ahn Kiwook) attribution 추가
- GitHub Actions checkout/setup-java v1 → v4 업그레이드
- 설정 임포트 시 INT_KEYS(floating_indicator_x/y) putInt 처리 버그 수정
- 설정 임포트 시 BOOLEAN_KEYS에 hw_capslock_to_ctrl, hw_tab_vim_mode 누락 수정
- 설정 임포트 파싱 테스트 케이스 추가 및 동기화
@verlane verlane merged commit 894c29e into main May 7, 2026
1 check passed
@verlane verlane deleted the feat/rebrand-moakey-vim branch June 28, 2026 02:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant