영문 자판으로 잘못 친 dkssud가 안녕으로 바뀌는 그림

dkssudgktpdy 👋

한/영 키를 자주 깜빡합니다.

안녕을 치려고 했는데 화면에는 dkssud가 찍혀 있어요. 보통 여기쯤에서 알아챕니다. 지우고, 한/영 키를 누르고, 다시 칩니다. 반대도 있어요. transformer를 치려다 ㅅㄱ문래귿ㄱ가 됩니다.

비슷한 앱을 찾아봤습니다. 꽤 있더라고요. 단축키를 누르면 방금 친 걸 뒤집어 주는 앱들은 내가 먼저 틀린 걸 알아채야 합니다. 스페이스를 누르면 알아서 고쳐 주는 앱도 있었는데, 한글 모드에서 친 영어만 고쳐 주고 전용 입력기를 깔아야 했어요. 러시아에는 이 장르의 원조 같은 앱이 있는데, 맥에서는 영어와 러시아어만 됩니다.

영문 모드에서 친 한글을 알아보고, 고쳐 주고, 입력기까지 바꿔 주는 앱은 못 찾았습니다.

그래서 만들었어요.

meant는 메뉴 막대에 사는 앱입니다. 글을 쓰다 스페이스를 누르면, 방금 친 단어가 잘못된 자판처럼 보일 때 커서 옆에 작은 창이 뜹니다. dkssud → 안녕. Enter를 누르면 바뀌고, 입력기도 한글로 넘어갑니다. 그 자리에서 그냥 이어서 치면 돼요. 한/영 키를 누를 일이 거의 없어집니다.

meant 데모. 메모 앱에서 dkssud를 치고 스페이스를 누르면 안녕으로 바꿀지 묻는 창이 뜨고, Enter를 누르면 바뀌면서 입력기도 한글로 넘어갑니다.


뒤집기는 쉬워

두벌식 자판과 영문 자판은 키가 하나씩 짝지어져 있습니다. d는 ㅇ, k는 ㅏ. 그러니 dkssudgktpdy는 사전 없이도 안녕하세요가 됩니다. 자음과 모음을 받침까지 맞춰 조립하는 규칙만 있으면 돼요. 한글 입력기가 하는 일을 그대로 따라 하는 거죠.

대문자는 조금 다릅니다. 두벌식에서 Shift는 쌍자음이에요. q는 ㅂ, Q는 ㅃ. 그래서 hello는 ㅗ디ㅣㅐ인데 HELLO는 ㅗ띠ㅣㅒ입니다.

그런데 아쉬운 건, 이게 한쪽으로만 됩니다. 영문 모드에서 친 한글은 Shift를 그대로 들고 있어요. ㄸ은 E, ㄷ은 e. 대소문자만 보면 원래 글자를 알 수 있습니다.

한글 모드에서 친 영어는 아니에요. 두벌식에서 Shift가 글자를 바꾸는 키는 q w e r t o p 일곱 개뿐이고, 나머지는 눌러도 똑같이 나옵니다. H도 h도 ㅗ예요. 그래서 ㅗ띠ㅣㅒ를 되돌리면 HELLO가 아니라 hEllO가 됩니다. 사라진 Shift는 글자만 봐서는 알 수 없어요.

아무튼, 어려운 건 뒤집는 게 아니었어요. 언제 건드리느냐였습니다.

스페이스를 누를 때마다 뒤집어 보는 건 괜찮습니다. 계산이 싸니까요. 문제는 그때마다 창을 띄우는 거예요. 사람은 시키지 않은 일을 싫어하잖아요. 너무 자주 뜨면 앱을 끕니다.

다행히 평소에 치는 글은 대부분 맞게 친 겁니다. 안녕하세요를 뒤집으면 dkssudgktpdy, 영어 단어가 아니죠. hello를 뒤집으면 ㅗ디ㅣㅐ, 한글이 아니고요. 한쪽만 말이 될 때만 띄우면 됩니다.

양쪽이 다 말이 되는 경우도 있습니다. and를 두벌식으로 치면 뭉입니다. 사전에는 없는 말일지 몰라도 깨진 단어는 아니죠. and도 뭉도 말이 됩니다. 이런 건 앱이 알 수가 없으니 단축키로 넘겼어요. 뭉 뒤에서 단축키를 누르면 묻지 않고 and으로 바꿉니다. 스페이스는 제안이고, 단축키는 실행입니다.


안녕안녕안녕

뒤집는 엔진은 금방 됐습니다. 진짜 일은 남의 앱 글자를 바꾸는 데서 시작됐어요. macOS에는 다른 앱의 입력창을 고칠 수 있는 통로(손쉬운 사용)가 있는데, 앱마다 반응이 달랐습니다. 바꾼 척만 하는 앱도 있고, 바꿔 놓고도 한동안 옛날 글자를 알려 주는 앱도 있어요.

처음엔 Enter를 눌러도 아무 일이 없었습니다. 그래서 안 되면 다음 방법으로 넘어가게 세 가지를 준비했더니, dkssud가 안녕안녕안녕이 됐어요. 첫 번째가 성공했는데 옛날 글자를 보고 실패한 줄 안 거죠.

다음엔 커서가 맨 앞으로 갔습니다. 빈 줄이 사라지기도 했고요. 단어 하나를 바꾸려고 글 전체를 새로 써 넣고 있었거든요. 단어만 바꾸고 커서 자리를 계산해서 옮기게 했더니, 이번엔 커서가 단어 중간에 섰습니다. 입력창마다 한글을 글자로 세기도 하고 자모로 세기도 해서, 계산이 맞을 리가 없었어요. 한 시간 가까이, 매번 조금씩 다르게 틀렸습니다.

