텍스트 편집기를 UI로 사용하는 아이디어에서 출발해 nfp에 `-e` 기능을 추가하며 겪은 구현상의 고민과, 저장소를 git과 CodeBerg로 옮긴 근황을 다룹니다.
지난 금요일, 저는 Dave Gauer의 텍스트 편집기를 UI로 사용하는 것에 관한 글을 발견했는데, 컴퓨터에 대해 제가 좋아하는 지점을 정확히 건드리는 내용이었습니다. 거기서 언급된 예시 중 하나가 텍스트 편집기에서 cron 설정 파일을 여는 crontab -e였습니다. 이 방식은 설정 파일의 위치를 외울 필요를 덜어줄 뿐 아니라, 설정이 없을 때는 안내용 주석 예시도 제공하고, 편집을 마친 뒤에는 cron이 변경 사항을 다시 읽도록 친절하게 신호까지 보내 줍니다.
그리고 저는 거의 즉시, 이런 것과 비슷한 기능을 활용할 수 있는 제 도구를 떠올렸습니다: nfp.
놀랍게도 저는 실제로 프로젝트를 열고 이것저것 만지기 시작했을 뿐 아니라, 주말 내내 계속 작업했고, 일요일이 끝날 무렵에는 그 기능을 정말로 완성했습니다! 게다가 흔한 의미의 비교적 작은 기능이긴 했지만, 스누커 경기를 보는 동안, 음식을 하는 동안, 가족을 데리고 볼일을 보러 다니는 동안, 그리고 몇 가지 긴급 상황을 처리하는 와중에도 계속 코딩하고 있었다는 점도 덧붙여야겠습니다.
그래서 저는 꽤나 스스로가 만족스러운 기분으로 잠자리에 들었습니다 :-)
어떤 프로그래밍 작업이든, 무엇을 해야 할지를 생각하는 단계에서 실제로 구현하는 단계로 넘어가면 점차 진짜 복잡성이 드러난다는 사실이 저는 아직도 신납니다. “nfp -e는 텍스트 편집기에서 설정을 열고 편집 후 재시작해야 한다”라고 말하면 충분히 단순하게 들리지만, 실제로는 제가 풀어야 했던 질문이 몇 가지 있었습니다. 그중 몇 개는 꽤나 머리를 싸매게 만들었습니다.
첫째, 어느 편집기를 열어야 할까요? 가장 뻔한 것은 $EDITOR 환경 변수지만, 보통은 우선순위가 더 높은 $VISUAL도 있습니다.
재시작은 어떻게 할까요? 가장 먼저 떠오른 것은 이미 실행 중인 데몬에 시그널을 보내는 방법이었지만, 그건 꽤 번거로울 수 있습니다. 데몬은 파일 이벤트를 기다리는 루프 안에서 살아 있고, 그 루프가 설정에서 파싱한 정보를 소유하고 있기 때문입니다. SIGHUP를 처리하려면 그 정보를 갱신하는 별도의 장치가 필요합니다. Rust에서 그걸 어떻게 해야 할지 생각하는 건 저로서는 그다지 편하지 않습니다.
다행히도 이 복잡함은 전화위복이 되었습니다. 파일 감시 장치는 이미 있으니, 설정 파일도 같이 감시하고 일반 파일들과는 다르게 처리하는 특별한 경우만 추가하면 되었던 것입니다!
nfp -e를 실행했을 때, 계속 편집할 수 있도록 어떻게 같은 임시 파일을 다시 열어 줄 수 있을까요? 그때는 새로운 프로세스이고, 이전 임시 파일을 알지 못합니다.crontab -e는 같은 프로세스 안에서 루프를 구성하고, 같은 파일을 다시 편집할지 묻는 예/아니오 프롬프트를 보여주는 방식으로 이를 해결합니다. 하지만 그러면 이 기능이 감당할 만한 수준보다 더 복잡해지기 시작합니다.
저는 결국 더 단순한 해법을 택했고, 항상 실제 설정 파일을 열도록 했습니다. 즉, 파일이 망가질 가능성은 있습니다. 이 경우는 실행 중인 데몬 자체에서 처리하는데, 설정을 파싱할 수 없으면 단순히 메인 루프를 재시작하지 않습니다.
전체적으로 꽤 재미있었습니다!
저는 (드디어) 저장소를 pijul에서 git으로 변환했고, CodeBerg에 올렸습니다. 저는 여전히 버전 관리 시스템으로서 pijul이 더 뛰어난 아키텍처를 가졌다고 생각하지만, 세상은 이제 git으로 완전히 정착한 듯합니다. 또, GitHub의 유해한 문화를 상대하지 않아도 된다는 점은 좋지만, 코드가 너무 특이한 방식으로 공개되어 있으면 대부분의 사람들은 아예 시도조차 하고 싶어 하지 않습니다. 4년 동안 저는 단 한 번의 반응도 받지 못했습니다 :-) 그래도 저는 여전히 공유를 믿습니다. CodeBerg가 제게 꼭 맞는 지점이 되기를 바랍니다.
다만 제가 Rust로 정기적으로 코딩하는 것은 아니고, 현대적인 관용구도 계속 따라가고 있지는 않다는 점은 염두에 두세요. 그래서 제 코드는 여러 면에서 개선의 여지가 아주 많을 것이 분명합니다. 여러분의 의견을 꼭 듣고 싶습니다! (명백한 것 하나는, 코드에 테스트가 필요하다는 점입니다. 다만 Rust에서 테스트를 어떻게 작성하는지 제가 배워야 합니다!)