다중 도구 환경에서의 커서 모양 관리

#wezterm#neovim#zsh#terminal#cursor
• • •

TL;DR: 터미널, 쉘, 에디터가 각각 커서 모양을 독립적으로 제어할 수 있는 다중 계층 환경에서, 최종적으로 보이는 커서는 가장 하위 계층(현재 실행 중인 애플리케이션)의 설정이 우선한다. 이 계층적 우선순위를 이해하면 커서가 예상과 다르게 보일 때 어떤 도구의 설정을 수정해야 할지 명확히 판단할 수 있다.

터미널 환경에서 보이는 커서 모양은 터미널 에뮬레이터, 쉘, 그리고 내부에서 실행되는 애플리케이션(에디터 등)이라는 여러 소프트웨어 계층에 의해 영향을 받습니다. 이 문서는 각 계층이 커서를 제어하는 메커니즘과, 최종적으로 어떤 모양이 화면에 표시되는지를 결정하는 상호작용 원리를 설명합니다.

커서 모양은 터미널 에뮬레이터(WezTerm), 쉘(zsh with zsh-vi-mode), 터미널 내 애플리케이션(Neovim) 세 계층에서 각각 제어될 수 있다. 각 계층은 하위 계층에게 커서 모양 변경 요청(DECSCUSR 시퀀스)을 보낼 수 있으며, 실제 보이는 커서 모양은 가장 최근에 DECSCUSR (Device Control String for Cursor Style, 커서 스타일 제어 ANSI 시퀀스) 시퀀스를 전송한 애플리케이션(쉘, 에디터 등)의 요청에 의해 결정된다.

계층별 제어 메커니즘:

  1. 터미널 에뮬레이터 (WezTerm): config.default_cursor_style으로 전체 기본값을 설정한다. 이는 애플리케이션이 별도로 커서를 변경하지 않을 때 적용되는 초기값이다.
  2. 쉘 및 쉘 플러그인 (zsh-vi-mode): 쉘 자체나 플러그인이 현재 모드(예: 명령 모드/입력 모드)에 따라 터미널에 커서 변경 시퀀스를 보낸다. 예를 들어 zsh-vi-mode는 기본적으로 Normal 모드에서 block, Insert 모드에서 beam 커서로 자동 전환한다. 이 동작은 ZVM_CURSOR_STYLE_ENABLED 변수로 비활성화하거나, ZVM_INSERT_MODE_CURSOR, ZVM_NORMAL_MODE_CURSOR 변수로 세부 모양을 커스터마이즈할 수 있다.
  3. 터미널 애플리케이션 (Neovim): 애플리케이션은 런타임 중 가장 적극적으로 커서를 제어한다. Neovim은 guicursor 옵션(vim.opt.guicursor)을 통해 모드별 정밀한 커서 스타일(block, underline, bar, blink 여부 등)을 설정하며, 이 설정이 쉘이나 터미널의 기본값을 무조건 덮어쓴다.

한글 입력에 대한 실용적 고려사항: 한글은 자음과 모음이 조합되는 과정에서 글자 영역이 변화한다. Insert 모드에서 block 커서는 조합 중인 글자를 시각적으로 가려 불편함을 줄 수 있다. 따라서 한글 입력이 빈번한 환경에서는 Insert 모드 커서를 block이 아닌 underline(hor20) 또는 bar(ver25)로 설정하는 것이 실용적이다. Normal 모드는 상태 구분을 위해 block을 유지하는 것이 일반적이다.

실제 WezTerm 설정에서 default_cursor_style = "SteadyUnderline"을 지정했음에도 쉘 프롬프트에서 block 커서가 관찰될 수 있다. 그 원인은 zsh-vi-mode 플러그인이 Insert 모드 진입 시점에 커서를 beam으로 변경했지만, 사용자가 한글 조합 중이거나 플러그인의 초기 모드 설정(ZVM_LINE_INIT_MODE)에 의해 최종 모양이 달라졌기 때문이다.

문제 해결은 계층 구조를 따라 아래로 내려가며 점검해야 한다: 1) Neovim 내부라면 guicursor 설정 검토, 2) 쉘 프롬프트라면 zsh-vi-mode 설정 검토, 3) 모든 경우에 무관한 기본 모양이라면 WezTerm 설정 검토.

관련 항목

  • DECSCUSR (커서 스타일 제어 ANSI 시퀀스)
  • zsh-vi-mode 플러그인 동작
  • Neovim guicursor 옵션 세부 문법

Open questions

  • IME(입력기) 조합 상태 표시가 터미널 커서와 어떻게 상호작용하는지 구체적인 메커니즘
published 9 days ago · last updated 9 days ago