Skip to content

fix: setup-keybind이 oh-my-tmux 사용자의 ~/.tmux.conf를 손상시키는 문제 (#15) - #21

Merged
lunemis merged 1 commit into
mainfrom
fix/issue-15-oh-my-tmux
May 4, 2026
Merged

fix: setup-keybind이 oh-my-tmux 사용자의 ~/.tmux.conf를 손상시키는 문제 (#15)#21
lunemis merged 1 commit into
mainfrom
fix/issue-15-oh-my-tmux

Conversation

@lunemis

@lunemis lunemis commented May 4, 2026

Copy link
Copy Markdown
Owner

Fixes #15.

Summary

oh-my-tmux는 ~/.tmux.confcut -c3- | sh로 처리해서 주석에 인코딩된 헬퍼 함수를 실행한다. 기존 setup-keybind는 일반(주석 없는) bind 라인을 그대로 append했고, 앞 두 글자가 잘려나가 nd m display-popup ... 같은 invalid shell이 되어 tmux source-file ~/.tmux.conf가 exit 127로 실패했다.

이슈에서 제안된 A+B 하이브리드 감지(symlink target + 시그니처 라인) + sentinel 앞 삽입 방식으로 구현했고, 추가로 발견한 엣지 케이스를 함께 다뤘다.

Changes

tmux/popup.go

  • isOhMyTmux() — symlink target에 .tmux/ 포함 OR 첫 줄이 # : << 'EOF' 시그니처일 때 oh-my-tmux로 감지 (상대 symlink는 conf 디렉토리 기준으로 resolve)
  • findTmuxConfLocal() — 매칭된 conf 경로에서 .tmux.conf.local 도출 (XDG/홈 페어링 유지)
  • writeBindToLocal()# "$@" sentinel 앞에 bind 라인 삽입. sentinel 없으면 끝에 append, 파일 없으면 생성, 기존 marker 라인 발견 시 in-place 교체 (idempotent)
  • stripMarkerLines() — main conf에 남은 mux 라인 정리. marker 태그 라인 + 레거시 untagged 패턴(display-popup -E -w 80% -h 80% "mux") 모두 처리. 이전에 버그를 겪은 사용자를 위한 backward 정리

install.sh

  • is_oh_my_tmux() — Go 측과 동일한 하이브리드 감지. 상대 symlink target(ln -s .tmux/.tmux.conf ~/.tmux.conf) 케이스도 매칭
  • strip_mux_lines() — symlink를 통과(write through symlink)해서 진짜 conf 파일을 정리. mv는 symlink를 일반 파일로 교체해 버려서 oh-my-tmux 구조가 깨짐
  • setup_keybind() — oh-my-tmux 분기에서 awk로 sentinel 앞 삽입, main conf 정리 동시 수행

Codex Review

이 PR은 codex(/codex review) 리뷰를 거쳤고 다음 3가지 finding을 모두 반영했다:

  • [P2] install.sh 분기에서 main conf 손상 흔적을 정리하지 않던 문제
  • [P2] Go 쪽 cleanup이 marker 태그만 보고 레거시 untagged 라인은 못 잡던 문제
  • [P3] 상대 symlink target(.tmux/.tmux.conf)이 */.tmux/* 패턴에 매칭 안 되던 문제

추가로 smoke 테스트 중 mv가 symlink를 깨버리는 문제를 발견해서 write-through-symlink로 변경했다.

Test plan

  • go test ./... 모두 통과 (tmux/popup_test.go 16개 케이스 신규 추가)
  • Plain tmux conf — 기존 동작 유지
  • oh-my-tmux symlink (절대 경로 target)
  • oh-my-tmux symlink (상대 경로 target — .tmux/.tmux.conf)
  • oh-my-tmux 시그니처만 있는 case (symlink 없이 파일 복사)
  • sentinel 앞 삽입 + idempotency (재실행 시 marker 라인 in-place 교체)
  • sentinel 부재 시 fallback (끝에 append)
  • .tmux.conf.local 부재 시 자동 생성
  • 손상된 main conf 정리 + symlink 구조 보존 (Go 경로)
  • 손상된 main conf 정리 + symlink 구조 보존 (install.sh 경로)
  • 사용자가 직접 작성한 bind X display-popup ... "mux popup" 류는 정리 대상에서 제외 (false positive 회피)

oh-my-tmux는 ~/.tmux.conf를 `cut -c3- | sh`로 처리해서 헤더 함수를
실행하는데, 기존 setup-keybind는 일반 bind 라인을 그대로 append했고
앞 두 글자가 잘려나가면서 `nd m display-popup ...` 같은 invalid shell이
되어 reload가 exit 127로 실패했다.

oh-my-tmux 감지 (symlink target 또는 시그니처 라인)와 .tmux.conf.local
sentinel(`# "$@"`) 앞 삽입 라우팅을 추가했다. 이전에 손상된 사용자를
위해 main conf에 남은 mux 라인(marker + 레거시 install.sh 패턴) 정리도
같이 수행하며, oh-my-tmux의 symlink 구조를 보존한다.

install.sh fallback도 같은 로직으로 동기화했다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lunemis
lunemis merged commit 29959ff into main May 4, 2026
1 check passed
@lunemis
lunemis deleted the fix/issue-15-oh-my-tmux branch May 4, 2026 11:25
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.

[Bug] setup-keybind corrupts ~/.tmux.conf for oh-my-tmux users

1 participant