그래서 사람이 고치듯이 하기로 했습니다. 고칠 글자 수만큼 Shift+←로 선택하고, 지우고, 새 단어를 넣는다. 앱한테 부탁하지 않고 키보드로 직접 하는 거예요. 키보드 입력은 거의 모든 앱이 똑같이 받고, 커서는 넣은 단어 끝에 알아서 남습니다.

그래도 두 군데가 더 걸렸어요. 한글은 치는 중일 때 지우면 받침만 지워집니다. 밑줄 그어진 뭉을 지우면 ㅇ만 사라지는 식이죠. 그래서 조합부터 끝내고 바꿉니다. Notion은 앱이 보낸 Cmd+V를 무시해서, 키보드에서 직접 누른 것처럼 보내야 들어갔습니다.


틀린 걸 어떻게 알지?

HUD가 떴을 때를 치고 있었습니다. HUD를 영어로 치고, 한/영을 안 바꾸고 그대로 떴을을 쳤어요. 화면에는 EjTdmf. 일부러 해 본 겁니다. 이 앱이 있는 이유가 바로 이 상황이니까요.

창이 안 떴습니다.

ㄸ과 ㅆ은 Shift를 눌러야 나옵니다. 그래서 E와 T가 대문자예요. 앱은 대소문자가 섞인 EjTdmf를 getValue 같은 코드로 보고 건드리지 않았던 겁니다. 코드를 망가뜨리지 않으려고 넣은 규칙이 정작 제일 중요한 경우를 막고 있었어요. 뒤집었을 때 온전한 한글이 나오면 대소문자가 섞여도 띄우도록 바꿨습니다.

반대쪽에서도 비슷한 일이 있었습니다. ㅔㅑㅜㅜㅑㅜㅎ은 pinning인데 창이 안 떴어요. 앱이 가진 영어 단어 목록에 pinning이 없었거든요. 목록에 넣으면 끝나는 일이긴 했습니다. 그런데 그러면 빠진 단어를 찾을 때마다 앱을 업데이트해야 하잖아요.

질문을 바꿨습니다. 바꾼 결과가 아는 단어인지만 묻지 말고, 지금 친 게 이상한지도 보자. ㅔㅑㅜㅜㅑㅜㅎ은 pinning을 몰라도 이상합니다. 자모만 늘어서 있으니까요. 둘 중 하나라도 맞으면 띄우기로 했어요.

그러면 ㅋㅋㅋ도 뜹니다. ㅠㅠ도요. 그건 맞게 친 건데 말이죠. 하지만 그 땐 취소하면 됩니다. 그리고 앞으로 같은 텍스트를 고치지 않도록, 창이 떴을 때 Tab을 누르면 다음부터 그 단어는 묻지 않게 했습니다.

풀었더니 이번엔 너무 풀렸어요. MLOps를 쳤더니 ㅢㅒㅔㄴ로 바꾸겠냐고 묻습니다. MLOps가 영어 단어 목록에 없으니 이상하다고 본 거예요. 근데 ㅢㅒㅔㄴ은 누가 봐도 쓰려던 말이 아니죠. 영어를 한글로 바꿀 때는 결과가 온전한 한글 글자일 때만 묻도록 다시 조였습니다.

정리하면 지금은 이럴 때 묻습니다.

  • 영어로 친 한글: 알파벳이 네 개 이상이고, 영어 단어 목록에 없고, 뒤집으면 자모가 따로 놀지 않는 두 글자 이상의 한글이 될 때.
  • 한글로 친 영어: 친 글자에 따로 노는 자모가 있거나, 뒤집으면 목록에 있는 네 글자 이상의 영어 단어가 될 때.
  • 한글과 알파벳이 섞인 단어는 건드리지 않습니다.
  • Tab으로 넘긴 단어는 다시 묻지 않습니다.
  • 무와 an처럼 양쪽 다 말이 되는 건 묻지 않고, 단축키로 바꿉니다.

트리거

트리거에 관한 두 가지를 더 생각했어요.

하나는 스페이스 말고도 단어가 끝나는 때가 있다는 것. dkssud.처럼 마침표가 바로 붙거나, 따옴표나 괄호를 닫을 때요. 이건 고쳤습니다. 그래서 지금은 마침표, 쉼표, 따옴표, 괄호로 단어가 끝나도 창이 뜹니다. 기호는 그대로 두고 단어만 바꿔요. dkssud.는 안녕.이 됩니다.

다른 하나는 스페이스로 받기였습니다. 잘못 친 어절 다음 스페이스를 누르면 수정 제안이 트리거 됩니다. 그 다음 수정하려면 Enter를 누르면 바뀌어요. 그런데 스페이스를 누르고 Enter를 누르는 게 두 동작처럼 느껴졌습니다. 번거로웠죠. 대신 스페이스를 두 번 누르면 한 동작 같을 것 같았고요.

근데 창이 떠 있을 때 스페이스는 사실 “아니야, 그냥 둬”였습니다. 잘못 뜬 제안은 그냥 계속 치면 사라져요. 스페이스를 확정으로 바꾸면, 제안을 무시하고 계속 치던 사람이 원하지 않던 변환을 당합니다. 타이밍 문제와 실수 방지를 이유로 이건 접었어요.


지금도 한/영 키를 자주 깜빡합니다. 이제 괜찮아요. 👍

설치 파일은 GitHub에 있습니다.